{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} -- : dep clay module Omni.Jr.Web.Style ( css, statusBadgeClass, priorityBadgeClass, ) where import Alpha hiding (wrap, (**), (|>)) import Clay import qualified Clay.Flexbox as Flexbox import qualified Clay.Media as Media import qualified Clay.Stylesheet as Stylesheet import qualified Data.Text.Lazy as LazyText css :: LazyText.Text css = render stylesheet stylesheet :: Css stylesheet = do baseStyles layoutStyles navigationStyles cardStyles listGroupStyles statusBadges buttonStyles formStyles executionDetailsStyles activityTimelineStyles commitStyles markdownStyles retryBannerStyles responsiveStyles darkModeStyles baseStyles :: Css baseStyles = do star ? boxSizing borderBox html <> body ? do margin (px 0) (px 0) (px 0) (px 0) padding (px 0) (px 0) (px 0) (px 0) body ? do fontFamily [ "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans", "sans-serif" ] [sansSerif] fontSize (px 14) lineHeight (em 1.3) color "#1f2937" backgroundColor "#f5f5f5" minHeight (vh 100) "h1" ? do fontSize (px 20) fontWeight bold margin (px 0) (px 0) (em 0.3) (px 0) "h2" ? do fontSize (px 16) fontWeight (weight 600) color "#374151" margin (em 1) (px 0) (em 0.5) (px 0) "h3" ? do fontSize (px 14) fontWeight (weight 600) color "#374151" margin (em 0.75) (px 0) (em 0.25) (px 0) a ? do color "#0066cc" textDecoration none a # hover ? textDecoration underline code ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (em 0.9) backgroundColor "#f3f4f6" padding (px 1) (px 4) (px 1) (px 4) borderRadius (px 2) (px 2) (px 2) (px 2) pre ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (px 12) backgroundColor "#1e1e1e" color "#d4d4d4" padding (px 8) (px 8) (px 8) (px 8) borderRadius (px 2) (px 2) (px 2) (px 2) overflow auto whiteSpace preWrap maxHeight (px 500) layoutStyles :: Css layoutStyles = do ".container" ? do width (pct 100) maxWidth (px 960) margin (px 0) auto (px 0) auto padding (px 8) (px 12) (px 8) (px 12) main_ ? do Stylesheet.key "flex" ("1 0 auto" :: Text) ".page-content" ? do padding (px 0) (px 0) (px 0) (px 0) ".stats-grid" ? do display grid Stylesheet.key "grid-template-columns" ("repeat(auto-fit, minmax(80px, 1fr))" :: Text) Stylesheet.key "gap" ("6px" :: Text) ".task-list" ? do display flex flexDirection column Stylesheet.key "gap" ("2px" :: Text) ".detail-row" ? do display flex flexWrap Flexbox.wrap padding (px 6) (px 0) (px 6) (px 0) marginBottom (px 4) ".detail-label" ? do fontWeight (weight 600) width (px 100) color "#6b7280" minWidth (px 80) fontSize (px 13) ".detail-value" ? do Stylesheet.key "flex" ("1" :: Text) minWidth (px 0) ".detail-section" ? do marginTop (em 0.75) paddingTop (em 0.75) borderTop (px 1) solid "#e5e7eb" ".dep-list" <> ".child-list" ? do margin (px 4) (px 0) (px 4) (px 0) paddingLeft (px 16) (".dep-list" ** li) <> (".child-list" ** li) ? margin (px 2) (px 0) (px 2) (px 0) ".dep-type" <> ".child-status" ? do color "#6b7280" fontSize (px 12) ".child-title" ? color "#374151" ".priority-desc" ? do color "#6b7280" marginLeft (px 4) navigationStyles :: Css navigationStyles = do ".navbar" ? do backgroundColor white padding (px 6) (px 12) (px 6) (px 12) borderBottom (px 1) solid "#d0d0d0" marginBottom (px 8) display flex alignItems center justifyContent spaceBetween flexWrap Flexbox.wrap Stylesheet.key "gap" ("8px" :: Text) ".navbar-brand" ? do fontSize (px 18) fontWeight bold color "#0066cc" textDecoration none ".navbar-brand" # hover ? textDecoration none ".navbar-toggle-checkbox" ? display none ".navbar-hamburger" ? do display none flexDirection column justifyContent center alignItems center width (px 32) height (px 32) cursor pointer Stylesheet.key "gap" ("4px" :: Text) ".hamburger-line" ? do display block width (px 20) height (px 2) backgroundColor "#374151" borderRadius (px 1) (px 1) (px 1) (px 1) transition "all" (ms 200) ease (sec 0) ".navbar-links" ? do display flex Stylesheet.key "gap" ("2px" :: Text) flexWrap Flexbox.wrap alignItems center ".navbar-link" ? do display inlineBlock padding (px 4) (px 10) (px 4) (px 10) color "#374151" textDecoration none borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 13) fontWeight (weight 500) transition "background-color" (ms 150) ease (sec 0) ".navbar-link" # hover ? do backgroundColor "#f3f4f6" textDecoration none ".navbar-dropdown" ? do position relative display inlineBlock ".navbar-dropdown-btn" ? do display inlineBlock padding (px 4) (px 10) (px 4) (px 10) color "#374151" backgroundColor transparent border (px 0) none transparent borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 13) fontWeight (weight 500) cursor pointer transition "background-color" (ms 150) ease (sec 0) ".navbar-dropdown-btn" # hover ? backgroundColor "#f3f4f6" ".navbar-dropdown-content" ? do display none position absolute left (px 0) top (pct 100) backgroundColor white minWidth (px 120) Stylesheet.key "box-shadow" ("0 2px 8px rgba(0,0,0,0.15)" :: Text) borderRadius (px 2) (px 2) (px 2) (px 2) zIndex 100 Stylesheet.key "overflow" ("hidden" :: Text) ".navbar-dropdown" # hover |> ".navbar-dropdown-content" ? display block ".navbar-dropdown-item" ? do display block padding (px 8) (px 12) (px 8) (px 12) color "#374151" textDecoration none fontSize (px 13) transition "background-color" (ms 150) ease (sec 0) ".navbar-dropdown-item" # hover ? do backgroundColor "#f3f4f6" textDecoration none header ? do backgroundColor white padding (px 6) (px 12) (px 6) (px 12) borderBottom (px 1) solid "#d0d0d0" marginBottom (px 8) ".nav-content" ? do maxWidth (px 960) margin (px 0) auto (px 0) auto display flex alignItems center justifyContent spaceBetween flexWrap Flexbox.wrap Stylesheet.key "gap" ("8px" :: Text) ".nav-brand" ? do fontSize (px 16) fontWeight bold color "#1f2937" textDecoration none ".nav-brand" # hover ? textDecoration none ".nav-links" ? do display flex Stylesheet.key "gap" ("4px" :: Text) flexWrap Flexbox.wrap ".actions" ? do display flex flexDirection row flexWrap Flexbox.wrap Stylesheet.key "gap" ("6px" :: Text) marginBottom (px 8) cardStyles :: Css cardStyles = do ".card" <> ".task-card" <> ".stat-card" <> ".task-detail" <> ".task-summary" <> ".filter-form" <> ".status-form" <> ".diff-section" <> ".review-actions" ? do backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d0d0d0" ".review-actions" ? do display flex flexDirection row flexWrap Flexbox.wrap alignItems center Stylesheet.key "gap" ("8px" :: Text) ".stat-card" ? textAlign center ".stat-count" ? do fontSize (px 22) fontWeight bold ".stat-label" ? do fontSize (px 11) color "#6b7280" marginTop (px 2) ".stat-card.badge-open" ? do borderLeft (px 4) solid "#f59e0b" (".stat-card.badge-open" |> ".stat-count") ? color "#92400e" ".stat-card.badge-inprogress" ? borderLeft (px 4) solid "#3b82f6" (".stat-card.badge-inprogress" |> ".stat-count") ? color "#1e40af" ".stat-card.badge-review" ? borderLeft (px 4) solid "#8b5cf6" (".stat-card.badge-review" |> ".stat-count") ? color "#6b21a8" ".stat-card.badge-approved" ? borderLeft (px 4) solid "#06b6d4" (".stat-card.badge-approved" |> ".stat-count") ? color "#0e7490" ".stat-card.badge-done" ? borderLeft (px 4) solid "#10b981" (".stat-card.badge-done" |> ".stat-count") ? color "#065f46" ".task-card" ? do transition "border-color" (ms 150) ease (sec 0) ".task-card" # hover ? do borderColor "#999" ".task-card-link" ? do display block textDecoration none color inherit cursor pointer ".task-card-link" # hover ? textDecoration none ".task-header" ? do display flex flexWrap Flexbox.wrap alignItems center Stylesheet.key "gap" ("6px" :: Text) marginBottom (px 4) ".task-id" ? do fontFamily ["SF Mono", "Monaco", "monospace"] [monospace] color "#0066cc" textDecoration none fontSize (px 12) padding (px 2) (px 0) (px 2) (px 0) ".task-id" # hover ? textDecoration underline ".priority" ? do fontSize (px 11) color "#6b7280" ".task-title" ? do fontSize (px 14) margin (px 0) (px 0) (px 0) (px 0) ".empty-msg" ? do color "#6b7280" fontStyle italic ".info-msg" ? do color "#6b7280" marginBottom (px 12) ".kb-preview" ? do color "#6b7280" fontSize (px 12) marginTop (px 4) overflow hidden Stylesheet.key "text-overflow" ("ellipsis" :: Text) ".ready-link" ? do fontSize (px 13) color "#0066cc" ".count-badge" ? do backgroundColor "#0066cc" color white padding (px 2) (px 8) (px 2) (px 8) borderRadius (px 10) (px 10) (px 10) (px 10) fontSize (px 12) verticalAlign middle ".description" ? do backgroundColor "#f9fafb" padding (px 8) (px 8) (px 8) (px 8) borderRadius (px 2) (px 2) (px 2) (px 2) margin (px 0) (px 0) (px 0) (px 0) color "#374151" fontSize (px 13) ".diff-block" ? do maxHeight (px 600) overflowY auto ".progress-bar" ? do height (px 6) backgroundColor "#e5e7eb" borderRadius (px 2) (px 2) (px 2) (px 2) overflow hidden marginTop (px 6) ".progress-fill" ? do height (pct 100) backgroundColor "#0066cc" borderRadius (px 2) (px 2) (px 2) (px 2) transition "width" (ms 300) ease (sec 0) ".multi-progress-container" ? do marginBottom (px 12) ".multi-progress-bar" ? do display flex height (px 8) backgroundColor "#e5e7eb" borderRadius (px 4) (px 4) (px 4) (px 4) overflow hidden marginTop (px 6) ".multi-progress-segment" ? do height (pct 100) transition "width" (ms 300) ease (sec 0) ".progress-done" ? backgroundColor "#10b981" ".progress-inprogress" ? backgroundColor "#f59e0b" ".progress-open" ? backgroundColor "#3b82f6" ".progress-legend" ? do display flex Stylesheet.key "gap" ("16px" :: Text) marginTop (px 6) fontSize (px 12) color "#6b7280" ".legend-item" ? do display flex alignItems center Stylesheet.key "gap" ("4px" :: Text) ".legend-dot" ? do display inlineBlock width (px 10) height (px 10) borderRadius (px 2) (px 2) (px 2) (px 2) ".legend-done" ? backgroundColor "#10b981" ".legend-inprogress" ? backgroundColor "#f59e0b" ".legend-open" ? backgroundColor "#3b82f6" ".stats-section" ? do backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d0d0d0" ".stats-row" ? do display flex alignItems center Stylesheet.key "gap" ("8px" :: Text) padding (px 4) (px 0) (px 4) (px 0) marginBottom (px 2) ".stats-label" ? do minWidth (px 80) fontWeight (weight 500) fontSize (px 13) ".stats-bar-container" ? do Stylesheet.key "flex" ("1" :: Text) ".stats-count" ? do minWidth (px 32) textAlign (alignSide sideRight) fontWeight (weight 500) fontSize (px 13) ".summary-section" ? do backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d0d0d0" ".no-commit-msg" ? do backgroundColor "#fff3cd" border (px 1) solid "#ffc107" borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) margin (px 8) (px 0) (px 8) (px 0) ".conflict-warning" ? do backgroundColor "#fee2e2" border (px 1) solid "#ef4444" borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) margin (px 8) (px 0) (px 8) (px 0) listGroupStyles :: Css listGroupStyles = do ".list-group" ? do display flex flexDirection column backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) border (px 1) solid "#d0d0d0" overflow hidden ".list-group-item" ? do display flex alignItems center justifyContent spaceBetween padding (px 8) (px 10) (px 8) (px 10) borderBottom (px 1) solid "#e5e7eb" textDecoration none color inherit transition "background-color" (ms 150) ease (sec 0) ".list-group-item" # lastChild ? borderBottom (px 0) none transparent ".list-group-item" # hover ? do backgroundColor "#f9fafb" textDecoration none ".list-group-item-content" ? do display flex alignItems center Stylesheet.key "gap" ("8px" :: Text) Stylesheet.key "flex" ("1" :: Text) minWidth (px 0) overflow hidden ".list-group-item-id" ? do fontFamily ["SF Mono", "Monaco", "monospace"] [monospace] color "#0066cc" fontSize (px 12) flexShrink 0 ".list-group-item-title" ? do fontSize (px 13) color "#374151" overflow hidden Stylesheet.key "text-overflow" ("ellipsis" :: Text) whiteSpace nowrap ".list-group-item-meta" ? do display flex alignItems center Stylesheet.key "gap" ("6px" :: Text) flexShrink 0 statusBadges :: Css statusBadges = do ".badge" ? do display inlineBlock padding (px 2) (px 6) (px 2) (px 6) borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 11) fontWeight (weight 500) whiteSpace nowrap ".badge-open" ? do backgroundColor "#fef3c7" color "#92400e" ".badge-inprogress" ? do backgroundColor "#dbeafe" color "#1e40af" ".badge-review" ? do backgroundColor "#ede9fe" color "#6b21a8" ".badge-approved" ? do backgroundColor "#cffafe" color "#0e7490" ".badge-done" ? do backgroundColor "#d1fae5" color "#065f46" ".status-badge-dropdown" ? do position relative display inlineBlock ".status-badge-clickable" ? do cursor pointer Stylesheet.key "user-select" ("none" :: Text) ".status-badge-clickable" # hover ? do opacity 0.85 ".dropdown-arrow" ? do fontSize (px 8) marginLeft (px 2) opacity 0.7 ".status-dropdown-menu" ? do display none position absolute left (px 0) top (pct 100) marginTop (px 2) backgroundColor white borderRadius (px 4) (px 4) (px 4) (px 4) Stylesheet.key "box-shadow" ("0 2px 8px rgba(0,0,0,0.15)" :: Text) zIndex 100 padding (px 4) (px 4) (px 4) (px 4) minWidth (px 100) ".status-badge-dropdown.open" |> ".status-dropdown-menu" ? do display block ".status-option-form" ? do margin (px 0) (px 0) (px 0) (px 0) padding (px 0) (px 0) (px 0) (px 0) ".status-dropdown-option" ? do display block width (pct 100) textAlign (alignSide sideLeft) margin (px 2) (px 0) (px 2) (px 0) border (px 0) none transparent cursor pointer transition "opacity" (ms 150) ease (sec 0) ".status-dropdown-option" # hover ? do opacity 0.7 ".status-dropdown-option" # focus ? do opacity 0.85 Stylesheet.key "outline" ("2px solid #0066cc" :: Text) Stylesheet.key "outline-offset" ("1px" :: Text) ".status-dropdown-option.selected" ? do Stylesheet.key "outline" ("2px solid #0066cc" :: Text) Stylesheet.key "outline-offset" ("1px" :: Text) ".status-badge-clickable" # focus ? do Stylesheet.key "outline" ("2px solid #0066cc" :: Text) Stylesheet.key "outline-offset" ("2px" :: Text) buttonStyles :: Css buttonStyles = do ".btn" <> ".action-btn" <> ".filter-btn" <> ".submit-btn" <> ".accept-btn" <> ".reject-btn" <> ".review-link-btn" ? do display inlineBlock minHeight (px 32) padding (px 6) (px 12) (px 6) (px 12) borderRadius (px 2) (px 2) (px 2) (px 2) border (px 0) none transparent fontSize (px 13) fontWeight (weight 500) textDecoration none cursor pointer textAlign center transition "all" (ms 150) ease (sec 0) Stylesheet.key "touch-action" ("manipulation" :: Text) ".action-btn" ? do backgroundColor white border (px 1) solid "#d1d5db" color "#374151" ".action-btn" # hover ? do backgroundColor "#f9fafb" borderColor "#9ca3af" ".action-btn-primary" <> ".filter-btn" <> ".submit-btn" ? do backgroundColor "#0066cc" color white borderColor "#0066cc" ".action-btn-primary" # hover <> ".filter-btn" # hover <> ".submit-btn" # hover ? do backgroundColor "#0052a3" ".accept-btn" ? do backgroundColor "#10b981" color white ".accept-btn" # hover ? backgroundColor "#059669" ".reject-btn" ? do backgroundColor "#ef4444" color white ".reject-btn" # hover ? backgroundColor "#dc2626" ".clear-btn" ? do display inlineBlock minHeight (px 32) padding (px 6) (px 10) (px 6) (px 10) backgroundColor "#6b7280" color white borderRadius (px 2) (px 2) (px 2) (px 2) textDecoration none fontSize (px 13) cursor pointer ".clear-btn" # hover ? backgroundColor "#4b5563" ".review-link-btn" ? do backgroundColor "#8b5cf6" color white ".review-link-btn" # hover ? backgroundColor "#7c3aed" ".review-link-section" ? margin (px 8) (px 0) (px 8) (px 0) ".btn-secondary" <> ".load-more-btn" ? do backgroundColor "#6b7280" color white width (pct 100) marginTop (px 8) ".btn-secondary" # hover <> ".load-more-btn" # hover ? backgroundColor "#4b5563" formStyles :: Css formStyles = do ".filter-row" ? do display flex flexWrap Flexbox.wrap Stylesheet.key "gap" ("8px" :: Text) alignItems flexEnd ".filter-group" ? do display flex flexDirection row alignItems center Stylesheet.key "gap" ("4px" :: Text) (".filter-group" |> label) ? do fontSize (px 12) color "#6b7280" fontWeight (weight 500) whiteSpace nowrap ".filter-select" <> ".filter-input" <> ".status-select" ? do minHeight (px 32) padding (px 6) (px 10) (px 6) (px 10) border (px 1) solid "#d1d5db" borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 13) minWidth (px 100) ".filter-input" ? minWidth (px 120) ".inline-form" ? display inlineBlock ".reject-form" ? do display flex Stylesheet.key "gap" ("6px" :: Text) Stylesheet.key "flex" ("1" :: Text) minWidth (px 200) flexWrap Flexbox.wrap ".reject-notes" ? do Stylesheet.key "flex" ("1" :: Text) minWidth (px 160) minHeight (px 32) padding (px 6) (px 10) (px 6) (px 10) border (px 1) solid "#d1d5db" borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 13) Stylesheet.key "resize" ("vertical" :: Text) ".edit-description" ? do marginTop (px 8) padding (px 8) (px 0) (px 0) (px 0) borderTop (px 1) solid "#e5e7eb" (".edit-description" |> "summary") ? do cursor pointer color "#0066cc" fontSize (px 13) fontWeight (weight 500) (".edit-description" |> "summary") # hover ? textDecoration underline ".description-textarea" ? do width (pct 100) minHeight (px 250) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d1d5db" borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 13) fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] lineHeight (em 1.5) Stylesheet.key "resize" ("vertical" :: Text) marginTop (px 8) ".form-actions" ? do display flex flexDirection row flexWrap Flexbox.wrap Stylesheet.key "gap" ("8px" :: Text) marginTop (px 8) ".fact-edit-form" ? do marginTop (px 8) ".form-group" ? do marginBottom (px 16) (".form-group" |> label) ? do display block marginBottom (px 4) fontSize (px 13) fontWeight (weight 500) color "#374151" ".form-input" <> ".form-textarea" ? do width (pct 100) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d1d5db" borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 14) lineHeight (em 1.5) ".form-input" # focus <> ".form-textarea" # focus ? do borderColor "#0066cc" Stylesheet.key "outline" ("none" :: Text) Stylesheet.key "box-shadow" ("0 0 0 2px rgba(0, 102, 204, 0.2)" :: Text) ".form-textarea" ? do minHeight (px 120) Stylesheet.key "resize" ("vertical" :: Text) fontFamily [ "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif" ] [sansSerif] ".btn" ? do display inlineBlock padding (px 8) (px 16) (px 8) (px 16) border (px 0) none transparent borderRadius (px 3) (px 3) (px 3) (px 3) fontSize (px 14) fontWeight (weight 500) textDecoration none cursor pointer transition "all" (ms 150) ease (sec 0) ".btn-primary" ? do backgroundColor "#0066cc" color white ".btn-primary" # hover ? backgroundColor "#0052a3" ".btn-secondary" ? do backgroundColor "#6b7280" color white ".btn-secondary" # hover ? backgroundColor "#4b5563" ".btn-danger" ? do backgroundColor "#dc2626" color white ".btn-danger" # hover ? backgroundColor "#b91c1c" ".danger-zone" ? do marginTop (px 24) padding (px 16) (px 16) (px 16) (px 16) backgroundColor "#fef2f2" border (px 1) solid "#fecaca" borderRadius (px 4) (px 4) (px 4) (px 4) (".danger-zone" |> h2) ? do color "#dc2626" marginBottom (px 12) ".back-link" ? do marginTop (px 24) paddingTop (px 16) borderTop (px 1) solid "#e5e7eb" (".back-link" |> a) ? do color "#6b7280" textDecoration none (".back-link" |> a) # hover ? do color "#374151" textDecoration underline ".task-link" ? do color "#0066cc" textDecoration none fontWeight (weight 500) ".task-link" # hover ? textDecoration underline ".error-msg" ? do color "#dc2626" backgroundColor "#fef2f2" padding (px 16) (px 16) (px 16) (px 16) borderRadius (px 4) (px 4) (px 4) (px 4) border (px 1) solid "#fecaca" ".create-fact-section" ? do marginBottom (px 16) ".create-fact-toggle" ? do cursor pointer display inlineBlock ".fact-create-form" ? do marginTop (px 12) padding (px 16) (px 16) (px 16) (px 16) backgroundColor white borderRadius (px 4) (px 4) (px 4) (px 4) border (px 1) solid "#d1d5db" executionDetailsStyles :: Css executionDetailsStyles = do ".execution-section" ? do marginTop (em 1) backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d0d0d0" ".execution-details" ? do marginTop (px 8) ".metric-row" ? do display flex flexWrap Flexbox.wrap padding (px 4) (px 0) (px 4) (px 0) marginBottom (px 2) ".metric-label" ? do fontWeight (weight 600) width (px 120) color "#6b7280" fontSize (px 13) ".metric-value" ? do Stylesheet.key "flex" ("1" :: Text) fontSize (px 13) ".amp-link" ? do color "#0066cc" textDecoration none wordBreak breakAll ".amp-link" # hover ? textDecoration underline ".amp-thread-btn" ? do display inlineBlock padding (px 4) (px 10) (px 4) (px 10) backgroundColor "#7c3aed" color white borderRadius (px 3) (px 3) (px 3) (px 3) textDecoration none fontSize (px 12) fontWeight (weight 500) transition "background-color" (ms 150) ease (sec 0) ".amp-thread-btn" # hover ? do backgroundColor "#6d28d9" textDecoration none ".retry-count" ? do color "#f97316" fontWeight (weight 600) ".attempts-divider" ? do margin (px 12) (px 0) (px 12) (px 0) border (px 0) none transparent borderTop (px 1) solid "#e5e7eb" ".attempt-header" ? do fontWeight (weight 600) fontSize (px 13) color "#374151" marginTop (px 8) marginBottom (px 4) paddingBottom (px 4) borderBottom (px 1) solid "#f3f4f6" ".aggregated-metrics" ? do marginTop (em 0.5) paddingTop (em 0.75) ".metrics-grid" ? do display grid Stylesheet.key "grid-template-columns" ("repeat(auto-fit, minmax(100px, 1fr))" :: Text) Stylesheet.key "gap" ("10px" :: Text) marginTop (px 8) ".metric-card" ? do backgroundColor "#f9fafb" border (px 1) solid "#e5e7eb" borderRadius (px 4) (px 4) (px 4) (px 4) padding (px 10) (px 12) (px 10) (px 12) textAlign center (".metric-card" |> ".metric-value") ? do fontSize (px 20) fontWeight bold color "#374151" display block marginBottom (px 2) width auto (".metric-card" |> ".metric-label") ? do fontSize (px 11) color "#6b7280" fontWeight (weight 400) width auto activityTimelineStyles :: Css activityTimelineStyles = do ".activity-section" ? do marginTop (em 1) backgroundColor white borderRadius (px 2) (px 2) (px 2) (px 2) padding (px 8) (px 10) (px 8) (px 10) border (px 1) solid "#d0d0d0" ".activity-timeline" ? do position relative paddingLeft (px 20) marginTop (px 8) ".activity-timeline" # before ? do Stylesheet.key "content" ("''" :: Text) position absolute left (px 6) top (px 0) bottom (px 0) width (px 2) backgroundColor "#e5e7eb" ".activity-item" ? do position relative display flex Stylesheet.key "gap" ("8px" :: Text) paddingBottom (px 10) marginBottom (px 0) ".activity-item" # lastChild ? paddingBottom (px 0) ".activity-icon" ? do position absolute left (px (-16)) width (px 14) height (px 14) borderRadius (pct 50) (pct 50) (pct 50) (pct 50) display flex alignItems center justifyContent center fontSize (px 8) fontWeight bold backgroundColor white border (px 2) solid "#e5e7eb" ".activity-content" ? do Stylesheet.key "flex" ("1" :: Text) ".activity-header" ? do display flex alignItems center Stylesheet.key "gap" ("6px" :: Text) marginBottom (px 2) ".activity-stage" ? do fontWeight (weight 600) fontSize (px 12) ".activity-time" ? do fontSize (px 11) color "#6b7280" ".activity-message" ? do margin (px 2) (px 0) (px 0) (px 0) fontSize (px 12) color "#374151" ".activity-metadata" ? do marginTop (px 4) (".activity-metadata" |> "summary") ? do fontSize (px 11) color "#6b7280" cursor pointer ".metadata-json" ? do fontSize (px 10) backgroundColor "#f3f4f6" padding (px 4) (px 6) (px 4) (px 6) borderRadius (px 2) (px 2) (px 2) (px 2) marginTop (px 2) maxHeight (px 150) overflow auto ".stage-claiming" |> ".activity-icon" ? do borderColor "#3b82f6" color "#3b82f6" ".stage-running" |> ".activity-icon" ? do borderColor "#f59e0b" color "#f59e0b" ".stage-reviewing" |> ".activity-icon" ? do borderColor "#8b5cf6" color "#8b5cf6" ".stage-retrying" |> ".activity-icon" ? do borderColor "#f97316" color "#f97316" ".stage-completed" |> ".activity-icon" ? do borderColor "#10b981" color "#10b981" ".stage-failed" |> ".activity-icon" ? do borderColor "#ef4444" color "#ef4444" commitStyles :: Css commitStyles = do ".commit-list" ? do display flex flexDirection column Stylesheet.key "gap" ("4px" :: Text) marginTop (px 8) ".commit-item" ? do padding (px 6) (px 8) (px 6) (px 8) backgroundColor "#f9fafb" borderRadius (px 2) (px 2) (px 2) (px 2) border (px 1) solid "#e5e7eb" ".commit-header" ? do display flex alignItems center Stylesheet.key "gap" ("8px" :: Text) marginBottom (px 2) ".commit-hash" ? do fontFamily ["SF Mono", "Monaco", "monospace"] [monospace] fontSize (px 12) color "#0066cc" textDecoration none backgroundColor "#e5e7eb" padding (px 1) (px 4) (px 1) (px 4) borderRadius (px 2) (px 2) (px 2) (px 2) ".commit-hash" # hover ? textDecoration underline ".commit-summary" ? do fontSize (px 13) color "#374151" fontWeight (weight 500) ".commit-meta" ? do display flex Stylesheet.key "gap" ("12px" :: Text) fontSize (px 11) color "#6b7280" ".commit-author" ? fontWeight (weight 500) ".commit-files" ? do color "#9ca3af" markdownStyles :: Css markdownStyles = do ".markdown-content" ? do width (pct 100) lineHeight (em 1.6) fontSize (px 14) color "#374151" ".md-h1" ? do fontSize (px 18) fontWeight bold margin (em 1) (px 0) (em 0.5) (px 0) paddingBottom (em 0.3) borderBottom (px 1) solid "#e5e7eb" ".md-h2" ? do fontSize (px 16) fontWeight (weight 600) margin (em 0.8) (px 0) (em 0.4) (px 0) ".md-h3" ? do fontSize (px 14) fontWeight (weight 600) margin (em 0.6) (px 0) (em 0.3) (px 0) ".md-para" ? do margin (em 0.5) (px 0) (em 0.5) (px 0) ".md-code" ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (px 12) backgroundColor "#1e1e1e" color "#d4d4d4" padding (px 10) (px 12) (px 10) (px 12) borderRadius (px 4) (px 4) (px 4) (px 4) overflow auto whiteSpace preWrap margin (em 0.5) (px 0) (em 0.5) (px 0) ".md-list" ? do margin (em 0.5) (px 0) (em 0.5) (px 0) paddingLeft (px 24) (".md-list" ** li) ? do margin (px 4) (px 0) (px 4) (px 0) ".md-inline-code" ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (em 0.9) backgroundColor "#f3f4f6" padding (px 1) (px 4) (px 1) (px 4) borderRadius (px 2) (px 2) (px 2) (px 2) retryBannerStyles :: Css retryBannerStyles = do ".retry-banner" ? do borderRadius (px 4) (px 4) (px 4) (px 4) padding (px 12) (px 16) (px 12) (px 16) margin (px 0) (px 0) (px 16) (px 0) ".retry-banner-warning" ? do backgroundColor "#fef3c7" border (px 1) solid "#f59e0b" ".retry-banner-critical" ? do backgroundColor "#fee2e2" border (px 1) solid "#ef4444" ".retry-banner-header" ? do display flex alignItems center Stylesheet.key "gap" ("8px" :: Text) marginBottom (px 8) ".retry-icon" ? do fontSize (px 18) fontWeight bold ".retry-attempt" ? do fontSize (px 14) fontWeight (weight 600) color "#374151" ".retry-warning-badge" ? do backgroundColor "#dc2626" color white fontSize (px 11) fontWeight (weight 600) padding (px 2) (px 8) (px 2) (px 8) borderRadius (px 2) (px 2) (px 2) (px 2) marginLeft auto ".retry-banner-details" ? do fontSize (px 13) color "#374151" ".retry-detail-row" ? do display flex alignItems flexStart Stylesheet.key "gap" ("8px" :: Text) margin (px 4) (px 0) (px 4) (px 0) ".retry-label" ? do fontWeight (weight 500) minWidth (px 110) flexShrink 0 ".retry-value" ? do color "#4b5563" ".retry-commit" ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (em 0.9) backgroundColor "#f3f4f6" padding (px 1) (px 4) (px 1) (px 4) borderRadius (px 2) (px 2) (px 2) (px 2) ".retry-conflict-list" ? do margin (px 0) (px 0) (px 0) (px 0) padding (px 0) (px 0) (px 0) (px 16) (".retry-conflict-list" ** li) ? do fontFamily ["SF Mono", "Monaco", "Consolas", "monospace"] [monospace] fontSize (px 12) margin (px 2) (px 0) (px 2) (px 0) ".retry-warning-message" ? do marginTop (px 12) padding (px 10) (px 12) (px 10) (px 12) backgroundColor "#fecaca" borderRadius (px 2) (px 2) (px 2) (px 2) fontSize (px 12) color "#991b1b" fontWeight (weight 500) responsiveStyles :: Css responsiveStyles = do query Media.screen [Media.maxWidth (px 600)] <| do body ? fontSize (px 13) ".container" ? padding (px 6) (px 8) (px 6) (px 8) ".navbar" ? do padding (px 6) (px 8) (px 6) (px 8) flexWrap Flexbox.wrap ".navbar-hamburger" ? do display flex Stylesheet.key "order" ("2" :: Text) ".navbar-links" ? do display none width (pct 100) Stylesheet.key "order" ("3" :: Text) flexDirection column alignItems flexStart paddingTop (px 8) Stylesheet.key "gap" ("0" :: Text) ".navbar-toggle-checkbox" # checked |+ ".navbar-hamburger" |+ ".navbar-links" ? do display flex ".navbar-link" ? do padding (px 8) (px 6) (px 8) (px 6) fontSize (px 13) width (pct 100) ".navbar-dropdown" ? do width (pct 100) ".navbar-dropdown-btn" ? do padding (px 8) (px 6) (px 8) (px 6) fontSize (px 13) width (pct 100) textAlign (alignSide sideLeft) ".navbar-dropdown-content" ? do position static Stylesheet.key "box-shadow" ("none" :: Text) paddingLeft (px 12) backgroundColor transparent ".navbar-dropdown-item" ? do padding (px 6) (px 10) (px 6) (px 10) fontSize (px 12) ".nav-content" ? do flexDirection column alignItems flexStart ".stats-grid" ? do Stylesheet.key "grid-template-columns" ("repeat(2, 1fr)" :: Text) ".detail-row" ? do flexDirection column Stylesheet.key "gap" ("2px" :: Text) ".detail-label" ? width auto ".filter-row" ? do flexWrap Flexbox.wrap ".filter-group" ? do width auto flexWrap Flexbox.nowrap ".filter-select" <> ".filter-input" ? minWidth (px 80) ".review-actions" ? do flexDirection column ".reject-form" ? do width (pct 100) flexDirection column ".reject-notes" ? width (pct 100) ".actions" ? flexDirection column ".action-btn" ? width (pct 100) darkModeStyles :: Css darkModeStyles = query Media.screen [prefersDark] <| do body ? do backgroundColor "#111827" color "#f3f4f6" ".card" <> ".task-card" <> ".stat-card" <> ".task-detail" <> ".task-summary" <> ".filter-form" <> ".status-form" <> ".diff-section" <> ".review-actions" <> ".list-group" ? do backgroundColor "#1f2937" borderColor "#374151" ".list-group-item" ? borderBottomColor "#374151" ".list-group-item" # hover ? backgroundColor "#374151" ".list-group-item-id" ? color "#60a5fa" ".list-group-item-title" ? color "#d1d5db" header ? do backgroundColor "#1f2937" borderColor "#374151" ".navbar" ? do backgroundColor "#1f2937" borderColor "#374151" ".navbar-brand" ? color "#60a5fa" ".navbar-link" ? color "#d1d5db" ".navbar-link" # hover ? backgroundColor "#374151" ".navbar-dropdown-btn" ? color "#d1d5db" ".navbar-dropdown-btn" # hover ? backgroundColor "#374151" ".navbar-dropdown-content" ? do backgroundColor "#1f2937" Stylesheet.key "box-shadow" ("0 2px 8px rgba(0,0,0,0.3)" :: Text) ".navbar-dropdown-item" ? color "#d1d5db" ".navbar-dropdown-item" # hover ? backgroundColor "#374151" ".status-dropdown-menu" ? do backgroundColor "#1f2937" Stylesheet.key "box-shadow" ("0 2px 8px rgba(0,0,0,0.3)" :: Text) ".hamburger-line" ? backgroundColor "#d1d5db" ".nav-brand" ? color "#f3f4f6" "h2" <> "h3" ? color "#d1d5db" a ? color "#60a5fa" ".detail-label" <> ".priority" <> ".dep-type" <> ".child-status" <> ".empty-msg" <> ".stat-label" <> ".priority-desc" ? color "#9ca3af" ".child-title" ? color "#d1d5db" code ? do backgroundColor "#374151" color "#f3f4f6" ".detail-section" ? borderTopColor "#374151" ".description" ? do backgroundColor "#374151" color "#e5e7eb" ".badge-open" ? do backgroundColor "#78350f" color "#fcd34d" ".badge-inprogress" ? do backgroundColor "#1e3a8a" color "#93c5fd" ".badge-review" ? do backgroundColor "#4c1d95" color "#c4b5fd" ".badge-approved" ? do backgroundColor "#164e63" color "#67e8f9" ".badge-done" ? do backgroundColor "#064e3b" color "#6ee7b7" ".action-btn" ? do backgroundColor "#374151" borderColor "#4b5563" color "#f3f4f6" ".action-btn" # hover ? backgroundColor "#4b5563" ".filter-select" <> ".filter-input" <> ".status-select" <> ".reject-notes" ? do backgroundColor "#374151" borderColor "#4b5563" color "#f3f4f6" ".stats-section" <> ".summary-section" ? do backgroundColor "#1f2937" borderColor "#374151" ".progress-bar" ? backgroundColor "#374151" ".progress-fill" ? backgroundColor "#60a5fa" ".multi-progress-bar" ? backgroundColor "#374151" ".progress-legend" ? color "#9ca3af" ".activity-section" ? do backgroundColor "#1f2937" borderColor "#374151" ".activity-timeline" # before ? backgroundColor "#374151" ".activity-icon" ? do backgroundColor "#1f2937" borderColor "#374151" ".activity-time" ? color "#9ca3af" ".activity-message" ? color "#d1d5db" (".activity-metadata" |> "summary") ? color "#9ca3af" ".metadata-json" ? backgroundColor "#374151" ".execution-section" ? do backgroundColor "#1f2937" borderColor "#374151" ".metric-label" ? color "#9ca3af" ".metric-value" ? color "#d1d5db" ".metric-card" ? do backgroundColor "#374151" borderColor "#4b5563" (".metric-card" |> ".metric-value") ? color "#f3f4f6" (".metric-card" |> ".metric-label") ? color "#9ca3af" ".amp-link" ? color "#60a5fa" ".amp-thread-btn" ? do backgroundColor "#8b5cf6" ".amp-thread-btn" # hover ? backgroundColor "#7c3aed" ".markdown-content" ? color "#d1d5db" ".commit-item" ? do backgroundColor "#374151" borderColor "#4b5563" ".commit-hash" ? do backgroundColor "#4b5563" color "#60a5fa" ".commit-summary" ? color "#d1d5db" ".commit-meta" ? color "#9ca3af" ".md-h1" ? borderBottomColor "#374151" ".md-inline-code" ? do backgroundColor "#374151" color "#f3f4f6" ".edit-description" ? borderTopColor "#374151" (".edit-description" |> "summary") ? color "#60a5fa" ".description-textarea" ? do backgroundColor "#374151" borderColor "#4b5563" color "#f3f4f6" ".fact-create-form" ? do backgroundColor "#1f2937" borderColor "#374151" -- Responsive dark mode: dropdown content needs background on mobile query Media.screen [Media.maxWidth (px 600)] <| do ".navbar-dropdown-content" ? do backgroundColor "#1f2937" ".navbar-dropdown-item" # hover ? do backgroundColor "#374151" prefersDark :: Stylesheet.Feature prefersDark = Stylesheet.Feature "prefers-color-scheme" (Just (Clay.value ("dark" :: Text))) statusBadgeClass :: Text -> Text statusBadgeClass status = case status of "Open" -> "badge badge-open" "InProgress" -> "badge badge-inprogress" "Review" -> "badge badge-review" "Approved" -> "badge badge-approved" "Done" -> "badge badge-done" _ -> "badge" priorityBadgeClass :: Text -> Text priorityBadgeClass priority = case priority of "P0" -> "badge badge-p0" "P1" -> "badge badge-p1" "P2" -> "badge badge-p2" "P3" -> "badge badge-p3" "P4" -> "badge badge-p4" _ -> "badge"