job_harbor 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/job_harbor/application.css +2 -0
- data/app/assets/stylesheets/job_harbor/application.tailwind.css +459 -0
- data/app/views/layouts/job_harbor/application.html.erb +1 -486
- data/lib/job_harbor/version.rb +1 -1
- data/lib/tasks/tailwind.rake +129 -0
- metadata +4 -2
- data/app/assets/stylesheets/solidqueue_dashboard/application.css +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a1b68a22bd455a51f26a4a616e40e00e76698ee0c71e017adc058971d9388ac
|
|
4
|
+
data.tar.gz: fcbb5ee40a161e6e99a90a2ffed21aae04d99eecc4ccae726c42288fda8fa2fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 50b14d40d3828c535ccae32548a2c6a0ba9849e2eea29a1b2444e02144ac6d99adc88591c00974052b76f0d611fe272fdfa096276706fbcc9326cd3b46d2298d
|
|
7
|
+
data.tar.gz: 9b797624b652746ca7f4cf3067e22baeb800acc179d3bcbb59a02874d5712857bded64cd3d59a3e9bbb9cc95824313841c4343b5442d854620d3c67382f7d801
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-sky-500:oklch(68.5% .169 237.323);--spacing:.25rem;--breakpoint-2xl:96rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--background:0 0% 98%;--foreground:240 10% 3.9%;--card:0 0% 100%;--card-foreground:240 10% 3.9%;--primary:240 5.9% 10%;--primary-foreground:0 0% 98%;--secondary:240 4.8% 95.9%;--secondary-foreground:240 5.9% 10%;--muted:240 4.8% 95.9%;--muted-foreground:240 3.8% 46.1%;--accent:240 4.8% 93.8%;--accent-foreground:240 5.9% 10%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:240 5.9% 90%;--input:240 5.9% 90%;--ring:240 5.9% 10%;--radius:.65rem;--chart-1:12 76% 61%;--chart-2:173 58% 39%;--chart-3:197 37% 24%;--chart-4:43 74% 66%;--chart-5:27 87% 67%}.dark{--background:240 10% 5.4%;--foreground:0 0% 92%;--card:240 10% 3.9%;--card-foreground:0 0% 92%;--primary:0 0% 95%;--primary-foreground:240 5.9% 10%;--secondary:240 3.7% 15.9%;--secondary-foreground:0 0% 92%;--muted:240 3.7% 15.9%;--muted-foreground:240 5% 64.9%;--accent:240 3.7% 15.9%;--accent-foreground:0 0% 92%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 92%;--border:240 3.7% 15.9%;--input:240 3.7% 15.9%;--ring:240 4.9% 83.9%;--chart-1:220 70% 50%;--chart-2:160 60% 45%;--chart-3:30 80% 55%;--chart-4:280 65% 60%;--chart-5:340 75% 55%}*,:before,:after{box-sizing:border-box}body{background-color:hsl(var(--background));color:hsl(var(--foreground));-webkit-font-smoothing:antialiased;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji}}@layer components{.navbar{border-bottom:1px solid hsl(var(--border));background-color:hsl(var(--card));align-items:center;gap:1rem;height:3.5rem;padding:0 1.5rem;display:flex}.navbar-section{align-items:center;gap:.375rem;display:flex}.navbar-item{color:hsl(var(--muted-foreground));border-radius:calc(var(--radius) - 2px);white-space:nowrap;align-items:center;gap:.375rem;padding:.375rem .75rem;font-size:.875rem;font-weight:500;text-decoration:none;transition:color .15s,background-color .15s;display:inline-flex}.navbar-item:hover{color:hsl(var(--foreground));background-color:hsl(var(--accent))}.navbar-item-current{color:hsl(var(--primary-foreground));background-color:hsl(var(--primary))}.navbar-item-current:hover{color:hsl(var(--primary-foreground));background-color:hsl(var(--primary));opacity:.9}.navbar-badge{border-radius:calc(var(--radius) - 4px);background-color:hsl(var(--muted));color:hsl(var(--muted-foreground));padding:.125rem .375rem;font-size:.75rem;font-weight:600}.navbar-item-current .navbar-badge{background-color:hsl(var(--primary-foreground)/.2);color:hsl(var(--primary-foreground))}.card{border-radius:var(--radius);border:1px solid hsl(var(--border));background-color:hsl(var(--card));color:hsl(var(--card-foreground));box-shadow:0 1px 2px #0000000d}.card-header{flex-direction:column;gap:.375rem;padding:1.5rem;display:flex}.card-title{letter-spacing:-.025em;margin:0;font-size:1rem;font-weight:600;line-height:1}.card-description{color:hsl(var(--muted-foreground));font-size:.875rem}.card-content{padding:1.5rem;padding-top:0}.card-footer{align-items:center;padding:0 1.5rem 1.5rem;display:flex}.badge{border-radius:calc(var(--radius) - 2px);white-space:nowrap;align-items:center;gap:.375rem;padding:.125rem .625rem;font-size:.75rem;font-weight:500;transition:color .15s,background-color .15s;display:inline-flex}.badge-primary{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground))}.badge-secondary{background-color:hsl(var(--secondary));color:hsl(var(--secondary-foreground))}.badge-destructive{background-color:hsl(var(--destructive));color:hsl(var(--destructive-foreground))}.badge-outline{border:1px solid hsl(var(--border));color:hsl(var(--foreground));background-color:#0000}.badge-red{color:#ef4444;background-color:#ef44441a}.dark .badge-red{color:#fca5a5;background-color:#ef444426}.badge-amber{color:#d97706;background-color:#fbbf241a}.dark .badge-amber{color:#fcd34d;background-color:#fbbf2426}.badge-yellow{color:#a16207;background-color:#facc151a}.dark .badge-yellow{color:#fde047;background-color:#facc1526}.badge-green{color:#16a34a;background-color:#22c55e1a}.dark .badge-green{color:#86efac;background-color:#22c55e26}.badge-sky{color:#0284c7;background-color:#0ea5e91a}.dark .badge-sky{color:#7dd3fc;background-color:#0ea5e926}.badge-zinc{color:#52525b;background-color:#52525b1a}.dark .badge-zinc{color:#a1a1aa;background-color:#52525b33}.circle{border-radius:9999px;flex-shrink:0;width:.5rem;height:.5rem;display:inline-block}.circle-red{background-color:#ef4444}.circle-amber{background-color:#fbbf24}.circle-green{background-color:#22c55e}.circle-yellow{background-color:#facc15}.circle-sky{background-color:#0ea5e9}.circle-zinc{background-color:#52525b}.btn{white-space:nowrap;border-radius:calc(var(--radius) - 2px);cursor:pointer;border:none;justify-content:center;align-items:center;gap:.5rem;font-size:.875rem;font-weight:500;line-height:1;text-decoration:none;transition:color .15s,background-color .15s,opacity .15s;display:inline-flex}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-default{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));height:2.5rem;padding:.5rem 1rem}.btn-default:hover{opacity:.9}.btn-secondary{background-color:hsl(var(--secondary));color:hsl(var(--secondary-foreground));border:1px solid hsl(var(--border));height:2.5rem;padding:.5rem 1rem}.btn-secondary:hover{background-color:hsl(var(--accent))}.btn-destructive{background-color:hsl(var(--destructive));color:hsl(var(--destructive-foreground));height:2.5rem;padding:.5rem 1rem}.btn-destructive:hover{opacity:.9}.btn-outline{border:1px solid hsl(var(--border));color:hsl(var(--foreground));background-color:#0000;height:2.5rem;padding:.5rem 1rem}.btn-outline:hover{background-color:hsl(var(--accent))}.btn-ghost{color:hsl(var(--foreground));background-color:#0000;height:2.5rem;padding:.5rem 1rem}.btn-ghost:hover{background-color:hsl(var(--accent))}.btn-icon{width:2.5rem;height:2.5rem;color:hsl(var(--foreground));border:1px solid hsl(var(--border));background-color:#0000;padding:0}.btn-icon:hover{background-color:hsl(var(--accent))}.btn-sm{height:1.75rem;padding:.25rem .5rem;font-size:.75rem}.btn-xs{height:1.5rem;padding:.125rem .5rem;font-size:.75rem}.select{border-radius:calc(var(--radius) - 2px);border:1px solid hsl(var(--input));background-color:hsl(var(--card));width:12rem;height:2.25rem;color:hsl(var(--foreground));cursor:pointer;align-items:center;padding:.375rem .75rem;font-size:.875rem;display:inline-flex}.select:focus{outline:2px solid hsl(var(--ring));outline-offset:2px}.select option{background-color:hsl(var(--card));color:hsl(var(--foreground))}.table-wrapper{overflow-x:auto}table.sqd-table{border-collapse:collapse;caption-side:bottom;width:100%;font-size:.875rem}table.sqd-table thead tr{border-bottom:1px solid hsl(var(--border))}table.sqd-table th{text-align:left;vertical-align:middle;text-transform:uppercase;letter-spacing:.05em;height:2.5rem;color:hsl(var(--muted-foreground));white-space:nowrap;padding:0 1rem;font-size:.75rem;font-weight:500}table.sqd-table tbody tr{border-bottom:1px solid hsl(var(--border));transition:background-color .15s}table.sqd-table tbody tr:hover{background-color:hsl(var(--muted)/.5)}table.sqd-table td{vertical-align:middle;padding:.75rem 1rem}.info-line{align-items:center;gap:1rem;padding:.5rem 0;display:flex}.info-line-label{color:hsl(var(--muted-foreground));white-space:nowrap;flex-shrink:0;font-size:.875rem}.info-line-separator{background-color:hsl(var(--border));flex:1;height:1px}.info-line-value{color:hsl(var(--foreground));text-align:right;white-space:nowrap;font-size:.875rem;font-weight:500}.alert{border-radius:var(--radius);border:1px solid;align-items:center;gap:.75rem;padding:1rem;font-size:.875rem;display:flex;position:relative}.alert-success{color:#16a34a;background-color:#22c55e0d;border-color:#22c55e4d}.dark .alert-success{color:#86efac;background-color:#22c55e1a}.alert-error{color:#dc2626;background-color:#ef44440d;border-color:#ef44444d}.dark .alert-error{color:#fca5a5;background-color:#ef44441a}.alert-warning{color:#d97706;background-color:#fbbf240d;border-color:#fbbf244d}.dark .alert-warning{color:#fcd34d;background-color:#fbbf241a}.alert-info{color:#0284c7;background-color:#0ea5e90d;border-color:#0ea5e94d}.dark .alert-info{color:#7dd3fc;background-color:#0ea5e91a}.pagination-nav{justify-content:center;align-items:center;gap:.25rem;display:flex}.pagination-link{min-width:2rem;height:2rem;color:hsl(var(--muted-foreground));border-radius:calc(var(--radius) - 2px);justify-content:center;align-items:center;padding:0 .5rem;font-size:.875rem;font-weight:500;text-decoration:none;transition:background-color .15s;display:inline-flex}.pagination-link:hover{background-color:hsl(var(--accent));color:hsl(var(--foreground))}.pagination-active{background-color:hsl(var(--primary));color:hsl(var(--primary-foreground));border:1px solid hsl(var(--primary))}.pagination-disabled{opacity:.5;cursor:not-allowed}.link{color:hsl(var(--foreground));text-underline-offset:4px;text-decoration:underline}.link:hover{opacity:.75}.sqd-chart{width:100%;height:200px;position:relative}.sqd-chart canvas{width:100%!important;height:100%!important}.code-block{background-color:hsl(var(--muted));border-radius:calc(var(--radius) - 2px);white-space:pre-wrap;word-break:break-word;padding:.75rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.8125rem;overflow-x:auto}.stat-card{border-radius:var(--radius);border:1px solid hsl(var(--border));background-color:hsl(var(--card));flex-direction:column;gap:.25rem;padding:1.5rem;text-decoration:none;transition:border-color .15s;display:flex}a.stat-card:hover{border-color:hsl(var(--foreground)/.2)}.stat-card-label{color:hsl(var(--muted-foreground));align-items:center;gap:.5rem;font-size:.875rem;font-weight:500;display:flex}.stat-card-value{color:hsl(var(--foreground));font-size:2.25rem;font-weight:700;line-height:1}.sqd-rate-low{color:#16a34a;background-color:#22c55e1a}.dark .sqd-rate-low{color:#86efac;background-color:#22c55e26}.sqd-rate-medium{color:#d97706;background-color:#fbbf241a}.dark .sqd-rate-medium{color:#fcd34d;background-color:#fbbf2426}.sqd-rate-high{color:#dc2626;background-color:#ef44441a}.dark .sqd-rate-high{color:#fca5a5;background-color:#ef444426}.sqd-retry-badge{border-radius:calc(var(--radius) - 4px);color:#d97706;background-color:#fbbf2426;padding:.125rem .375rem;font-size:.6875rem;font-weight:600}.dark .sqd-retry-badge{color:#fcd34d}html:not(.dark) .sqd-theme-icon-sun{display:none}html:not(.dark) .sqd-theme-icon-moon,html.dark .sqd-theme-icon-sun{display:block}html.dark .sqd-theme-icon-moon{display:none}}@layer utilities{.relative{position:relative}.static{position:static}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.table{display:table}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-6{height:calc(var(--spacing)*6)}.h-12{height:calc(var(--spacing)*12)}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-6{width:calc(var(--spacing)*6)}.w-12{width:calc(var(--spacing)*12)}.w-full{width:100%}.max-w-screen-2xl{max-width:var(--breakpoint-2xl)}.flex-shrink-0{flex-shrink:0}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}.border{border-style:var(--tw-border-style);border-width:1px}.px-6{padding-inline:calc(var(--spacing)*6)}.py-6{padding-block:calc(var(--spacing)*6)}.py-12{padding-block:calc(var(--spacing)*12)}.pl-1{padding-left:calc(var(--spacing)*1)}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-sky-500{color:var(--color-sky-500)}.uppercase{text-transform:uppercase}.no-underline{text-decoration-line:none}.opacity-75{opacity:.75}.ring{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}@media (min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@config "../../../../tailwind.config.js";
|
|
3
|
+
@source "../../../views/**/*.erb";
|
|
4
|
+
@source "../../../components/**/*.rb";
|
|
5
|
+
|
|
6
|
+
@layer base {
|
|
7
|
+
:root {
|
|
8
|
+
--background: 0 0% 98%;
|
|
9
|
+
--foreground: 240 10% 3.9%;
|
|
10
|
+
--card: 0 0% 100%;
|
|
11
|
+
--card-foreground: 240 10% 3.9%;
|
|
12
|
+
--primary: 240 5.9% 10%;
|
|
13
|
+
--primary-foreground: 0 0% 98%;
|
|
14
|
+
--secondary: 240 4.8% 95.9%;
|
|
15
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
16
|
+
--muted: 240 4.8% 95.9%;
|
|
17
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
18
|
+
--accent: 240 4.8% 93.8%;
|
|
19
|
+
--accent-foreground: 240 5.9% 10%;
|
|
20
|
+
--destructive: 0 84.2% 60.2%;
|
|
21
|
+
--destructive-foreground: 0 0% 98%;
|
|
22
|
+
--border: 240 5.9% 90%;
|
|
23
|
+
--input: 240 5.9% 90%;
|
|
24
|
+
--ring: 240 5.9% 10%;
|
|
25
|
+
--radius: 0.65rem;
|
|
26
|
+
--chart-1: 12 76% 61%;
|
|
27
|
+
--chart-2: 173 58% 39%;
|
|
28
|
+
--chart-3: 197 37% 24%;
|
|
29
|
+
--chart-4: 43 74% 66%;
|
|
30
|
+
--chart-5: 27 87% 67%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.dark {
|
|
34
|
+
--background: 240 10% 5.4%;
|
|
35
|
+
--foreground: 0 0% 92%;
|
|
36
|
+
--card: 240 10% 3.9%;
|
|
37
|
+
--card-foreground: 0 0% 92%;
|
|
38
|
+
--primary: 0 0% 95%;
|
|
39
|
+
--primary-foreground: 240 5.9% 10%;
|
|
40
|
+
--secondary: 240 3.7% 15.9%;
|
|
41
|
+
--secondary-foreground: 0 0% 92%;
|
|
42
|
+
--muted: 240 3.7% 15.9%;
|
|
43
|
+
--muted-foreground: 240 5% 64.9%;
|
|
44
|
+
--accent: 240 3.7% 15.9%;
|
|
45
|
+
--accent-foreground: 0 0% 92%;
|
|
46
|
+
--destructive: 0 62.8% 30.6%;
|
|
47
|
+
--destructive-foreground: 0 0% 92%;
|
|
48
|
+
--border: 240 3.7% 15.9%;
|
|
49
|
+
--input: 240 3.7% 15.9%;
|
|
50
|
+
--ring: 240 4.9% 83.9%;
|
|
51
|
+
--chart-1: 220 70% 50%;
|
|
52
|
+
--chart-2: 160 60% 45%;
|
|
53
|
+
--chart-3: 30 80% 55%;
|
|
54
|
+
--chart-4: 280 65% 60%;
|
|
55
|
+
--chart-5: 340 75% 55%;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
59
|
+
|
|
60
|
+
body {
|
|
61
|
+
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
62
|
+
background-color: hsl(var(--background));
|
|
63
|
+
color: hsl(var(--foreground));
|
|
64
|
+
-webkit-font-smoothing: antialiased;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@layer components {
|
|
69
|
+
/* Navbar */
|
|
70
|
+
.navbar {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
gap: 1rem;
|
|
74
|
+
padding: 0 1.5rem;
|
|
75
|
+
height: 3.5rem;
|
|
76
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
77
|
+
background-color: hsl(var(--card));
|
|
78
|
+
}
|
|
79
|
+
.navbar-section { display: flex; align-items: center; gap: 0.375rem; }
|
|
80
|
+
.navbar-item {
|
|
81
|
+
display: inline-flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
gap: 0.375rem;
|
|
84
|
+
padding: 0.375rem 0.75rem;
|
|
85
|
+
font-size: 0.875rem;
|
|
86
|
+
font-weight: 500;
|
|
87
|
+
color: hsl(var(--muted-foreground));
|
|
88
|
+
text-decoration: none;
|
|
89
|
+
border-radius: calc(var(--radius) - 2px);
|
|
90
|
+
transition: color 150ms, background-color 150ms;
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
}
|
|
93
|
+
.navbar-item:hover {
|
|
94
|
+
color: hsl(var(--foreground));
|
|
95
|
+
background-color: hsl(var(--accent));
|
|
96
|
+
}
|
|
97
|
+
.navbar-item-current {
|
|
98
|
+
color: hsl(var(--primary-foreground));
|
|
99
|
+
background-color: hsl(var(--primary));
|
|
100
|
+
}
|
|
101
|
+
.navbar-item-current:hover {
|
|
102
|
+
color: hsl(var(--primary-foreground));
|
|
103
|
+
background-color: hsl(var(--primary));
|
|
104
|
+
opacity: 0.9;
|
|
105
|
+
}
|
|
106
|
+
.navbar-badge {
|
|
107
|
+
padding: 0.125rem 0.375rem;
|
|
108
|
+
font-size: 0.75rem;
|
|
109
|
+
font-weight: 600;
|
|
110
|
+
border-radius: calc(var(--radius) - 4px);
|
|
111
|
+
background-color: hsl(var(--muted));
|
|
112
|
+
color: hsl(var(--muted-foreground));
|
|
113
|
+
}
|
|
114
|
+
.navbar-item-current .navbar-badge {
|
|
115
|
+
background-color: hsl(var(--primary-foreground) / 0.2);
|
|
116
|
+
color: hsl(var(--primary-foreground));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Cards */
|
|
120
|
+
.card {
|
|
121
|
+
border-radius: var(--radius);
|
|
122
|
+
border: 1px solid hsl(var(--border));
|
|
123
|
+
background-color: hsl(var(--card));
|
|
124
|
+
color: hsl(var(--card-foreground));
|
|
125
|
+
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
126
|
+
}
|
|
127
|
+
.card-header {
|
|
128
|
+
display: flex;
|
|
129
|
+
flex-direction: column;
|
|
130
|
+
gap: 0.375rem;
|
|
131
|
+
padding: 1.5rem;
|
|
132
|
+
}
|
|
133
|
+
.card-title {
|
|
134
|
+
margin: 0;
|
|
135
|
+
font-size: 1rem;
|
|
136
|
+
font-weight: 600;
|
|
137
|
+
line-height: 1;
|
|
138
|
+
letter-spacing: -0.025em;
|
|
139
|
+
}
|
|
140
|
+
.card-description {
|
|
141
|
+
font-size: 0.875rem;
|
|
142
|
+
color: hsl(var(--muted-foreground));
|
|
143
|
+
}
|
|
144
|
+
.card-content { padding: 1.5rem; padding-top: 0; }
|
|
145
|
+
.card-footer { display: flex; align-items: center; padding: 1.5rem; padding-top: 0; }
|
|
146
|
+
|
|
147
|
+
/* Badges */
|
|
148
|
+
.badge {
|
|
149
|
+
display: inline-flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
gap: 0.375rem;
|
|
152
|
+
padding: 0.125rem 0.625rem;
|
|
153
|
+
font-size: 0.75rem;
|
|
154
|
+
font-weight: 500;
|
|
155
|
+
border-radius: calc(var(--radius) - 2px);
|
|
156
|
+
white-space: nowrap;
|
|
157
|
+
transition: color 150ms, background-color 150ms;
|
|
158
|
+
}
|
|
159
|
+
.badge-primary { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
|
|
160
|
+
.badge-secondary { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); }
|
|
161
|
+
.badge-destructive { background-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
|
|
162
|
+
.badge-outline { border: 1px solid hsl(var(--border)); color: hsl(var(--foreground)); background-color: transparent; }
|
|
163
|
+
|
|
164
|
+
.badge-red { background-color: rgb(239 68 68 / 0.1); color: rgb(239 68 68); }
|
|
165
|
+
.dark .badge-red { background-color: rgb(239 68 68 / 0.15); color: rgb(252 165 165); }
|
|
166
|
+
.badge-amber { background-color: rgb(251 191 36 / 0.1); color: rgb(217 119 6); }
|
|
167
|
+
.dark .badge-amber { background-color: rgb(251 191 36 / 0.15); color: rgb(252 211 77); }
|
|
168
|
+
.badge-yellow { background-color: rgb(250 204 21 / 0.1); color: rgb(161 98 7); }
|
|
169
|
+
.dark .badge-yellow { background-color: rgb(250 204 21 / 0.15); color: rgb(253 224 71); }
|
|
170
|
+
.badge-green { background-color: rgb(34 197 94 / 0.1); color: rgb(22 163 74); }
|
|
171
|
+
.dark .badge-green { background-color: rgb(34 197 94 / 0.15); color: rgb(134 239 172); }
|
|
172
|
+
.badge-sky { background-color: rgb(14 165 233 / 0.1); color: rgb(2 132 199); }
|
|
173
|
+
.dark .badge-sky { background-color: rgb(14 165 233 / 0.15); color: rgb(125 211 252); }
|
|
174
|
+
.badge-zinc { background-color: rgb(82 82 91 / 0.1); color: rgb(82 82 91); }
|
|
175
|
+
.dark .badge-zinc { background-color: rgb(82 82 91 / 0.2); color: rgb(161 161 170); }
|
|
176
|
+
|
|
177
|
+
/* Status Circles */
|
|
178
|
+
.circle { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 9999px; flex-shrink: 0; }
|
|
179
|
+
.circle-red { background-color: rgb(239 68 68); }
|
|
180
|
+
.circle-amber { background-color: rgb(251 191 36); }
|
|
181
|
+
.circle-green { background-color: rgb(34 197 94); }
|
|
182
|
+
.circle-yellow { background-color: rgb(250 204 21); }
|
|
183
|
+
.circle-sky { background-color: rgb(14 165 233); }
|
|
184
|
+
.circle-zinc { background-color: rgb(82 82 91); }
|
|
185
|
+
|
|
186
|
+
/* Buttons */
|
|
187
|
+
.btn {
|
|
188
|
+
display: inline-flex;
|
|
189
|
+
align-items: center;
|
|
190
|
+
justify-content: center;
|
|
191
|
+
gap: 0.5rem;
|
|
192
|
+
font-size: 0.875rem;
|
|
193
|
+
font-weight: 500;
|
|
194
|
+
white-space: nowrap;
|
|
195
|
+
border-radius: calc(var(--radius) - 2px);
|
|
196
|
+
border: none;
|
|
197
|
+
cursor: pointer;
|
|
198
|
+
transition: color 150ms, background-color 150ms, opacity 150ms;
|
|
199
|
+
text-decoration: none;
|
|
200
|
+
line-height: 1;
|
|
201
|
+
}
|
|
202
|
+
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
203
|
+
.btn-default {
|
|
204
|
+
background-color: hsl(var(--primary));
|
|
205
|
+
color: hsl(var(--primary-foreground));
|
|
206
|
+
padding: 0.5rem 1rem;
|
|
207
|
+
height: 2.5rem;
|
|
208
|
+
}
|
|
209
|
+
.btn-default:hover { opacity: 0.9; }
|
|
210
|
+
.btn-secondary {
|
|
211
|
+
background-color: hsl(var(--secondary));
|
|
212
|
+
color: hsl(var(--secondary-foreground));
|
|
213
|
+
border: 1px solid hsl(var(--border));
|
|
214
|
+
padding: 0.5rem 1rem;
|
|
215
|
+
height: 2.5rem;
|
|
216
|
+
}
|
|
217
|
+
.btn-secondary:hover { background-color: hsl(var(--accent)); }
|
|
218
|
+
.btn-destructive {
|
|
219
|
+
background-color: hsl(var(--destructive));
|
|
220
|
+
color: hsl(var(--destructive-foreground));
|
|
221
|
+
padding: 0.5rem 1rem;
|
|
222
|
+
height: 2.5rem;
|
|
223
|
+
}
|
|
224
|
+
.btn-destructive:hover { opacity: 0.9; }
|
|
225
|
+
.btn-outline {
|
|
226
|
+
border: 1px solid hsl(var(--border));
|
|
227
|
+
background-color: transparent;
|
|
228
|
+
color: hsl(var(--foreground));
|
|
229
|
+
padding: 0.5rem 1rem;
|
|
230
|
+
height: 2.5rem;
|
|
231
|
+
}
|
|
232
|
+
.btn-outline:hover { background-color: hsl(var(--accent)); }
|
|
233
|
+
.btn-ghost {
|
|
234
|
+
background-color: transparent;
|
|
235
|
+
color: hsl(var(--foreground));
|
|
236
|
+
padding: 0.5rem 1rem;
|
|
237
|
+
height: 2.5rem;
|
|
238
|
+
}
|
|
239
|
+
.btn-ghost:hover { background-color: hsl(var(--accent)); }
|
|
240
|
+
.btn-icon {
|
|
241
|
+
padding: 0;
|
|
242
|
+
width: 2.5rem;
|
|
243
|
+
height: 2.5rem;
|
|
244
|
+
background-color: transparent;
|
|
245
|
+
color: hsl(var(--foreground));
|
|
246
|
+
border: 1px solid hsl(var(--border));
|
|
247
|
+
}
|
|
248
|
+
.btn-icon:hover { background-color: hsl(var(--accent)); }
|
|
249
|
+
.btn-sm { height: 1.75rem; padding: 0.25rem 0.5rem; font-size: 0.75rem; }
|
|
250
|
+
.btn-xs { height: 1.5rem; padding: 0.125rem 0.5rem; font-size: 0.75rem; }
|
|
251
|
+
|
|
252
|
+
/* Select */
|
|
253
|
+
.select {
|
|
254
|
+
display: inline-flex;
|
|
255
|
+
height: 2.25rem;
|
|
256
|
+
width: 12rem;
|
|
257
|
+
align-items: center;
|
|
258
|
+
border-radius: calc(var(--radius) - 2px);
|
|
259
|
+
border: 1px solid hsl(var(--input));
|
|
260
|
+
background-color: hsl(var(--card));
|
|
261
|
+
padding: 0.375rem 0.75rem;
|
|
262
|
+
font-size: 0.875rem;
|
|
263
|
+
color: hsl(var(--foreground));
|
|
264
|
+
cursor: pointer;
|
|
265
|
+
}
|
|
266
|
+
.select:focus { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }
|
|
267
|
+
.select option { background-color: hsl(var(--card)); color: hsl(var(--foreground)); }
|
|
268
|
+
|
|
269
|
+
/* Tables */
|
|
270
|
+
.table-wrapper { overflow-x: auto; }
|
|
271
|
+
table.sqd-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; caption-side: bottom; }
|
|
272
|
+
table.sqd-table thead tr { border-bottom: 1px solid hsl(var(--border)); }
|
|
273
|
+
table.sqd-table th {
|
|
274
|
+
height: 2.5rem;
|
|
275
|
+
padding: 0 1rem;
|
|
276
|
+
text-align: left;
|
|
277
|
+
vertical-align: middle;
|
|
278
|
+
font-weight: 500;
|
|
279
|
+
font-size: 0.75rem;
|
|
280
|
+
text-transform: uppercase;
|
|
281
|
+
letter-spacing: 0.05em;
|
|
282
|
+
color: hsl(var(--muted-foreground));
|
|
283
|
+
white-space: nowrap;
|
|
284
|
+
}
|
|
285
|
+
table.sqd-table tbody tr { border-bottom: 1px solid hsl(var(--border)); transition: background-color 150ms; }
|
|
286
|
+
table.sqd-table tbody tr:hover { background-color: hsl(var(--muted) / 0.5); }
|
|
287
|
+
table.sqd-table td { padding: 0.75rem 1rem; vertical-align: middle; }
|
|
288
|
+
|
|
289
|
+
/* Info Lines */
|
|
290
|
+
.info-line {
|
|
291
|
+
display: flex;
|
|
292
|
+
align-items: center;
|
|
293
|
+
gap: 1rem;
|
|
294
|
+
padding: 0.5rem 0;
|
|
295
|
+
}
|
|
296
|
+
.info-line-label {
|
|
297
|
+
font-size: 0.875rem;
|
|
298
|
+
color: hsl(var(--muted-foreground));
|
|
299
|
+
white-space: nowrap;
|
|
300
|
+
flex-shrink: 0;
|
|
301
|
+
}
|
|
302
|
+
.info-line-separator {
|
|
303
|
+
flex: 1;
|
|
304
|
+
height: 1px;
|
|
305
|
+
background-color: hsl(var(--border));
|
|
306
|
+
}
|
|
307
|
+
.info-line-value {
|
|
308
|
+
font-size: 0.875rem;
|
|
309
|
+
font-weight: 500;
|
|
310
|
+
color: hsl(var(--foreground));
|
|
311
|
+
text-align: right;
|
|
312
|
+
white-space: nowrap;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* Alerts / Flash */
|
|
316
|
+
.alert {
|
|
317
|
+
position: relative;
|
|
318
|
+
display: flex;
|
|
319
|
+
align-items: center;
|
|
320
|
+
gap: 0.75rem;
|
|
321
|
+
padding: 1rem;
|
|
322
|
+
border-radius: var(--radius);
|
|
323
|
+
border: 1px solid;
|
|
324
|
+
font-size: 0.875rem;
|
|
325
|
+
}
|
|
326
|
+
.alert-success {
|
|
327
|
+
border-color: rgb(34 197 94 / 0.3);
|
|
328
|
+
background-color: rgb(34 197 94 / 0.05);
|
|
329
|
+
color: rgb(22 163 74);
|
|
330
|
+
}
|
|
331
|
+
.dark .alert-success { color: rgb(134 239 172); background-color: rgb(34 197 94 / 0.1); }
|
|
332
|
+
.alert-error {
|
|
333
|
+
border-color: rgb(239 68 68 / 0.3);
|
|
334
|
+
background-color: rgb(239 68 68 / 0.05);
|
|
335
|
+
color: rgb(220 38 38);
|
|
336
|
+
}
|
|
337
|
+
.dark .alert-error { color: rgb(252 165 165); background-color: rgb(239 68 68 / 0.1); }
|
|
338
|
+
.alert-warning {
|
|
339
|
+
border-color: rgb(251 191 36 / 0.3);
|
|
340
|
+
background-color: rgb(251 191 36 / 0.05);
|
|
341
|
+
color: rgb(217 119 6);
|
|
342
|
+
}
|
|
343
|
+
.dark .alert-warning { color: rgb(252 211 77); background-color: rgb(251 191 36 / 0.1); }
|
|
344
|
+
.alert-info {
|
|
345
|
+
border-color: rgb(14 165 233 / 0.3);
|
|
346
|
+
background-color: rgb(14 165 233 / 0.05);
|
|
347
|
+
color: rgb(2 132 199);
|
|
348
|
+
}
|
|
349
|
+
.dark .alert-info { color: rgb(125 211 252); background-color: rgb(14 165 233 / 0.1); }
|
|
350
|
+
|
|
351
|
+
/* Pagination */
|
|
352
|
+
.pagination-nav { display: flex; align-items: center; justify-content: center; gap: 0.25rem; }
|
|
353
|
+
.pagination-link {
|
|
354
|
+
display: inline-flex;
|
|
355
|
+
align-items: center;
|
|
356
|
+
justify-content: center;
|
|
357
|
+
min-width: 2rem;
|
|
358
|
+
height: 2rem;
|
|
359
|
+
padding: 0 0.5rem;
|
|
360
|
+
font-size: 0.875rem;
|
|
361
|
+
font-weight: 500;
|
|
362
|
+
color: hsl(var(--muted-foreground));
|
|
363
|
+
text-decoration: none;
|
|
364
|
+
border-radius: calc(var(--radius) - 2px);
|
|
365
|
+
transition: background-color 150ms;
|
|
366
|
+
}
|
|
367
|
+
.pagination-link:hover { background-color: hsl(var(--accent)); color: hsl(var(--foreground)); }
|
|
368
|
+
.pagination-active {
|
|
369
|
+
background-color: hsl(var(--primary));
|
|
370
|
+
color: hsl(var(--primary-foreground));
|
|
371
|
+
border: 1px solid hsl(var(--primary));
|
|
372
|
+
}
|
|
373
|
+
.pagination-disabled { opacity: 0.5; cursor: not-allowed; }
|
|
374
|
+
|
|
375
|
+
/* Link utility */
|
|
376
|
+
.link { color: hsl(var(--foreground)); text-decoration: underline; text-underline-offset: 4px; }
|
|
377
|
+
.link:hover { opacity: 0.75; }
|
|
378
|
+
|
|
379
|
+
/* Chart */
|
|
380
|
+
.sqd-chart { position: relative; width: 100%; height: 200px; }
|
|
381
|
+
.sqd-chart canvas { width: 100% !important; height: 100% !important; }
|
|
382
|
+
|
|
383
|
+
/* Code blocks */
|
|
384
|
+
.code-block {
|
|
385
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
386
|
+
font-size: 0.8125rem;
|
|
387
|
+
background-color: hsl(var(--muted));
|
|
388
|
+
padding: 0.75rem;
|
|
389
|
+
border-radius: calc(var(--radius) - 2px);
|
|
390
|
+
overflow-x: auto;
|
|
391
|
+
white-space: pre-wrap;
|
|
392
|
+
word-break: break-word;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* Stat card */
|
|
396
|
+
.stat-card {
|
|
397
|
+
border-radius: var(--radius);
|
|
398
|
+
border: 1px solid hsl(var(--border));
|
|
399
|
+
background-color: hsl(var(--card));
|
|
400
|
+
padding: 1.5rem;
|
|
401
|
+
display: flex;
|
|
402
|
+
flex-direction: column;
|
|
403
|
+
gap: 0.25rem;
|
|
404
|
+
text-decoration: none;
|
|
405
|
+
transition: border-color 150ms;
|
|
406
|
+
}
|
|
407
|
+
a.stat-card:hover { border-color: hsl(var(--foreground) / 0.2); }
|
|
408
|
+
.stat-card-label {
|
|
409
|
+
font-size: 0.875rem;
|
|
410
|
+
font-weight: 500;
|
|
411
|
+
color: hsl(var(--muted-foreground));
|
|
412
|
+
display: flex;
|
|
413
|
+
align-items: center;
|
|
414
|
+
gap: 0.5rem;
|
|
415
|
+
}
|
|
416
|
+
.stat-card-value {
|
|
417
|
+
font-size: 2.25rem;
|
|
418
|
+
font-weight: 700;
|
|
419
|
+
line-height: 1;
|
|
420
|
+
color: hsl(var(--foreground));
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/* Utility: sqd-rate badge colors (reused from failure stats) */
|
|
424
|
+
.sqd-rate-low { background-color: rgb(34 197 94 / 0.1); color: rgb(22 163 74); }
|
|
425
|
+
.dark .sqd-rate-low { background-color: rgb(34 197 94 / 0.15); color: rgb(134 239 172); }
|
|
426
|
+
.sqd-rate-medium { background-color: rgb(251 191 36 / 0.1); color: rgb(217 119 6); }
|
|
427
|
+
.dark .sqd-rate-medium { background-color: rgb(251 191 36 / 0.15); color: rgb(252 211 77); }
|
|
428
|
+
.sqd-rate-high { background-color: rgb(239 68 68 / 0.1); color: rgb(220 38 38); }
|
|
429
|
+
.dark .sqd-rate-high { background-color: rgb(239 68 68 / 0.15); color: rgb(252 165 165); }
|
|
430
|
+
|
|
431
|
+
/* Legacy compat: sqd- prefixed classes used by existing tests */
|
|
432
|
+
.sqd-nav-link { }
|
|
433
|
+
.sqd-nav-badge { }
|
|
434
|
+
.sqd-theme-toggle { }
|
|
435
|
+
.sqd-theme-icon-sun, .sqd-theme-icon-moon { }
|
|
436
|
+
.sqd-refresh-selector { }
|
|
437
|
+
.sqd-refresh-select { }
|
|
438
|
+
.sqd-per-page-selector { }
|
|
439
|
+
.sqd-per-page-select { }
|
|
440
|
+
.sqd-filters { }
|
|
441
|
+
.sqd-filter-select { }
|
|
442
|
+
.sqd-failure-rates { }
|
|
443
|
+
.sqd-failure-table { }
|
|
444
|
+
.sqd-retry-badge {
|
|
445
|
+
padding: 0.125rem 0.375rem;
|
|
446
|
+
font-size: 0.6875rem;
|
|
447
|
+
font-weight: 600;
|
|
448
|
+
border-radius: calc(var(--radius) - 4px);
|
|
449
|
+
background-color: rgb(251 191 36 / 0.15);
|
|
450
|
+
color: rgb(217 119 6);
|
|
451
|
+
}
|
|
452
|
+
.dark .sqd-retry-badge { color: rgb(252 211 77); }
|
|
453
|
+
|
|
454
|
+
/* Dark theme icon visibility */
|
|
455
|
+
html:not(.dark) .sqd-theme-icon-sun { display: none; }
|
|
456
|
+
html:not(.dark) .sqd-theme-icon-moon { display: block; }
|
|
457
|
+
html.dark .sqd-theme-icon-sun { display: block; }
|
|
458
|
+
html.dark .sqd-theme-icon-moon { display: none; }
|
|
459
|
+
}
|
|
@@ -6,492 +6,7 @@
|
|
|
6
6
|
<meta charset="utf-8">
|
|
7
7
|
<%= csrf_meta_tags %>
|
|
8
8
|
<%= csp_meta_tag %>
|
|
9
|
-
|
|
10
|
-
<%# Tailwind Play CDN - zero build step %>
|
|
11
|
-
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
|
|
12
|
-
<script>
|
|
13
|
-
tailwind.config = {
|
|
14
|
-
darkMode: 'class',
|
|
15
|
-
theme: {
|
|
16
|
-
extend: {
|
|
17
|
-
colors: {
|
|
18
|
-
border: 'hsl(var(--border))',
|
|
19
|
-
input: 'hsl(var(--input))',
|
|
20
|
-
ring: 'hsl(var(--ring))',
|
|
21
|
-
background: 'hsl(var(--background))',
|
|
22
|
-
foreground: 'hsl(var(--foreground))',
|
|
23
|
-
primary: { DEFAULT: 'hsl(var(--primary))', foreground: 'hsl(var(--primary-foreground))' },
|
|
24
|
-
secondary: { DEFAULT: 'hsl(var(--secondary))', foreground: 'hsl(var(--secondary-foreground))' },
|
|
25
|
-
destructive: { DEFAULT: 'hsl(var(--destructive))', foreground: 'hsl(var(--destructive-foreground))' },
|
|
26
|
-
muted: { DEFAULT: 'hsl(var(--muted))', foreground: 'hsl(var(--muted-foreground))' },
|
|
27
|
-
accent: { DEFAULT: 'hsl(var(--accent))', foreground: 'hsl(var(--accent-foreground))' },
|
|
28
|
-
card: { DEFAULT: 'hsl(var(--card))', foreground: 'hsl(var(--card-foreground))' },
|
|
29
|
-
},
|
|
30
|
-
borderRadius: {
|
|
31
|
-
lg: 'var(--radius)',
|
|
32
|
-
md: 'calc(var(--radius) - 2px)',
|
|
33
|
-
sm: 'calc(var(--radius) - 4px)',
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
}
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<style>
|
|
41
|
-
/* === HSL Variable System (shadcn-inspired) === */
|
|
42
|
-
:root {
|
|
43
|
-
--background: 0 0% 98%;
|
|
44
|
-
--foreground: 240 10% 3.9%;
|
|
45
|
-
--card: 0 0% 100%;
|
|
46
|
-
--card-foreground: 240 10% 3.9%;
|
|
47
|
-
--primary: 240 5.9% 10%;
|
|
48
|
-
--primary-foreground: 0 0% 98%;
|
|
49
|
-
--secondary: 240 4.8% 95.9%;
|
|
50
|
-
--secondary-foreground: 240 5.9% 10%;
|
|
51
|
-
--muted: 240 4.8% 95.9%;
|
|
52
|
-
--muted-foreground: 240 3.8% 46.1%;
|
|
53
|
-
--accent: 240 4.8% 93.8%;
|
|
54
|
-
--accent-foreground: 240 5.9% 10%;
|
|
55
|
-
--destructive: 0 84.2% 60.2%;
|
|
56
|
-
--destructive-foreground: 0 0% 98%;
|
|
57
|
-
--border: 240 5.9% 90%;
|
|
58
|
-
--input: 240 5.9% 90%;
|
|
59
|
-
--ring: 240 5.9% 10%;
|
|
60
|
-
--radius: 0.65rem;
|
|
61
|
-
--chart-1: 12 76% 61%;
|
|
62
|
-
--chart-2: 173 58% 39%;
|
|
63
|
-
--chart-3: 197 37% 24%;
|
|
64
|
-
--chart-4: 43 74% 66%;
|
|
65
|
-
--chart-5: 27 87% 67%;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.dark {
|
|
69
|
-
--background: 240 10% 5.4%;
|
|
70
|
-
--foreground: 0 0% 92%;
|
|
71
|
-
--card: 240 10% 3.9%;
|
|
72
|
-
--card-foreground: 0 0% 92%;
|
|
73
|
-
--primary: 0 0% 95%;
|
|
74
|
-
--primary-foreground: 240 5.9% 10%;
|
|
75
|
-
--secondary: 240 3.7% 15.9%;
|
|
76
|
-
--secondary-foreground: 0 0% 92%;
|
|
77
|
-
--muted: 240 3.7% 15.9%;
|
|
78
|
-
--muted-foreground: 240 5% 64.9%;
|
|
79
|
-
--accent: 240 3.7% 15.9%;
|
|
80
|
-
--accent-foreground: 0 0% 92%;
|
|
81
|
-
--destructive: 0 62.8% 30.6%;
|
|
82
|
-
--destructive-foreground: 0 0% 92%;
|
|
83
|
-
--border: 240 3.7% 15.9%;
|
|
84
|
-
--input: 240 3.7% 15.9%;
|
|
85
|
-
--ring: 240 4.9% 83.9%;
|
|
86
|
-
--chart-1: 220 70% 50%;
|
|
87
|
-
--chart-2: 160 60% 45%;
|
|
88
|
-
--chart-3: 30 80% 55%;
|
|
89
|
-
--chart-4: 280 65% 60%;
|
|
90
|
-
--chart-5: 340 75% 55%;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
*, *::before, *::after { box-sizing: border-box; }
|
|
94
|
-
|
|
95
|
-
body {
|
|
96
|
-
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
97
|
-
background-color: hsl(var(--background));
|
|
98
|
-
color: hsl(var(--foreground));
|
|
99
|
-
-webkit-font-smoothing: antialiased;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/* === Component Classes === */
|
|
103
|
-
|
|
104
|
-
/* Navbar */
|
|
105
|
-
.navbar {
|
|
106
|
-
display: flex;
|
|
107
|
-
align-items: center;
|
|
108
|
-
gap: 1rem;
|
|
109
|
-
padding: 0 1.5rem;
|
|
110
|
-
height: 3.5rem;
|
|
111
|
-
border-bottom: 1px solid hsl(var(--border));
|
|
112
|
-
background-color: hsl(var(--card));
|
|
113
|
-
}
|
|
114
|
-
.navbar-section { display: flex; align-items: center; gap: 0.375rem; }
|
|
115
|
-
.navbar-item {
|
|
116
|
-
display: inline-flex;
|
|
117
|
-
align-items: center;
|
|
118
|
-
gap: 0.375rem;
|
|
119
|
-
padding: 0.375rem 0.75rem;
|
|
120
|
-
font-size: 0.875rem;
|
|
121
|
-
font-weight: 500;
|
|
122
|
-
color: hsl(var(--muted-foreground));
|
|
123
|
-
text-decoration: none;
|
|
124
|
-
border-radius: calc(var(--radius) - 2px);
|
|
125
|
-
transition: color 150ms, background-color 150ms;
|
|
126
|
-
white-space: nowrap;
|
|
127
|
-
}
|
|
128
|
-
.navbar-item:hover {
|
|
129
|
-
color: hsl(var(--foreground));
|
|
130
|
-
background-color: hsl(var(--accent));
|
|
131
|
-
}
|
|
132
|
-
.navbar-item-current {
|
|
133
|
-
color: hsl(var(--primary-foreground));
|
|
134
|
-
background-color: hsl(var(--primary));
|
|
135
|
-
}
|
|
136
|
-
.navbar-item-current:hover {
|
|
137
|
-
color: hsl(var(--primary-foreground));
|
|
138
|
-
background-color: hsl(var(--primary));
|
|
139
|
-
opacity: 0.9;
|
|
140
|
-
}
|
|
141
|
-
.navbar-badge {
|
|
142
|
-
padding: 0.125rem 0.375rem;
|
|
143
|
-
font-size: 0.75rem;
|
|
144
|
-
font-weight: 600;
|
|
145
|
-
border-radius: calc(var(--radius) - 4px);
|
|
146
|
-
background-color: hsl(var(--muted));
|
|
147
|
-
color: hsl(var(--muted-foreground));
|
|
148
|
-
}
|
|
149
|
-
.navbar-item-current .navbar-badge {
|
|
150
|
-
background-color: hsl(var(--primary-foreground) / 0.2);
|
|
151
|
-
color: hsl(var(--primary-foreground));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* Cards */
|
|
155
|
-
.card {
|
|
156
|
-
border-radius: var(--radius);
|
|
157
|
-
border: 1px solid hsl(var(--border));
|
|
158
|
-
background-color: hsl(var(--card));
|
|
159
|
-
color: hsl(var(--card-foreground));
|
|
160
|
-
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
161
|
-
}
|
|
162
|
-
.card-header {
|
|
163
|
-
display: flex;
|
|
164
|
-
flex-direction: column;
|
|
165
|
-
gap: 0.375rem;
|
|
166
|
-
padding: 1.5rem;
|
|
167
|
-
}
|
|
168
|
-
.card-title {
|
|
169
|
-
margin: 0;
|
|
170
|
-
font-size: 1rem;
|
|
171
|
-
font-weight: 600;
|
|
172
|
-
line-height: 1;
|
|
173
|
-
letter-spacing: -0.025em;
|
|
174
|
-
}
|
|
175
|
-
.card-description {
|
|
176
|
-
font-size: 0.875rem;
|
|
177
|
-
color: hsl(var(--muted-foreground));
|
|
178
|
-
}
|
|
179
|
-
.card-content { padding: 1.5rem; padding-top: 0; }
|
|
180
|
-
.card-footer { display: flex; align-items: center; padding: 1.5rem; padding-top: 0; }
|
|
181
|
-
|
|
182
|
-
/* Badges */
|
|
183
|
-
.badge {
|
|
184
|
-
display: inline-flex;
|
|
185
|
-
align-items: center;
|
|
186
|
-
gap: 0.375rem;
|
|
187
|
-
padding: 0.125rem 0.625rem;
|
|
188
|
-
font-size: 0.75rem;
|
|
189
|
-
font-weight: 500;
|
|
190
|
-
border-radius: calc(var(--radius) - 2px);
|
|
191
|
-
white-space: nowrap;
|
|
192
|
-
transition: color 150ms, background-color 150ms;
|
|
193
|
-
}
|
|
194
|
-
.badge-primary { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
|
|
195
|
-
.badge-secondary { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); }
|
|
196
|
-
.badge-destructive { background-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
|
|
197
|
-
.badge-outline { border: 1px solid hsl(var(--border)); color: hsl(var(--foreground)); background-color: transparent; }
|
|
198
|
-
|
|
199
|
-
.badge-red { background-color: rgb(239 68 68 / 0.1); color: rgb(239 68 68); }
|
|
200
|
-
.dark .badge-red { background-color: rgb(239 68 68 / 0.15); color: rgb(252 165 165); }
|
|
201
|
-
.badge-amber { background-color: rgb(251 191 36 / 0.1); color: rgb(217 119 6); }
|
|
202
|
-
.dark .badge-amber { background-color: rgb(251 191 36 / 0.15); color: rgb(252 211 77); }
|
|
203
|
-
.badge-yellow { background-color: rgb(250 204 21 / 0.1); color: rgb(161 98 7); }
|
|
204
|
-
.dark .badge-yellow { background-color: rgb(250 204 21 / 0.15); color: rgb(253 224 71); }
|
|
205
|
-
.badge-green { background-color: rgb(34 197 94 / 0.1); color: rgb(22 163 74); }
|
|
206
|
-
.dark .badge-green { background-color: rgb(34 197 94 / 0.15); color: rgb(134 239 172); }
|
|
207
|
-
.badge-sky { background-color: rgb(14 165 233 / 0.1); color: rgb(2 132 199); }
|
|
208
|
-
.dark .badge-sky { background-color: rgb(14 165 233 / 0.15); color: rgb(125 211 252); }
|
|
209
|
-
.badge-zinc { background-color: rgb(82 82 91 / 0.1); color: rgb(82 82 91); }
|
|
210
|
-
.dark .badge-zinc { background-color: rgb(82 82 91 / 0.2); color: rgb(161 161 170); }
|
|
211
|
-
|
|
212
|
-
/* Status Circles */
|
|
213
|
-
.circle { display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 9999px; flex-shrink: 0; }
|
|
214
|
-
.circle-red { background-color: rgb(239 68 68); }
|
|
215
|
-
.circle-amber { background-color: rgb(251 191 36); }
|
|
216
|
-
.circle-green { background-color: rgb(34 197 94); }
|
|
217
|
-
.circle-yellow { background-color: rgb(250 204 21); }
|
|
218
|
-
.circle-sky { background-color: rgb(14 165 233); }
|
|
219
|
-
.circle-zinc { background-color: rgb(82 82 91); }
|
|
220
|
-
|
|
221
|
-
/* Buttons */
|
|
222
|
-
.btn {
|
|
223
|
-
display: inline-flex;
|
|
224
|
-
align-items: center;
|
|
225
|
-
justify-content: center;
|
|
226
|
-
gap: 0.5rem;
|
|
227
|
-
font-size: 0.875rem;
|
|
228
|
-
font-weight: 500;
|
|
229
|
-
white-space: nowrap;
|
|
230
|
-
border-radius: calc(var(--radius) - 2px);
|
|
231
|
-
border: none;
|
|
232
|
-
cursor: pointer;
|
|
233
|
-
transition: color 150ms, background-color 150ms, opacity 150ms;
|
|
234
|
-
text-decoration: none;
|
|
235
|
-
line-height: 1;
|
|
236
|
-
}
|
|
237
|
-
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
238
|
-
.btn-default {
|
|
239
|
-
background-color: hsl(var(--primary));
|
|
240
|
-
color: hsl(var(--primary-foreground));
|
|
241
|
-
padding: 0.5rem 1rem;
|
|
242
|
-
height: 2.5rem;
|
|
243
|
-
}
|
|
244
|
-
.btn-default:hover { opacity: 0.9; }
|
|
245
|
-
.btn-secondary {
|
|
246
|
-
background-color: hsl(var(--secondary));
|
|
247
|
-
color: hsl(var(--secondary-foreground));
|
|
248
|
-
border: 1px solid hsl(var(--border));
|
|
249
|
-
padding: 0.5rem 1rem;
|
|
250
|
-
height: 2.5rem;
|
|
251
|
-
}
|
|
252
|
-
.btn-secondary:hover { background-color: hsl(var(--accent)); }
|
|
253
|
-
.btn-destructive {
|
|
254
|
-
background-color: hsl(var(--destructive));
|
|
255
|
-
color: hsl(var(--destructive-foreground));
|
|
256
|
-
padding: 0.5rem 1rem;
|
|
257
|
-
height: 2.5rem;
|
|
258
|
-
}
|
|
259
|
-
.btn-destructive:hover { opacity: 0.9; }
|
|
260
|
-
.btn-outline {
|
|
261
|
-
border: 1px solid hsl(var(--border));
|
|
262
|
-
background-color: transparent;
|
|
263
|
-
color: hsl(var(--foreground));
|
|
264
|
-
padding: 0.5rem 1rem;
|
|
265
|
-
height: 2.5rem;
|
|
266
|
-
}
|
|
267
|
-
.btn-outline:hover { background-color: hsl(var(--accent)); }
|
|
268
|
-
.btn-ghost {
|
|
269
|
-
background-color: transparent;
|
|
270
|
-
color: hsl(var(--foreground));
|
|
271
|
-
padding: 0.5rem 1rem;
|
|
272
|
-
height: 2.5rem;
|
|
273
|
-
}
|
|
274
|
-
.btn-ghost:hover { background-color: hsl(var(--accent)); }
|
|
275
|
-
.btn-icon {
|
|
276
|
-
padding: 0;
|
|
277
|
-
width: 2.5rem;
|
|
278
|
-
height: 2.5rem;
|
|
279
|
-
background-color: transparent;
|
|
280
|
-
color: hsl(var(--foreground));
|
|
281
|
-
border: 1px solid hsl(var(--border));
|
|
282
|
-
}
|
|
283
|
-
.btn-icon:hover { background-color: hsl(var(--accent)); }
|
|
284
|
-
.btn-sm { height: 1.75rem; padding: 0.25rem 0.5rem; font-size: 0.75rem; }
|
|
285
|
-
.btn-xs { height: 1.5rem; padding: 0.125rem 0.5rem; font-size: 0.75rem; }
|
|
286
|
-
|
|
287
|
-
/* Select */
|
|
288
|
-
.select {
|
|
289
|
-
display: inline-flex;
|
|
290
|
-
height: 2.25rem;
|
|
291
|
-
width: 12rem;
|
|
292
|
-
align-items: center;
|
|
293
|
-
border-radius: calc(var(--radius) - 2px);
|
|
294
|
-
border: 1px solid hsl(var(--input));
|
|
295
|
-
background-color: hsl(var(--card));
|
|
296
|
-
padding: 0.375rem 0.75rem;
|
|
297
|
-
font-size: 0.875rem;
|
|
298
|
-
color: hsl(var(--foreground));
|
|
299
|
-
cursor: pointer;
|
|
300
|
-
}
|
|
301
|
-
.select:focus { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }
|
|
302
|
-
.select option { background-color: hsl(var(--card)); color: hsl(var(--foreground)); }
|
|
303
|
-
|
|
304
|
-
/* Tables */
|
|
305
|
-
.table-wrapper { overflow-x: auto; }
|
|
306
|
-
table.sqd-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; caption-side: bottom; }
|
|
307
|
-
table.sqd-table thead tr { border-bottom: 1px solid hsl(var(--border)); }
|
|
308
|
-
table.sqd-table th {
|
|
309
|
-
height: 2.5rem;
|
|
310
|
-
padding: 0 1rem;
|
|
311
|
-
text-align: left;
|
|
312
|
-
vertical-align: middle;
|
|
313
|
-
font-weight: 500;
|
|
314
|
-
font-size: 0.75rem;
|
|
315
|
-
text-transform: uppercase;
|
|
316
|
-
letter-spacing: 0.05em;
|
|
317
|
-
color: hsl(var(--muted-foreground));
|
|
318
|
-
white-space: nowrap;
|
|
319
|
-
}
|
|
320
|
-
table.sqd-table tbody tr { border-bottom: 1px solid hsl(var(--border)); transition: background-color 150ms; }
|
|
321
|
-
table.sqd-table tbody tr:hover { background-color: hsl(var(--muted) / 0.5); }
|
|
322
|
-
table.sqd-table td { padding: 0.75rem 1rem; vertical-align: middle; }
|
|
323
|
-
|
|
324
|
-
/* Info Lines */
|
|
325
|
-
.info-line {
|
|
326
|
-
display: flex;
|
|
327
|
-
align-items: center;
|
|
328
|
-
gap: 1rem;
|
|
329
|
-
padding: 0.5rem 0;
|
|
330
|
-
}
|
|
331
|
-
.info-line-label {
|
|
332
|
-
font-size: 0.875rem;
|
|
333
|
-
color: hsl(var(--muted-foreground));
|
|
334
|
-
white-space: nowrap;
|
|
335
|
-
flex-shrink: 0;
|
|
336
|
-
}
|
|
337
|
-
.info-line-separator {
|
|
338
|
-
flex: 1;
|
|
339
|
-
height: 1px;
|
|
340
|
-
background-color: hsl(var(--border));
|
|
341
|
-
}
|
|
342
|
-
.info-line-value {
|
|
343
|
-
font-size: 0.875rem;
|
|
344
|
-
font-weight: 500;
|
|
345
|
-
color: hsl(var(--foreground));
|
|
346
|
-
text-align: right;
|
|
347
|
-
white-space: nowrap;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/* Alerts / Flash */
|
|
351
|
-
.alert {
|
|
352
|
-
position: relative;
|
|
353
|
-
display: flex;
|
|
354
|
-
align-items: center;
|
|
355
|
-
gap: 0.75rem;
|
|
356
|
-
padding: 1rem;
|
|
357
|
-
border-radius: var(--radius);
|
|
358
|
-
border: 1px solid;
|
|
359
|
-
font-size: 0.875rem;
|
|
360
|
-
}
|
|
361
|
-
.alert-success {
|
|
362
|
-
border-color: rgb(34 197 94 / 0.3);
|
|
363
|
-
background-color: rgb(34 197 94 / 0.05);
|
|
364
|
-
color: rgb(22 163 74);
|
|
365
|
-
}
|
|
366
|
-
.dark .alert-success { color: rgb(134 239 172); background-color: rgb(34 197 94 / 0.1); }
|
|
367
|
-
.alert-error {
|
|
368
|
-
border-color: rgb(239 68 68 / 0.3);
|
|
369
|
-
background-color: rgb(239 68 68 / 0.05);
|
|
370
|
-
color: rgb(220 38 38);
|
|
371
|
-
}
|
|
372
|
-
.dark .alert-error { color: rgb(252 165 165); background-color: rgb(239 68 68 / 0.1); }
|
|
373
|
-
.alert-warning {
|
|
374
|
-
border-color: rgb(251 191 36 / 0.3);
|
|
375
|
-
background-color: rgb(251 191 36 / 0.05);
|
|
376
|
-
color: rgb(217 119 6);
|
|
377
|
-
}
|
|
378
|
-
.dark .alert-warning { color: rgb(252 211 77); background-color: rgb(251 191 36 / 0.1); }
|
|
379
|
-
.alert-info {
|
|
380
|
-
border-color: rgb(14 165 233 / 0.3);
|
|
381
|
-
background-color: rgb(14 165 233 / 0.05);
|
|
382
|
-
color: rgb(2 132 199);
|
|
383
|
-
}
|
|
384
|
-
.dark .alert-info { color: rgb(125 211 252); background-color: rgb(14 165 233 / 0.1); }
|
|
385
|
-
|
|
386
|
-
/* Pagination */
|
|
387
|
-
.pagination-nav { display: flex; align-items: center; justify-content: center; gap: 0.25rem; }
|
|
388
|
-
.pagination-link {
|
|
389
|
-
display: inline-flex;
|
|
390
|
-
align-items: center;
|
|
391
|
-
justify-content: center;
|
|
392
|
-
min-width: 2rem;
|
|
393
|
-
height: 2rem;
|
|
394
|
-
padding: 0 0.5rem;
|
|
395
|
-
font-size: 0.875rem;
|
|
396
|
-
font-weight: 500;
|
|
397
|
-
color: hsl(var(--muted-foreground));
|
|
398
|
-
text-decoration: none;
|
|
399
|
-
border-radius: calc(var(--radius) - 2px);
|
|
400
|
-
transition: background-color 150ms;
|
|
401
|
-
}
|
|
402
|
-
.pagination-link:hover { background-color: hsl(var(--accent)); color: hsl(var(--foreground)); }
|
|
403
|
-
.pagination-active {
|
|
404
|
-
background-color: hsl(var(--primary));
|
|
405
|
-
color: hsl(var(--primary-foreground));
|
|
406
|
-
border: 1px solid hsl(var(--primary));
|
|
407
|
-
}
|
|
408
|
-
.pagination-disabled { opacity: 0.5; cursor: not-allowed; }
|
|
409
|
-
|
|
410
|
-
/* Link utility */
|
|
411
|
-
.link { color: hsl(var(--foreground)); text-decoration: underline; text-underline-offset: 4px; }
|
|
412
|
-
.link:hover { opacity: 0.75; }
|
|
413
|
-
|
|
414
|
-
/* Chart */
|
|
415
|
-
.sqd-chart { position: relative; width: 100%; height: 200px; }
|
|
416
|
-
.sqd-chart canvas { width: 100% !important; height: 100% !important; }
|
|
417
|
-
|
|
418
|
-
/* Code blocks */
|
|
419
|
-
.code-block {
|
|
420
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
421
|
-
font-size: 0.8125rem;
|
|
422
|
-
background-color: hsl(var(--muted));
|
|
423
|
-
padding: 0.75rem;
|
|
424
|
-
border-radius: calc(var(--radius) - 2px);
|
|
425
|
-
overflow-x: auto;
|
|
426
|
-
white-space: pre-wrap;
|
|
427
|
-
word-break: break-word;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/* Stat card */
|
|
431
|
-
.stat-card {
|
|
432
|
-
border-radius: var(--radius);
|
|
433
|
-
border: 1px solid hsl(var(--border));
|
|
434
|
-
background-color: hsl(var(--card));
|
|
435
|
-
padding: 1.5rem;
|
|
436
|
-
display: flex;
|
|
437
|
-
flex-direction: column;
|
|
438
|
-
gap: 0.25rem;
|
|
439
|
-
text-decoration: none;
|
|
440
|
-
transition: border-color 150ms;
|
|
441
|
-
}
|
|
442
|
-
a.stat-card:hover { border-color: hsl(var(--foreground) / 0.2); }
|
|
443
|
-
.stat-card-label {
|
|
444
|
-
font-size: 0.875rem;
|
|
445
|
-
font-weight: 500;
|
|
446
|
-
color: hsl(var(--muted-foreground));
|
|
447
|
-
display: flex;
|
|
448
|
-
align-items: center;
|
|
449
|
-
gap: 0.5rem;
|
|
450
|
-
}
|
|
451
|
-
.stat-card-value {
|
|
452
|
-
font-size: 2.25rem;
|
|
453
|
-
font-weight: 700;
|
|
454
|
-
line-height: 1;
|
|
455
|
-
color: hsl(var(--foreground));
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/* Utility: sqd-rate badge colors (reused from failure stats) */
|
|
459
|
-
.sqd-rate-low { background-color: rgb(34 197 94 / 0.1); color: rgb(22 163 74); }
|
|
460
|
-
.dark .sqd-rate-low { background-color: rgb(34 197 94 / 0.15); color: rgb(134 239 172); }
|
|
461
|
-
.sqd-rate-medium { background-color: rgb(251 191 36 / 0.1); color: rgb(217 119 6); }
|
|
462
|
-
.dark .sqd-rate-medium { background-color: rgb(251 191 36 / 0.15); color: rgb(252 211 77); }
|
|
463
|
-
.sqd-rate-high { background-color: rgb(239 68 68 / 0.1); color: rgb(220 38 38); }
|
|
464
|
-
.dark .sqd-rate-high { background-color: rgb(239 68 68 / 0.15); color: rgb(252 165 165); }
|
|
465
|
-
|
|
466
|
-
/* Legacy compat: sqd- prefixed classes used by existing tests */
|
|
467
|
-
.sqd-nav-link { /* NavLink uses this class */ }
|
|
468
|
-
.sqd-nav-badge { /* NavLink badge class */ }
|
|
469
|
-
.sqd-theme-toggle { /* ThemeToggle uses this class */ }
|
|
470
|
-
.sqd-theme-icon-sun, .sqd-theme-icon-moon { /* Theme icons */ }
|
|
471
|
-
.sqd-refresh-selector { /* RefreshSelector wrapper */ }
|
|
472
|
-
.sqd-refresh-select { /* RefreshSelector select */ }
|
|
473
|
-
.sqd-per-page-selector { /* PerPageSelector wrapper */ }
|
|
474
|
-
.sqd-per-page-select { /* PerPageSelector select */ }
|
|
475
|
-
.sqd-filters { /* JobFilters wrapper */ }
|
|
476
|
-
.sqd-filter-select { /* JobFilters select */ }
|
|
477
|
-
.sqd-failure-rates { /* FailureRates wrapper */ }
|
|
478
|
-
.sqd-failure-table { /* FailureRates table */ }
|
|
479
|
-
.sqd-retry-badge {
|
|
480
|
-
padding: 0.125rem 0.375rem;
|
|
481
|
-
font-size: 0.6875rem;
|
|
482
|
-
font-weight: 600;
|
|
483
|
-
border-radius: calc(var(--radius) - 4px);
|
|
484
|
-
background-color: rgb(251 191 36 / 0.15);
|
|
485
|
-
color: rgb(217 119 6);
|
|
486
|
-
}
|
|
487
|
-
.dark .sqd-retry-badge { color: rgb(252 211 77); }
|
|
488
|
-
|
|
489
|
-
/* Dark theme icon visibility */
|
|
490
|
-
html:not(.dark) .sqd-theme-icon-sun { display: none; }
|
|
491
|
-
html:not(.dark) .sqd-theme-icon-moon { display: block; }
|
|
492
|
-
html.dark .sqd-theme-icon-sun { display: block; }
|
|
493
|
-
html.dark .sqd-theme-icon-moon { display: none; }
|
|
494
|
-
</style>
|
|
9
|
+
<%= stylesheet_link_tag "job_harbor/application", media: "all" %>
|
|
495
10
|
</head>
|
|
496
11
|
<body class="min-h-screen">
|
|
497
12
|
<%# === Top Navbar === %>
|
data/lib/job_harbor/version.rb
CHANGED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
namespace :job_harbor do
|
|
2
|
+
namespace :tailwind do
|
|
3
|
+
TAILWIND_VERSION = "v4.1.3"
|
|
4
|
+
|
|
5
|
+
def tailwind_platform
|
|
6
|
+
cpu = RbConfig::CONFIG["host_cpu"]
|
|
7
|
+
os = RbConfig::CONFIG["host_os"]
|
|
8
|
+
|
|
9
|
+
case os
|
|
10
|
+
when /darwin/i
|
|
11
|
+
cpu.match?(/arm|aarch64/) ? "macos-arm64" : "macos-x64"
|
|
12
|
+
when /linux/i
|
|
13
|
+
cpu.match?(/arm|aarch64/) ? "linux-arm64" : "linux-x64"
|
|
14
|
+
when /mingw|mswin/i
|
|
15
|
+
"windows-x64.exe"
|
|
16
|
+
else
|
|
17
|
+
abort "Unsupported platform: #{os} #{cpu}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def vendor_dir
|
|
22
|
+
File.join(engine_root, "vendor/tailwindcss")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def tailwind_exe
|
|
26
|
+
exe = File.join(vendor_dir, "tailwindcss")
|
|
27
|
+
exe += ".exe" if Gem.win_platform?
|
|
28
|
+
exe
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def engine_root
|
|
32
|
+
File.expand_path("../..", __dir__)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def input_css
|
|
36
|
+
File.join(engine_root, "app/assets/stylesheets/job_harbor/application.tailwind.css")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def output_css
|
|
40
|
+
File.join(engine_root, "app/assets/stylesheets/job_harbor/application.css")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc "Download Tailwind CSS standalone CLI"
|
|
44
|
+
task :install do
|
|
45
|
+
require "fileutils"
|
|
46
|
+
require "net/http"
|
|
47
|
+
require "uri"
|
|
48
|
+
|
|
49
|
+
platform = tailwind_platform
|
|
50
|
+
filename = "tailwindcss-#{platform}"
|
|
51
|
+
url = "https://github.com/tailwindlabs/tailwindcss/releases/download/#{TAILWIND_VERSION}/#{filename}"
|
|
52
|
+
|
|
53
|
+
FileUtils.mkdir_p(vendor_dir)
|
|
54
|
+
target = tailwind_exe
|
|
55
|
+
|
|
56
|
+
puts "Downloading Tailwind CSS #{TAILWIND_VERSION} for #{platform}..."
|
|
57
|
+
puts " From: #{url}"
|
|
58
|
+
puts " To: #{target}"
|
|
59
|
+
|
|
60
|
+
download_with_redirects(url, target)
|
|
61
|
+
|
|
62
|
+
FileUtils.chmod(0o755, target)
|
|
63
|
+
puts "Tailwind CSS installed successfully!"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
desc "Compile Tailwind CSS (minified)"
|
|
67
|
+
task :build do
|
|
68
|
+
ensure_cli_installed!
|
|
69
|
+
|
|
70
|
+
puts "Building Tailwind CSS..."
|
|
71
|
+
system(
|
|
72
|
+
tailwind_exe,
|
|
73
|
+
"--input", input_css,
|
|
74
|
+
"--output", output_css,
|
|
75
|
+
"--minify",
|
|
76
|
+
"--cwd", engine_root,
|
|
77
|
+
exception: true
|
|
78
|
+
)
|
|
79
|
+
puts "Built: #{output_css}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
desc "Watch and compile Tailwind CSS (development)"
|
|
83
|
+
task :watch do
|
|
84
|
+
ensure_cli_installed!
|
|
85
|
+
|
|
86
|
+
puts "Watching Tailwind CSS for changes..."
|
|
87
|
+
system(
|
|
88
|
+
tailwind_exe,
|
|
89
|
+
"--input", input_css,
|
|
90
|
+
"--output", output_css,
|
|
91
|
+
"--watch",
|
|
92
|
+
"--cwd", engine_root,
|
|
93
|
+
exception: true
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
def ensure_cli_installed!
|
|
100
|
+
return if File.executable?(tailwind_exe)
|
|
101
|
+
|
|
102
|
+
abort <<~MSG
|
|
103
|
+
Tailwind CSS CLI not found at #{tailwind_exe}
|
|
104
|
+
Run: rake job_harbor:tailwind:install
|
|
105
|
+
MSG
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def download_with_redirects(url, target, limit = 5)
|
|
109
|
+
abort "Too many redirects" if limit == 0
|
|
110
|
+
|
|
111
|
+
uri = URI.parse(url)
|
|
112
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
|
|
113
|
+
request = Net::HTTP::Get.new(uri)
|
|
114
|
+
http.request(request) do |response|
|
|
115
|
+
case response
|
|
116
|
+
when Net::HTTPRedirection
|
|
117
|
+
download_with_redirects(response["location"], target, limit - 1)
|
|
118
|
+
when Net::HTTPSuccess
|
|
119
|
+
File.open(target, "wb") do |file|
|
|
120
|
+
response.read_body { |chunk| file.write(chunk) }
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
abort "Download failed: #{response.code} #{response.message}"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: job_harbor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Evan Sparkman
|
|
@@ -62,7 +62,8 @@ extra_rdoc_files: []
|
|
|
62
62
|
files:
|
|
63
63
|
- README.md
|
|
64
64
|
- Rakefile
|
|
65
|
-
- app/assets/stylesheets/
|
|
65
|
+
- app/assets/stylesheets/job_harbor/application.css
|
|
66
|
+
- app/assets/stylesheets/job_harbor/application.tailwind.css
|
|
66
67
|
- app/components/job_harbor/application_component.rb
|
|
67
68
|
- app/components/job_harbor/badge_component.rb
|
|
68
69
|
- app/components/job_harbor/chart_component.rb
|
|
@@ -106,6 +107,7 @@ files:
|
|
|
106
107
|
- lib/job_harbor/engine.rb
|
|
107
108
|
- lib/job_harbor/version.rb
|
|
108
109
|
- lib/tasks/solidqueue_dashboard_tasks.rake
|
|
110
|
+
- lib/tasks/tailwind.rake
|
|
109
111
|
homepage: https://github.com/esparkman/job_harbor
|
|
110
112
|
licenses:
|
|
111
113
|
- MIT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/* Solid Queue Dashboard styles are inlined in the layout for self-containment */
|