@energycap/internal-ui 0.1.1 → 0.1.3
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.
- package/CHANGELOG.md +52 -0
- package/README.md +8 -1
- package/bin/cli.mjs +3 -2
- package/dist/internal-ui.css +1 -1
- package/package.json +4 -5
- package/src/components/buttons.css +7 -0
- package/src/components/layout.css +17 -12
- package/{skills → src/skills}/energycap-internal-ui/SKILL.md +8 -8
- package/src/theme.css +43 -28
- /package/{skills → src/skills}/energycap-internal-ui/reference/components.md +0 -0
- /package/{skills → src/skills}/energycap-internal-ui/reference/page-templates.md +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@energycap/internal-ui` are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
> **Upgrading?** Breaking changes are called out with a **BREAKING** marker and
|
|
9
|
+
> collected under `### Changed` / `### Removed`. Review those sections before
|
|
10
|
+
> bumping across a minor (pre-1.0) or major version.
|
|
11
|
+
|
|
12
|
+
## [0.1.3] - 2026-06-30
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- This CHANGELOG.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Sidebar footer links (`.sidebar-footer a`) now use the brighter
|
|
21
|
+
`on-dark-muted-strong` (slate-400) tone so they read as links against the dark
|
|
22
|
+
sidebar instead of blending into the muted footer text.
|
|
23
|
+
|
|
24
|
+
## [0.1.2] - 2026-06-30
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Color and layout refinements across the theme tokens and components.
|
|
29
|
+
|
|
30
|
+
### Other
|
|
31
|
+
|
|
32
|
+
- Packaging and version maintenance. The docs kitchen-sink now reads the package
|
|
33
|
+
version automatically so it never drifts from the published version.
|
|
34
|
+
|
|
35
|
+
## [0.1.1] - 2026-06-29
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- CI release pipeline: npm publish and Netlify deploy path/working-directory
|
|
40
|
+
fixes, and a supported Node version for the release workflow.
|
|
41
|
+
|
|
42
|
+
## [0.1.0] - 2026-06-29
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- Initial release. A framework-agnostic Tailwind v4 theme + component-class
|
|
47
|
+
library: design tokens (Indigo primary, Slate neutrals, Inter / Cascadia Code)
|
|
48
|
+
and component classes (`.btn`, `.card`, `.badge-*`, `.alert-*`, form controls,
|
|
49
|
+
`.table-container`, and the sidebar/layout app shell).
|
|
50
|
+
- Two consumption paths: the `.` export (`src/index.css`) for Tailwind-build
|
|
51
|
+
consumers, and the prebuilt no-build bundle (`dist/internal-ui.css`).
|
|
52
|
+
- CLI (`npx @energycap/internal-ui install-skills`) and bundled agent skills.
|
package/README.md
CHANGED
|
@@ -37,12 +37,14 @@ color tokens are also exposed as Tailwind utilities.
|
|
|
37
37
|
|----------|---------|-------|
|
|
38
38
|
| `--primary` / `--primary-hover` | `bg-primary` / `bg-primary-hover`, `text-primary` | indigo 600 / 700 |
|
|
39
39
|
| `--primary-light` | `bg-primary-light`, `border-l-primary-light` | indigo-400 (accent on dark surfaces) |
|
|
40
|
-
| `--primary-soft` | — | indigo-
|
|
40
|
+
| `--primary-soft` | — | indigo-300 (focus ring / soft fill) |
|
|
41
41
|
| `--canvas` | `bg-canvas` | slate-50 (page background) |
|
|
42
42
|
| `--surface` / `--surface-alt` | `bg-surface` / `bg-surface-alt` | white / slate-100 |
|
|
43
43
|
| `--border` / `--border-strong` | `border-border` / `border-border-strong` | slate-200 / slate-400 |
|
|
44
44
|
| `--ink` / `--ink-soft` | `text-ink` / `text-ink-soft` | slate-900 / slate-800 |
|
|
45
45
|
| `--muted` / `--muted-strong` | `text-muted` / `text-muted-strong` | slate-500 / slate-600 |
|
|
46
|
+
| `--on-dark` / `--on-dark-soft` | `text-on-dark` / `text-on-dark-soft` | slate-100 / slate-300 (text on dark surfaces) |
|
|
47
|
+
| `--on-dark-muted` / `--on-dark-muted-strong` | `text-on-dark-muted` / `text-on-dark-muted-strong` | slate-500 / slate-400 (muted text on dark) |
|
|
46
48
|
| `--success` / `--warning` / `--danger` / `--info` | `text-*` / `bg-*` | green-600 / amber-600 / red-600 / blue-500 |
|
|
47
49
|
| `--danger-hover` | `bg-danger-hover` | red-700 (solid danger button hover) |
|
|
48
50
|
| `--{success,warning,danger,info}-bg` / `-text` | — | soft fill + readable text for alerts/badges |
|
|
@@ -77,3 +79,8 @@ npx @energycap/internal-ui install-skills # -> ./.agents/skills
|
|
|
77
79
|
npm run build # compile dist/internal-ui.css (minified)
|
|
78
80
|
npm run build:debug # same, unminified for inspection
|
|
79
81
|
```
|
|
82
|
+
|
|
83
|
+
## Changelog
|
|
84
|
+
|
|
85
|
+
See [`CHANGELOG.md`](./CHANGELOG.md) for release notes and breaking changes to
|
|
86
|
+
review before upgrading.
|
package/bin/cli.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* @energycap/internal-ui CLI — currently just installs the bundled agent skills
|
|
3
|
-
into a consuming repo's agent-agnostic
|
|
3
|
+
(shipped under the package's src/skills) into a consuming repo's agent-agnostic
|
|
4
|
+
.agents/skills directory. */
|
|
4
5
|
import { cp, mkdir, readdir } from 'node:fs/promises';
|
|
5
6
|
import { existsSync } from 'node:fs';
|
|
6
7
|
import { dirname, join, resolve } from 'node:path';
|
|
@@ -24,7 +25,7 @@ function parseFlags(args) {
|
|
|
24
25
|
|
|
25
26
|
async function installSkills(args) {
|
|
26
27
|
const flags = parseFlags(args);
|
|
27
|
-
const src = join(PKG_ROOT, 'skills');
|
|
28
|
+
const src = join(PKG_ROOT, 'src', 'skills');
|
|
28
29
|
const dest = resolve(process.cwd(), flags.dest || '.agents/skills');
|
|
29
30
|
|
|
30
31
|
if (!existsSync(src)) {
|
package/dist/internal-ui.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.2 | 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-leading:initial;--tw-font-weight:initial;--tw-border-style:solid;--tw-tracking:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-mono:"Cascadia Code", "Fira Code", "Consolas", monospace;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--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}::-webkit-calendar-picker-indicator{line-height:1}:-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}body{font-family:var(--font-sans,"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);color:var(--ink);background:var(--canvas);-webkit-font-smoothing:antialiased;line-height:1.5}ol{padding-left:1.5em;list-style:decimal}ul{padding-left:1.5em;list-style:outside}:focus:not(:focus-visible){outline:none}:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:3px}}@layer components{.btn{cursor:pointer;justify-content:center;align-items:center;gap:calc(var(--spacing) * 1.5);border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-normal);line-height:var(--leading-normal);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));text-decoration-line:none;display:inline-flex}.btn:hover{color:var(--color-white);text-decoration-line:none}.btn:disabled{cursor:not-allowed;opacity:.6}.btn:focus-visible{--tw-outline-style:none;box-shadow:0 0 0 3px var(--primary-soft);outline-style:none}.btn-primary{background-color:var(--primary)}.btn-primary:hover{background-color:var(--primary-hover)}.btn-danger{background-color:var(--danger)}.btn-danger:hover{background-color:var(--danger-hover)}.btn-outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);color:var(--ink)}.btn-outline:hover{border-color:var(--border-strong);background-color:var(--canvas);color:var(--ink)}.btn-sm{padding-inline:calc(var(--spacing) * 2.5);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.btn-icon-only{height:calc(var(--spacing) * 8);width:calc(var(--spacing) * 8);padding:0}.btn-group{align-items:center;gap:calc(var(--spacing) * 1.5);display:inline-flex}.form-group{margin-bottom:calc(var(--spacing) * 5)}.form-group>label{margin-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink);display:block}.form-control{border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--ink);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));font-family:inherit}.form-control::placeholder{color:var(--border-strong)}.form-control:focus{border-color:var(--primary);--tw-outline-style:none;box-shadow:0 0 0 3px var(--primary-soft);outline-style:none}textarea.form-control{min-height:calc(var(--spacing) * 30);resize:vertical;font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}select.form-control{cursor:pointer;appearance:none;padding-right:calc(var(--spacing) * 9);--tw-leading:var(--leading-snug);line-height:var(--leading-snug);background-image:linear-gradient(45deg, transparent 50%, var(--border-strong) 50%), linear-gradient(135deg, var(--border-strong) 50%, transparent 50%);background-position:right 16px center,right 11px center;background-repeat:no-repeat;background-size:5px 5px,5px 5px}.form-hint{margin-top:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted)}.form-actions{margin-top:calc(var(--spacing) * 6);gap:calc(var(--spacing) * 2.5);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border);padding-top:calc(var(--spacing) * 4);display:flex}.card{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 5);box-shadow:var(--shadow-card)}.card-heading{margin-bottom:calc(var(--spacing) * 4);align-items:center;gap:calc(var(--spacing) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);padding-bottom:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink-soft);display:flex}.card-heading i{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.table-container{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);max-width:100%;box-shadow:var(--shadow-card);overflow:auto}.table-container table{border-collapse:collapse;width:100%}.table-container thead th{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);background-color:var(--surface-alt);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);color:var(--muted);text-transform:uppercase}.table-container tbody td{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);vertical-align:middle;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.table-container tbody tr:last-child td{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.table-container tbody tr:hover{background-color:var(--canvas)}.table-container tfoot td{border-top-style:var(--tw-border-style);border-top-width:2px;border-color:var(--border);background-color:var(--canvas);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink-soft)}.table-empty{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 10);text-align:center;color:var(--muted)}.table-sticky thead th{z-index:2;background-color:var(--surface-alt);box-shadow:inset 0 -1px 0 var(--border);position:sticky;top:0}.row-clickable{cursor:pointer;position:relative}.row-clickable:focus-within{background-color:var(--canvas)}.row-anchor{z-index:1;text-indent:-9999px;color:inherit;position:absolute;inset:0;overflow:hidden}.row-anchor:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-color:var(--primary);outline-offset:-2px;border-radius:2px}.badge{align-items:center;gap:var(--spacing);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);white-space:nowrap;border-radius:3.40282e38px;display:inline-flex}.badge-success{background:var(--success-bg);color:var(--success-text)}.badge-warning{background:var(--warning-bg);color:var(--warning-text)}.badge-danger{background:var(--danger-bg);color:var(--danger-text)}.badge-info{background:var(--info-bg);color:var(--info-text)}.badge-muted{background-color:var(--surface-alt);color:var(--muted-strong)}.alert{margin-bottom:calc(var(--spacing) * 4);align-items:center;gap:calc(var(--spacing) * 2);border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);display:flex}.alert-success{border-style:var(--tw-border-style);border-width:1px;border-color:var(--success);background:var(--success-bg);color:var(--success-text)}.alert-warning{border-style:var(--tw-border-style);border-width:1px;border-color:var(--warning);background:var(--warning-bg);color:var(--warning-text)}.alert-error,.alert-danger{border-style:var(--tw-border-style);border-width:1px;border-color:var(--danger);background:var(--danger-bg);color:var(--danger-text)}.alert-info{border-style:var(--tw-border-style);border-width:1px;border-color:var(--info);background:var(--info-bg);color:var(--info-text)}.app-shell{min-height:100dvh;display:flex}.sidebar{width:calc(var(--spacing) * 55);background-color:var(--ink);flex-direction:column;flex-shrink:0;display:flex}.sidebar-brand{align-items:center;gap:calc(var(--spacing) * 2.5);border-bottom-style:var(--tw-border-style);border-color:#ffffff1a;border-bottom-width:1px;display:flex}@supports (color:color-mix(in lab, red, red)){.sidebar-brand{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.sidebar-brand{padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);color:var(--color-white)}.sidebar-nav{padding-inline:0;padding-block:calc(var(--spacing) * 2);flex:1;margin:0;list-style-type:none;overflow-y:auto}.sidebar-nav .nav-section{padding-inline:calc(var(--spacing) * 4.5);padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);color:var(--muted-strong);text-transform:uppercase}.sidebar-nav a{align-items:center;gap:calc(var(--spacing) * 2.5);border-left-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--border-strong);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-color:#0000;border-left-width:3px;text-decoration-line:none;display:flex}.sidebar-nav a:hover{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.sidebar-nav a:hover{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.sidebar-nav a:hover{color:var(--color-white)}.sidebar-nav a.active{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.sidebar-nav a.active{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.sidebar-nav a.active{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-white);border-left-color:var(--primary-light)}.sidebar-nav .nav-icon{width:calc(var(--spacing) * 4.5);opacity:.6;flex-shrink:0}.sidebar-footer{border-top-style:var(--tw-border-style);border-color:#ffffff1a;border-top-width:1px}@supports (color:color-mix(in lab, red, red)){.sidebar-footer{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.sidebar-footer{padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 3);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted-strong)}.sidebar-footer a{color:var(--border-strong);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));text-decoration-line:none}.sidebar-footer a:hover{color:var(--color-white)}.main-content{background-color:var(--canvas);min-width:0;padding-inline:calc(var(--spacing) * 8);padding-block:calc(var(--spacing) * 6);flex:1}.content-header{margin-bottom:calc(var(--spacing) * 6)}.content-header h1{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink)}.subtitle{margin-top:calc(var(--spacing) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.toolbar{margin-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 3);display:flex}.toolbar-spacer{flex:1}.pagination{margin-top:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 3);flex-wrap:wrap;display:flex}.pagination-summary{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.pagination-summary strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink)}.pagination-controls{align-items:center;gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex}.pagination-disabled{cursor:not-allowed;opacity:.4}}@layer utilities;:root{--primary:#4f46e5;--primary-hover:#4338ca;--primary-light:#818cf8;--primary-soft:#4f46e526;--canvas:#f8fafc;--surface:#fff;--surface-alt:#f1f5f9;--border:#e2e8f0;--border-strong:#94a3b8;--ink:#0f172a;--ink-soft:#1e293b;--muted:#64748b;--muted-strong:#475569;--success:#16a34a;--warning:#d97706;--danger:#dc2626;--danger-hover:#b91c1c;--info:#3b82f6;--success-bg:#dcfce7;--success-text:#15803d;--warning-bg:#fef9c3;--warning-text:#a16207;--danger-bg:#fee2e2;--danger-text:#b91c1c;--info-bg:#dbeafe;--info-text:#2563eb;--radius-sm:4px;--radius-md:6px;--radius-lg:8px;--shadow-card:0 1px 3px #0f172a0f, 0 0 0 1px #0f172a08}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
|
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-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-mono:"Cascadia Code", "Fira Code", "Consolas", monospace;--color-red-100:oklch(93.6% .032 17.717);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-amber-600:oklch(66.6% .179 58.318);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-100:oklch(96.2% .044 156.743);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-400:oklch(67.3% .182 276.935);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--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}::-webkit-calendar-picker-indicator{line-height:1}:-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}body{font-family:var(--font-sans,"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);color:var(--ink);background:var(--canvas);-webkit-font-smoothing:antialiased;line-height:1.5}ol{padding-left:1.5em;list-style:decimal}ul{padding-left:1.5em;list-style:outside}:focus:not(:focus-visible){outline:none}:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:3px}}@layer components{.btn{cursor:pointer;justify-content:center;align-items:center;gap:calc(var(--spacing) * 1.5);border-radius:var(--radius-md);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-normal);line-height:var(--leading-normal);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-width:1px;border-color:#0000;text-decoration-line:none;display:inline-flex}.btn:hover{color:var(--color-white);text-decoration-line:none}.btn:disabled{cursor:not-allowed;opacity:.6}.btn:focus-visible{--tw-outline-style:none;box-shadow:0 0 0 3px var(--primary-soft);outline-style:none}.btn-primary{background-color:var(--primary)}.btn-primary:hover{background-color:var(--primary-hover)}.btn-danger{background-color:var(--danger)}.btn-danger:hover{background-color:var(--danger-hover)}.btn-primary:focus-visible,.btn-danger:focus-visible{border-color:var(--color-white)}.btn-outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);color:var(--ink)}.btn-outline:hover{border-color:var(--border-strong);background-color:var(--canvas);color:var(--ink)}.btn-outline:focus-visible{border-color:var(--primary)}.btn-sm{padding-inline:calc(var(--spacing) * 2.5);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.btn-icon-only{height:calc(var(--spacing) * 8);width:calc(var(--spacing) * 8);padding:0}.btn-group{align-items:center;gap:calc(var(--spacing) * 1.5);display:inline-flex}.form-group{margin-bottom:calc(var(--spacing) * 5)}.form-group>label{margin-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink);display:block}.form-control{border-radius:var(--radius-md);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--ink);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));font-family:inherit}.form-control::placeholder{color:var(--border-strong)}.form-control:focus{border-color:var(--primary);--tw-outline-style:none;box-shadow:0 0 0 3px var(--primary-soft);outline-style:none}textarea.form-control{min-height:calc(var(--spacing) * 30);resize:vertical;font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}select.form-control{cursor:pointer;appearance:none;padding-right:calc(var(--spacing) * 9);--tw-leading:var(--leading-snug);line-height:var(--leading-snug);background-image:linear-gradient(45deg, transparent 50%, var(--border-strong) 50%), linear-gradient(135deg, var(--border-strong) 50%, transparent 50%);background-position:right 16px center,right 11px center;background-repeat:no-repeat;background-size:5px 5px,5px 5px}.form-hint{margin-top:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted)}.form-actions{margin-top:calc(var(--spacing) * 6);gap:calc(var(--spacing) * 2.5);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border);padding-top:calc(var(--spacing) * 4);display:flex}.card{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 5);box-shadow:var(--shadow-card)}.card-heading{margin-bottom:calc(var(--spacing) * 4);align-items:center;gap:calc(var(--spacing) * 2);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);padding-bottom:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink-soft);display:flex}.card-heading i{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.table-container{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);max-width:100%;box-shadow:var(--shadow-card);overflow:auto}.table-container table{border-collapse:collapse;width:100%}.table-container thead th{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);background-color:var(--surface-alt);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);color:var(--muted);text-transform:uppercase}.table-container tbody td{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);vertical-align:middle;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.table-container tbody tr:last-child td{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.table-container tbody tr:hover{background-color:var(--canvas)}.table-container tfoot td{border-top-style:var(--tw-border-style);border-top-width:2px;border-color:var(--border);background-color:var(--canvas);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink-soft)}.table-empty{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 10);text-align:center;color:var(--muted)}.table-sticky thead th{z-index:2;background-color:var(--surface-alt);box-shadow:inset 0 -1px 0 var(--border);position:sticky;top:0}.row-clickable{cursor:pointer;position:relative}.row-clickable:focus-within{background-color:var(--canvas)}.row-anchor{z-index:1;text-indent:-9999px;color:inherit;position:absolute;inset:0;overflow:hidden}.row-anchor:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-color:var(--primary);outline-offset:-2px;border-radius:2px}.badge{align-items:center;gap:var(--spacing);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);white-space:nowrap;border-radius:3.40282e38px;display:inline-flex}.badge-success{background:var(--success-bg);color:var(--success-text)}.badge-warning{background:var(--warning-bg);color:var(--warning-text)}.badge-danger{background:var(--danger-bg);color:var(--danger-text)}.badge-info{background:var(--info-bg);color:var(--info-text)}.badge-muted{background-color:var(--surface-alt);color:var(--muted-strong)}.alert{margin-bottom:calc(var(--spacing) * 4);align-items:center;gap:calc(var(--spacing) * 2);border-radius:var(--radius-md);padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);display:flex}.alert-success{border-style:var(--tw-border-style);border-width:1px;border-color:var(--success);background:var(--success-bg);color:var(--success-text)}.alert-warning{border-style:var(--tw-border-style);border-width:1px;border-color:var(--warning);background:var(--warning-bg);color:var(--warning-text)}.alert-error,.alert-danger{border-style:var(--tw-border-style);border-width:1px;border-color:var(--danger);background:var(--danger-bg);color:var(--danger-text)}.alert-info{border-style:var(--tw-border-style);border-width:1px;border-color:var(--info);background:var(--info-bg);color:var(--info-text)}.app-shell{height:100dvh;display:flex;overflow:hidden}.sidebar{width:calc(var(--spacing) * 55);background-color:var(--ink);flex-direction:column;flex-shrink:0;display:flex}.sidebar-brand{align-items:center;gap:calc(var(--spacing) * 2.5);border-bottom-style:var(--tw-border-style);border-color:#ffffff1a;border-bottom-width:1px;display:flex}@supports (color:color-mix(in lab, red, red)){.sidebar-brand{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.sidebar-brand{padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);color:var(--on-dark)}.sidebar>nav{flex-direction:column;flex:1;min-height:0;display:flex}.sidebar-nav{padding-inline:0;padding-block:calc(var(--spacing) * 2);flex:1;margin:0;list-style-type:none;overflow-y:auto}.sidebar-nav .nav-section{padding-inline:calc(var(--spacing) * 4.5);padding-top:calc(var(--spacing) * 4);padding-bottom:calc(var(--spacing) * 1.5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);color:var(--on-dark-muted);text-transform:uppercase}.sidebar-nav a{align-items:center;gap:calc(var(--spacing) * 2.5);border-left-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--on-dark-soft);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-color:#0000;border-left-width:3px;text-decoration-line:none;display:flex}.sidebar-nav a:hover{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.sidebar-nav a:hover{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.sidebar-nav a:hover{color:var(--on-dark)}.sidebar-nav a.active{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.sidebar-nav a.active{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.sidebar-nav a.active{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--on-dark);border-left-color:var(--primary-light)}.sidebar-nav .nav-icon{width:calc(var(--spacing) * 4.5);opacity:.6;flex-shrink:0}.sidebar-footer{border-top-style:var(--tw-border-style);border-color:#ffffff1a;border-top-width:1px}@supports (color:color-mix(in lab, red, red)){.sidebar-footer{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.sidebar-footer{padding-inline:calc(var(--spacing) * 4.5);padding-block:calc(var(--spacing) * 3);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--on-dark-muted)}.sidebar-footer a{color:var(--on-dark-muted-strong);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));text-decoration-line:none}.sidebar-footer a:hover{color:var(--on-dark)}.main-content{background-color:var(--canvas);min-width:0;padding-inline:calc(var(--spacing) * 8);padding-block:calc(var(--spacing) * 6);flex:1;overflow-y:auto}.content-header{margin-bottom:calc(var(--spacing) * 6)}.content-header h1{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink)}.subtitle{margin-top:calc(var(--spacing) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.toolbar{margin-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 3);display:flex}.toolbar-spacer{flex:1}.pagination{margin-top:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 3);flex-wrap:wrap;display:flex}.pagination-summary{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.pagination-summary strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink)}.pagination-controls{align-items:center;gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex}.pagination-disabled{cursor:not-allowed;opacity:.4}}@layer utilities;:root{--primary:var(--color-indigo-600);--primary-hover:var(--color-indigo-700);--primary-light:var(--color-indigo-400);--primary-soft:var(--color-indigo-300);--canvas:var(--color-slate-50);--surface:var(--color-white);--surface-alt:var(--color-slate-100);--border:var(--color-slate-200);--border-strong:var(--color-slate-400);--ink:var(--color-slate-900);--ink-soft:var(--color-slate-800);--muted:var(--color-slate-500);--muted-strong:var(--color-slate-600);--on-dark:var(--color-slate-100);--on-dark-soft:var(--color-slate-300);--on-dark-muted-strong:var(--color-slate-400);--on-dark-muted:var(--color-slate-500);--success:var(--color-green-600);--warning:var(--color-amber-600);--danger:var(--color-red-600);--danger-hover:var(--color-red-700);--info:var(--color-blue-500);--success-bg:var(--color-green-100);--success-text:var(--color-green-700);--warning-bg:var(--color-yellow-100);--warning-text:var(--color-yellow-700);--danger-bg:var(--color-red-100);--danger-text:var(--color-red-700);--info-bg:var(--color-blue-100);--info-text:var(--color-blue-600);--radius-sm:4px;--radius-md:6px;--radius-lg:8px;--shadow-card:0 1px 3px #0f172a0f, 0 0 0 1px #0f172a08}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@energycap/internal-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "EnergyCAP internal UI — shared Tailwind v4 theme + component classes for internal tools. Framework-agnostic.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"src",
|
|
14
14
|
"dist",
|
|
15
|
-
"skills",
|
|
16
15
|
"bin",
|
|
17
|
-
"README.md"
|
|
16
|
+
"README.md",
|
|
17
|
+
"CHANGELOG.md"
|
|
18
18
|
],
|
|
19
19
|
"bin": {
|
|
20
20
|
"internal-ui": "./bin/cli.mjs"
|
|
@@ -22,8 +22,7 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tailwindcss -i ./src/dist-entry.css -o ./dist/internal-ui.css --minify",
|
|
24
24
|
"build:debug": "tailwindcss -i ./src/dist-entry.css -o ./dist/internal-ui.css",
|
|
25
|
-
"
|
|
26
|
-
"prepublishOnly": "npm run sync:skills && npm run build"
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
27
26
|
},
|
|
28
27
|
"devDependencies": {
|
|
29
28
|
"@tailwindcss/cli": "^4.3.0",
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
.btn {
|
|
3
3
|
@apply inline-flex items-center justify-center gap-1.5 px-3.5 py-1.5
|
|
4
4
|
rounded-md text-sm font-medium leading-normal text-white
|
|
5
|
+
border border-transparent
|
|
5
6
|
no-underline cursor-pointer transition-colors;
|
|
6
7
|
}
|
|
7
8
|
.btn:hover { @apply text-white no-underline; }
|
|
8
9
|
.btn:disabled { @apply opacity-60 cursor-not-allowed; }
|
|
10
|
+
/* Focus mirrors .form-control: a primary-soft glow plus a border that turns
|
|
11
|
+
readable against the button's own fill — white on dark fills, primary on outline. */
|
|
9
12
|
.btn:focus-visible {
|
|
10
13
|
@apply outline-none;
|
|
11
14
|
box-shadow: 0 0 0 3px var(--primary-soft);
|
|
@@ -17,8 +20,12 @@
|
|
|
17
20
|
.btn-danger { @apply bg-danger; }
|
|
18
21
|
.btn-danger:hover { @apply bg-danger-hover; }
|
|
19
22
|
|
|
23
|
+
.btn-primary:focus-visible,
|
|
24
|
+
.btn-danger:focus-visible { @apply border-white; }
|
|
25
|
+
|
|
20
26
|
.btn-outline { @apply bg-surface border border-border text-ink; }
|
|
21
27
|
.btn-outline:hover { @apply bg-canvas border-border-strong text-ink; }
|
|
28
|
+
.btn-outline:focus-visible { @apply border-primary; }
|
|
22
29
|
|
|
23
30
|
.btn-sm { @apply px-2.5 py-1 text-xs; }
|
|
24
31
|
.btn-icon-only { @apply w-8 h-8 p-0; }
|
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/* App shell: sidebar + content side by side,
|
|
3
|
-
|
|
2
|
+
/* App shell: sidebar + content side by side, locked to the viewport so the
|
|
3
|
+
sidebar stays put and only .main-content scrolls. */
|
|
4
|
+
.app-shell { @apply flex h-dvh overflow-hidden; }
|
|
4
5
|
|
|
5
6
|
/* ── Sidebar ──────────────────────────────────────────────────── */
|
|
6
7
|
.sidebar { @apply flex flex-col shrink-0 w-55 bg-ink; }
|
|
7
8
|
.sidebar-brand {
|
|
8
9
|
@apply flex items-center gap-2.5 px-4.5 py-4 text-sm font-bold tracking-wide
|
|
9
|
-
text-
|
|
10
|
+
text-on-dark border-b border-white/10;
|
|
10
11
|
}
|
|
12
|
+
/* The <nav> wrapper is the flex child that fills the gap so .sidebar-footer
|
|
13
|
+
drops to the bottom; min-h-0 lets the inner list scroll instead of growing. */
|
|
14
|
+
.sidebar > nav { @apply flex-1 flex flex-col min-h-0; }
|
|
11
15
|
/* px-0 (alongside m-0) keeps the nav flush even under a consumer global
|
|
12
|
-
`ul { padding-left }` reset — list padding must never indent nav items.
|
|
16
|
+
`ul { padding-left }` reset — list padding must never indent nav items.
|
|
17
|
+
flex-1 also bottoms the footer for consumers who skip the <nav> wrapper. */
|
|
13
18
|
.sidebar-nav { @apply flex-1 m-0 px-0 py-2 list-none overflow-y-auto; }
|
|
14
19
|
.sidebar-nav .nav-section {
|
|
15
|
-
@apply px-4.5 pt-4 pb-1.5 text-xs font-semibold uppercase tracking-wider text-muted
|
|
20
|
+
@apply px-4.5 pt-4 pb-1.5 text-xs font-semibold uppercase tracking-wider text-on-dark-muted;
|
|
16
21
|
}
|
|
17
22
|
.sidebar-nav a {
|
|
18
23
|
@apply flex items-center gap-2.5 px-4.5 py-2 text-sm font-medium
|
|
19
|
-
text-
|
|
24
|
+
text-on-dark-soft no-underline border-l-[3px] border-transparent transition-colors;
|
|
20
25
|
}
|
|
21
|
-
.sidebar-nav a:hover { @apply bg-white/[0.06] text-
|
|
26
|
+
.sidebar-nav a:hover { @apply bg-white/[0.06] text-on-dark; }
|
|
22
27
|
.sidebar-nav a.active {
|
|
23
|
-
@apply bg-white/[0.06] text-
|
|
28
|
+
@apply bg-white/[0.06] text-on-dark font-semibold;
|
|
24
29
|
border-left-color: var(--primary-light);
|
|
25
30
|
}
|
|
26
31
|
.sidebar-nav .nav-icon { @apply w-4.5 shrink-0 opacity-60; }
|
|
27
32
|
.sidebar-footer {
|
|
28
|
-
@apply px-4.5 py-3 text-xs text-muted
|
|
33
|
+
@apply px-4.5 py-3 text-xs text-on-dark-muted border-t border-white/10;
|
|
29
34
|
}
|
|
30
|
-
.sidebar-footer a { @apply text-
|
|
31
|
-
.sidebar-footer a:hover { @apply text-
|
|
35
|
+
.sidebar-footer a { @apply text-on-dark-muted-strong no-underline transition-colors; }
|
|
36
|
+
.sidebar-footer a:hover { @apply text-on-dark; }
|
|
32
37
|
|
|
33
38
|
/* ── Main content ─────────────────────────────────────────────── */
|
|
34
|
-
.main-content { @apply flex-1 min-w-0 px-8 py-6 bg-canvas; }
|
|
39
|
+
.main-content { @apply flex-1 min-w-0 px-8 py-6 bg-canvas overflow-y-auto; }
|
|
35
40
|
.content-header { @apply mb-6; }
|
|
36
41
|
.content-header h1 { @apply text-xl font-semibold text-ink; }
|
|
37
42
|
.subtitle { @apply mt-0.5 text-sm text-muted; }
|
|
@@ -48,21 +48,21 @@ sans otherwise):
|
|
|
48
48
|
outlines. Interactive rows use `.row-clickable` + an inner `.row-anchor`.
|
|
49
49
|
5. **Match the existing structure.** New screens should reuse the page scaffolds
|
|
50
50
|
in `reference/page-templates.md`, not invent a new layout.
|
|
51
|
-
6. **Size with Tailwind's scale.**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
`w-55`) — not arbitrary inline `style="…px"`.
|
|
51
|
+
6. **Size with Tailwind's scale.** For spacing or sizing beyond the component
|
|
52
|
+
classes, use Tailwind utilities (`px-4`, `gap-2`, `max-h-[60vh]`, `w-55`) — not
|
|
53
|
+
arbitrary inline `style="…px"`.
|
|
55
54
|
|
|
56
55
|
## Token quick reference
|
|
57
56
|
|
|
58
57
|
Colors (each is a `var(--name)` and a `bg-`/`text-`/`border-` utility):
|
|
59
58
|
`primary`, `primary-hover`, `canvas` (page bg), `surface`, `surface-alt`,
|
|
60
59
|
`border`, `border-strong`, `ink` (text), `ink-soft`, `muted`, `muted-strong`,
|
|
61
|
-
`success`, `warning`, `danger`, `info`.
|
|
62
|
-
`
|
|
60
|
+
`success`, `warning`, `danger`, `danger-hover`, `info`. For text on dark surfaces
|
|
61
|
+
(e.g. the `bg-ink` sidebar): `on-dark`, `on-dark-soft`, `on-dark-muted`,
|
|
62
|
+
`on-dark-muted-strong`. Soft fill/text pairs: `--success-bg`/`--success-text`
|
|
63
63
|
(and warning/danger/info).
|
|
64
|
-
Other: `--radius-sm|md|lg`, `--shadow-card`,
|
|
65
|
-
`font-
|
|
64
|
+
Other: `--radius-sm|md|lg`, `--shadow-card`, `font-sans` (Inter),
|
|
65
|
+
`font-mono` (Cascadia Code).
|
|
66
66
|
|
|
67
67
|
## Component quick reference
|
|
68
68
|
|
package/src/theme.css
CHANGED
|
@@ -5,47 +5,58 @@
|
|
|
5
5
|
on: Indigo primary, Slate neutrals, Inter / Cascadia Code. Values mirror
|
|
6
6
|
the proven tokens shipped in Opus so existing screens shift minimally.
|
|
7
7
|
|
|
8
|
-
Pattern (Tailwind v4): the
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
Pattern (Tailwind v4): the semantic tokens live in :root and reference
|
|
9
|
+
Tailwind's own default-palette vars (var(--color-indigo-600), …) instead of
|
|
10
|
+
restating their hex — single source of truth. Tailwind detects each
|
|
11
|
+
referenced palette var and emits it (and only it) into the output, including
|
|
12
|
+
the no-build `dist` bundle compiled with `source(none)`, so `var(--token)`
|
|
13
|
+
always resolves regardless of which utilities a consumer generates. Tokens
|
|
14
|
+
with no 1:1 palette match (custom shadow/radius) stay as literals. `@theme inline`
|
|
15
|
+
then re-exposes the semantics as Tailwind utilities (bg-primary, text-muted, …)
|
|
16
|
+
pointing straight back at these :root vars.
|
|
13
17
|
════════════════════════════════════════════════════════════════════ */
|
|
14
18
|
|
|
15
19
|
:root {
|
|
16
20
|
/* Brand / actions */
|
|
17
|
-
--primary:
|
|
18
|
-
--primary-hover:
|
|
19
|
-
--primary-light:
|
|
20
|
-
--primary-soft:
|
|
21
|
+
--primary: var(--color-indigo-600);
|
|
22
|
+
--primary-hover: var(--color-indigo-700);
|
|
23
|
+
--primary-light: var(--color-indigo-400); /* accent on dark surfaces (active nav) */
|
|
24
|
+
--primary-soft: var(--color-indigo-300); /* focus ring / soft fill */
|
|
21
25
|
|
|
22
26
|
/* Surfaces */
|
|
23
|
-
--canvas:
|
|
24
|
-
--surface:
|
|
25
|
-
--surface-alt:
|
|
27
|
+
--canvas: var(--color-slate-50); /* app background */
|
|
28
|
+
--surface: var(--color-white); /* cards, inputs, panels */
|
|
29
|
+
--surface-alt: var(--color-slate-100); /* table headers, subtle fills */
|
|
26
30
|
|
|
27
31
|
/* Lines */
|
|
28
|
-
--border:
|
|
29
|
-
--border-strong:
|
|
32
|
+
--border: var(--color-slate-200);
|
|
33
|
+
--border-strong: var(--color-slate-400);
|
|
30
34
|
|
|
31
|
-
/* Text */
|
|
32
|
-
--ink:
|
|
33
|
-
--ink-soft:
|
|
34
|
-
--muted:
|
|
35
|
-
--muted-strong:
|
|
35
|
+
/* Text — on light surfaces */
|
|
36
|
+
--ink: var(--color-slate-900); /* primary text */
|
|
37
|
+
--ink-soft: var(--color-slate-800);
|
|
38
|
+
--muted: var(--color-slate-500);
|
|
39
|
+
--muted-strong: var(--color-slate-600);
|
|
40
|
+
|
|
41
|
+
/* Text — on dark surfaces (e.g. the bg-ink sidebar). Mirrors the light scale;
|
|
42
|
+
`-strong` = more contrast (lighter here), matching --muted-strong vs --muted. */
|
|
43
|
+
--on-dark: var(--color-slate-100); /* primary text on dark */
|
|
44
|
+
--on-dark-soft: var(--color-slate-300); /* secondary */
|
|
45
|
+
--on-dark-muted-strong: var(--color-slate-400); /* muted, higher contrast */
|
|
46
|
+
--on-dark-muted: var(--color-slate-500); /* muted, dim (footer, section labels) */
|
|
36
47
|
|
|
37
48
|
/* Semantic — solid (borders, icons, fills) */
|
|
38
|
-
--success:
|
|
39
|
-
--warning:
|
|
40
|
-
--danger:
|
|
41
|
-
--danger-hover:
|
|
42
|
-
--info:
|
|
49
|
+
--success: var(--color-green-600);
|
|
50
|
+
--warning: var(--color-amber-600);
|
|
51
|
+
--danger: var(--color-red-600);
|
|
52
|
+
--danger-hover: var(--color-red-700); /* solid danger button hover */
|
|
53
|
+
--info: var(--color-blue-500);
|
|
43
54
|
|
|
44
55
|
/* Semantic — soft background + readable text (alerts, badges) */
|
|
45
|
-
--success-bg:
|
|
46
|
-
--warning-bg:
|
|
47
|
-
--danger-bg:
|
|
48
|
-
--info-bg:
|
|
56
|
+
--success-bg: var(--color-green-100); --success-text: var(--color-green-700);
|
|
57
|
+
--warning-bg: var(--color-yellow-100); --warning-text: var(--color-yellow-700);
|
|
58
|
+
--danger-bg: var(--color-red-100); --danger-text: var(--color-red-700);
|
|
59
|
+
--info-bg: var(--color-blue-100); --info-text: var(--color-blue-600);
|
|
49
60
|
|
|
50
61
|
/* Radius (matches Tailwind v4 defaults; redeclared so component CSS resolves) */
|
|
51
62
|
--radius-sm: 4px;
|
|
@@ -77,6 +88,10 @@
|
|
|
77
88
|
--color-ink-soft: var(--ink-soft);
|
|
78
89
|
--color-muted: var(--muted);
|
|
79
90
|
--color-muted-strong: var(--muted-strong);
|
|
91
|
+
--color-on-dark: var(--on-dark);
|
|
92
|
+
--color-on-dark-soft: var(--on-dark-soft);
|
|
93
|
+
--color-on-dark-muted: var(--on-dark-muted);
|
|
94
|
+
--color-on-dark-muted-strong: var(--on-dark-muted-strong);
|
|
80
95
|
--color-success: var(--success);
|
|
81
96
|
--color-warning: var(--warning);
|
|
82
97
|
--color-danger: var(--danger);
|
|
File without changes
|
|
File without changes
|