@energycap/internal-ui 0.1.4 → 0.1.6
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 +24 -0
- package/README.md +4 -1
- package/dist/internal-ui.css +1 -1
- package/package.json +1 -1
- package/src/components/forms.css +17 -0
- package/src/components/modal.css +61 -0
- package/src/index.css +1 -0
- package/src/skills/energycap-internal-ui/SKILL.md +1 -1
- package/src/skills/energycap-internal-ui/reference/components.md +82 -17
- package/src/skills/energycap-internal-ui/reference/page-templates.md +12 -12
- package/src/theme.css +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
9
9
|
> collected under `### Changed` / `### Removed`. Review those sections before
|
|
10
10
|
> bumping across a minor (pre-1.0) or major version.
|
|
11
11
|
|
|
12
|
+
## [0.1.6] - 2026-07-07
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `.form-control` readonly + disabled states: `[readonly]` gets a muted
|
|
17
|
+
`--surface-alt` fill with muted text and no focus ring (still
|
|
18
|
+
selectable/copyable); `:disabled` gets the muted fill plus reduced opacity
|
|
19
|
+
and `not-allowed` cursor.
|
|
20
|
+
|
|
21
|
+
## [0.1.5] - 2026-07-07
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Modal / dialog component: `.modal` panel with `.modal-header` + `.modal-title` +
|
|
26
|
+
`.modal-close`, `.modal-body`, and `.modal-footer`. Recommended usage is `.modal`
|
|
27
|
+
on a native `<dialog>` opened with `.showModal()` (styled `::backdrop` scrim, plus
|
|
28
|
+
a UA-chrome reset) — the browser handles the focus trap, Esc-to-close, and page
|
|
29
|
+
`inert`. A `.modal-overlay` scrim is also provided as a CSS-only, no-JS fallback
|
|
30
|
+
(toggle with the `hidden` attribute — `.modal-overlay[hidden]` is styled out — a
|
|
31
|
+
server render, or a `:target` anchor); it does not trap focus. Library ships no
|
|
32
|
+
JavaScript.
|
|
33
|
+
- `--overlay` (slate-900 @ 50%) backdrop-scrim token and `--shadow-overlay`
|
|
34
|
+
elevation token for the modal panel.
|
|
35
|
+
|
|
12
36
|
## [0.1.4] - 2026-07-01
|
|
13
37
|
|
|
14
38
|
### Added
|
package/README.md
CHANGED
|
@@ -49,8 +49,10 @@ color tokens are also exposed as Tailwind utilities.
|
|
|
49
49
|
| `--success` / `--warning` / `--danger` / `--info` | `text-*` / `bg-*` | green-600 / amber-600 / red-600 / blue-500 |
|
|
50
50
|
| `--danger-hover` | `bg-danger-hover` | red-700 (solid danger button hover) |
|
|
51
51
|
| `--{success,warning,danger,info}-bg` / `-text` | — | soft fill + readable text for alerts/badges |
|
|
52
|
+
| `--overlay` | — | slate-900 @ 50% (modal backdrop scrim) |
|
|
52
53
|
| `--radius-sm/md/lg` | `rounded-sm/md/lg` | 4 / 6 / 8 px (match Tailwind defaults) |
|
|
53
54
|
| `--shadow-card` | — | card / panel elevation |
|
|
55
|
+
| `--shadow-overlay` | — | modal / dialog elevation |
|
|
54
56
|
| `--font-sans` / `--font-mono` | `font-sans` / `font-mono` | Inter / Cascadia Code |
|
|
55
57
|
|
|
56
58
|
## Component classes
|
|
@@ -58,12 +60,13 @@ color tokens are also exposed as Tailwind utilities.
|
|
|
58
60
|
| Family | Classes |
|
|
59
61
|
|--------|---------|
|
|
60
62
|
| Buttons | `.btn` + `.btn-primary` / `.btn-outline` / `.btn-danger`, `.btn-sm`, `.btn-icon-only`, `.btn-group` |
|
|
61
|
-
| Forms | `.form-group` (`> label`), `.form-control` (input/select/textarea), `.form-hint`, `.form-actions` |
|
|
63
|
+
| Forms | `.form-group` (`> label`), `.form-control` (input/select/textarea; supports `readonly` — muted, read-only — and `disabled` — inactive — states), `.form-hint`, `.form-actions` |
|
|
62
64
|
| Cards | `.card`, `.card-heading` |
|
|
63
65
|
| Tables | `.table-container` (+ `.table-sticky`) wrapping a `<table>`; `.table-empty`; `.row-clickable` + `.row-anchor`; `.row-selected` |
|
|
64
66
|
| Badges | `.badge` + `.badge-success/warning/danger/info/muted` |
|
|
65
67
|
| Alerts | `.alert` + `.alert-success/warning/error/info` (`.alert-danger` alias) |
|
|
66
68
|
| Layout | `.app-shell`, `.sidebar` (`.sidebar-brand/-nav/-footer`, `a.active`, `.nav-section`), `.main-content`, `.content-header`, `.subtitle`, `.toolbar`, `.pagination` |
|
|
69
|
+
| Modal | `.modal` (panel) — on a native `<dialog>` (`::backdrop` scrim, recommended) or inside a `.modal-overlay` scrim (no-JS fallback); `.modal-header` + `.modal-title` + `.modal-close`; `.modal-body`; `.modal-footer` |
|
|
67
70
|
|
|
68
71
|
See the kitchen-sink docs site (`apps/docs`) for live examples of every token
|
|
69
72
|
and component.
|
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-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-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--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.row-selected{background:var(--selected)}.table-container tbody tr.row-selected td:first-child{box-shadow:inset 3px 0 0 var(--primary)}.table-container tbody tr.row-clickable:hover{background:var(--hover)}.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);--hover:var(--color-indigo-200);--selected:var(--color-indigo-100);--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}
|
|
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-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--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;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--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}.form-control[readonly]{cursor:default;background-color:var(--surface-alt);color:var(--muted-strong)}.form-control[readonly]:focus{border-color:var(--border);box-shadow:none}.form-control:disabled{cursor:not-allowed;background-color:var(--surface-alt);color:var(--muted);opacity:.6}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.row-selected{background:var(--selected)}.table-container tbody tr.row-selected td:first-child{box-shadow:inset 3px 0 0 var(--primary)}.table-container tbody tr.row-clickable:hover{background:var(--hover)}.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}.modal-overlay{z-index:50;padding:calc(var(--spacing) * 4);background:var(--overlay);justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.modal-overlay[hidden]{display:none}.modal{width:100%;max-height:calc(100dvh - 2rem);max-width:var(--container-lg);border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);background-color:var(--surface);box-shadow:var(--shadow-overlay);flex-direction:column;display:flex;overflow:hidden}dialog.modal{max-width:min(var(--container-lg), calc(100vw - 2rem));margin:auto;padding:0}dialog.modal:not([open]){display:none}dialog.modal::backdrop{background:var(--overlay)}.modal-header{justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 4);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 4);display:flex}.modal-title{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--ink)}.modal-close{height:calc(var(--spacing) * 8);width:calc(var(--spacing) * 8);cursor:pointer;border-radius:var(--radius-md);border-style:var(--tw-border-style);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-leading:1;color:var(--muted);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));background-color:#0000;border-width:0;justify-content:center;align-items:center;line-height:1;text-decoration-line:none;display:flex}.modal-close:hover{background-color:var(--canvas);color:var(--ink);text-decoration-line:none}.modal-close:focus-visible{color:var(--ink);--tw-outline-style:none;box-shadow:0 0 0 3px var(--primary-soft);outline-style:none}.modal-body{padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--ink-soft);overflow-y:auto}.modal-footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2.5);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border);padding-inline:calc(var(--spacing) * 6);padding-block:calc(var(--spacing) * 4);display:flex}}@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);--hover:var(--color-indigo-200);--selected:var(--color-indigo-100);--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);--overlay:#0f172a80;--radius-sm:4px;--radius-md:6px;--radius-lg:8px;--shadow-card:0 1px 3px #0f172a0f, 0 0 0 1px #0f172a08;--shadow-overlay:0 20px 25px -5px #0f172a26, 0 8px 10px -6px #0f172a1f}@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
package/src/components/forms.css
CHANGED
|
@@ -13,6 +13,23 @@
|
|
|
13
13
|
box-shadow: 0 0 0 3px var(--primary-soft);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/* Readonly — value is shown, still selectable/copyable, but not editable.
|
|
17
|
+
Target [readonly] (not :read-only) so only controls that explicitly set the
|
|
18
|
+
readonly attribute are affected; <select> doesn't support readonly. */
|
|
19
|
+
.form-control[readonly] {
|
|
20
|
+
@apply bg-surface-alt text-muted-strong cursor-default;
|
|
21
|
+
}
|
|
22
|
+
.form-control[readonly]:focus {
|
|
23
|
+
@apply border-border;
|
|
24
|
+
box-shadow: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Disabled — fully inactive. Mirrors the .btn:disabled idiom (opacity +
|
|
28
|
+
not-allowed) on a muted fill. */
|
|
29
|
+
.form-control:disabled {
|
|
30
|
+
@apply bg-surface-alt text-muted cursor-not-allowed opacity-60;
|
|
31
|
+
}
|
|
32
|
+
|
|
16
33
|
textarea.form-control { @apply min-h-30 resize-y font-mono text-sm leading-relaxed; }
|
|
17
34
|
|
|
18
35
|
select.form-control {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
/* Full-screen scrim that centers the panel. Ships visible when in the DOM —
|
|
3
|
+
the consumer controls open/close (server render, the `hidden` attribute, or a
|
|
4
|
+
`:target` anchor). The explicit `[hidden]` rule is needed because the base
|
|
5
|
+
`display: flex` would otherwise beat the UA `[hidden] { display: none }`. */
|
|
6
|
+
.modal-overlay {
|
|
7
|
+
@apply fixed inset-0 z-50 flex items-center justify-center p-4;
|
|
8
|
+
background: var(--overlay);
|
|
9
|
+
}
|
|
10
|
+
.modal-overlay[hidden] { @apply hidden; }
|
|
11
|
+
|
|
12
|
+
/* The centered panel — reuses the card recipe with a deeper elevation. Caps its
|
|
13
|
+
height and lets the body scroll instead of growing past the viewport. Works
|
|
14
|
+
both inside `.modal-overlay` (the no-JS scrim) and applied directly to a
|
|
15
|
+
native `<dialog>` opened with `.showModal()` (see below). */
|
|
16
|
+
.modal {
|
|
17
|
+
@apply flex flex-col w-full max-w-lg max-h-[calc(100dvh-2rem)] overflow-hidden
|
|
18
|
+
bg-surface border border-border rounded-lg;
|
|
19
|
+
box-shadow: var(--shadow-overlay);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Native <dialog> support — the recommended "real" modal: open it with
|
|
23
|
+
`.showModal()` and the browser traps focus, adds Esc-to-close, and inerts the
|
|
24
|
+
rest of the page. No `.modal-overlay` needed (the UA centers the dialog and
|
|
25
|
+
paints the scrim as `::backdrop`); here we reset the UA chrome that fights the
|
|
26
|
+
panel styles and keep a viewport gutter on small screens. */
|
|
27
|
+
dialog.modal {
|
|
28
|
+
/* `m-auto` restores the centering the UA gives modal dialogs — Tailwind's
|
|
29
|
+
Preflight resets `margin: 0` on every element, which would otherwise pin the
|
|
30
|
+
dialog to the top-left. `p-0` drops the UA `padding: 1em`. */
|
|
31
|
+
@apply p-0 m-auto;
|
|
32
|
+
max-width: min(var(--container-lg), calc(100vw - 2rem));
|
|
33
|
+
}
|
|
34
|
+
/* Author `.modal { display: flex }` outranks the UA `dialog:not([open])` rule,
|
|
35
|
+
so a closed dialog would otherwise stay visible — hide it explicitly. */
|
|
36
|
+
dialog.modal:not([open]) { @apply hidden; }
|
|
37
|
+
dialog.modal::backdrop { background: var(--overlay); }
|
|
38
|
+
|
|
39
|
+
.modal-header {
|
|
40
|
+
@apply flex items-center justify-between gap-4 px-6 py-4 border-b border-border;
|
|
41
|
+
}
|
|
42
|
+
.modal-title { @apply text-base font-semibold text-ink; }
|
|
43
|
+
|
|
44
|
+
/* Icon button for the × glyph. Works on <button> or <a>. */
|
|
45
|
+
.modal-close {
|
|
46
|
+
@apply flex items-center justify-center w-8 h-8 rounded-md
|
|
47
|
+
bg-transparent border-0 text-muted text-xl leading-none
|
|
48
|
+
no-underline cursor-pointer transition-colors;
|
|
49
|
+
}
|
|
50
|
+
.modal-close:hover { @apply bg-canvas text-ink no-underline; }
|
|
51
|
+
.modal-close:focus-visible {
|
|
52
|
+
@apply outline-none text-ink;
|
|
53
|
+
box-shadow: 0 0 0 3px var(--primary-soft);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.modal-body { @apply px-6 py-5 overflow-y-auto text-sm text-ink-soft; }
|
|
57
|
+
|
|
58
|
+
.modal-footer {
|
|
59
|
+
@apply flex items-center justify-end gap-2.5 px-6 py-4 border-t border-border;
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/index.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: energycap-internal-ui
|
|
3
|
-
description: Build or restyle UI for EnergyCAP internal tools using the @energycap/internal-ui design system (a shared Tailwind v4 theme + component classes). Use when creating or editing pages, layouts, tables, forms, buttons, badges, or alerts in any internal tool (
|
|
3
|
+
description: Build or restyle UI for EnergyCAP internal tools using the @energycap/internal-ui design system (a shared Tailwind v4 theme + component classes). Use when creating or editing pages, layouts, tables, forms, buttons, badges, or alerts in any internal tool (an admin console, an internal dashboard, or a new tool) so they match the shared look and feel — Indigo/Slate palette, Inter font, and the .btn / .card / .table-container / .badge / .alert classes plus design tokens. Applies to Razor, plain HTML, React, or any frontend that consumes @energycap/internal-ui.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Building tools with @energycap/internal-ui
|
|
@@ -25,7 +25,7 @@ variant). `:disabled` is styled automatically.
|
|
|
25
25
|
|
|
26
26
|
```html
|
|
27
27
|
<section class="card">
|
|
28
|
-
<div class="card-heading">
|
|
28
|
+
<div class="card-heading">Project details</div>
|
|
29
29
|
<!-- content -->
|
|
30
30
|
</section>
|
|
31
31
|
```
|
|
@@ -40,12 +40,12 @@ on the container so the table scrolls internally instead of growing the page.
|
|
|
40
40
|
<div class="table-container table-sticky max-h-[60vh]">
|
|
41
41
|
<table>
|
|
42
42
|
<thead>
|
|
43
|
-
<tr><th>
|
|
43
|
+
<tr><th>Project</th><th>Status</th><th>Tasks</th></tr>
|
|
44
44
|
</thead>
|
|
45
45
|
<tbody>
|
|
46
46
|
<tr class="row-clickable">
|
|
47
|
-
<td><a class="row-anchor" href="/
|
|
48
|
-
<td><span class="badge badge-success">
|
|
47
|
+
<td><a class="row-anchor" href="/projects/1">Marketing Website</a>Marketing Website</td>
|
|
48
|
+
<td><span class="badge badge-success">Active</span></td>
|
|
49
49
|
<td>1,204</td>
|
|
50
50
|
</tr>
|
|
51
51
|
</tbody>
|
|
@@ -60,7 +60,7 @@ Empty state:
|
|
|
60
60
|
|
|
61
61
|
```html
|
|
62
62
|
<tbody>
|
|
63
|
-
<tr><td class="table-empty" colspan="3">No
|
|
63
|
+
<tr><td class="table-empty" colspan="3">No projects found.</td></tr>
|
|
64
64
|
</tbody>
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -73,8 +73,8 @@ hidden).
|
|
|
73
73
|
## Badges
|
|
74
74
|
|
|
75
75
|
```html
|
|
76
|
-
<span class="badge badge-success">
|
|
77
|
-
<span class="badge badge-warning">
|
|
76
|
+
<span class="badge badge-success">Active</span>
|
|
77
|
+
<span class="badge badge-warning">Pending</span>
|
|
78
78
|
<span class="badge badge-danger">Failed</span>
|
|
79
79
|
<span class="badge badge-info">Queued</span>
|
|
80
80
|
<span class="badge badge-muted">Draft</span>
|
|
@@ -84,20 +84,85 @@ hidden).
|
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
86
|
<div class="alert alert-success">Saved.</div>
|
|
87
|
-
<div class="alert alert-warning">
|
|
87
|
+
<div class="alert alert-warning">Some changes need review.</div>
|
|
88
88
|
<div class="alert alert-error">Could not load records.</div>
|
|
89
89
|
<div class="alert alert-info">Sync in progress.</div>
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
`.alert-danger` is an alias for `.alert-error`.
|
|
93
93
|
|
|
94
|
+
## Modal / dialog
|
|
95
|
+
|
|
96
|
+
**Use a native `<dialog>` (recommended).** Put `.modal` on the `<dialog>`; the
|
|
97
|
+
`::backdrop` is the scrim (styled for you). Open it with `.showModal()` and the
|
|
98
|
+
browser traps focus, adds Esc-to-close, and inerts the rest of the page — the
|
|
99
|
+
things a modal must do that CSS alone can't. This works fine in server-rendered
|
|
100
|
+
apps: the server emits the markup, and a few lines of vanilla JS wire open/close.
|
|
101
|
+
No `aria-modal` needed — `.showModal()` conveys modality to assistive tech.
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<button class="btn btn-primary" type="button" data-open-dialog="new-project">
|
|
105
|
+
New project
|
|
106
|
+
</button>
|
|
107
|
+
|
|
108
|
+
<dialog id="new-project" class="modal" aria-labelledby="new-project-title">
|
|
109
|
+
<div class="modal-header">
|
|
110
|
+
<h2 id="new-project-title" class="modal-title">Add new project</h2>
|
|
111
|
+
<button class="modal-close" type="button" data-close-dialog aria-label="Close">×</button>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="modal-body">
|
|
114
|
+
<!-- form-group / content -->
|
|
115
|
+
</div>
|
|
116
|
+
<div class="modal-footer">
|
|
117
|
+
<button class="btn btn-outline" type="button" data-close-dialog>Cancel</button>
|
|
118
|
+
<button class="btn btn-primary" type="button">Create project</button>
|
|
119
|
+
</div>
|
|
120
|
+
</dialog>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!-- The whole script. Delegates, so it covers every dialog on the page. -->
|
|
125
|
+
<script>
|
|
126
|
+
document.querySelectorAll('[data-open-dialog]').forEach((b) =>
|
|
127
|
+
b.addEventListener('click', () => document.getElementById(b.dataset.openDialog)?.showModal()));
|
|
128
|
+
document.querySelectorAll('[data-close-dialog]').forEach((b) =>
|
|
129
|
+
b.addEventListener('click', () => b.closest('dialog')?.close()));
|
|
130
|
+
</script>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**No-JS fallback.** If you truly can't run any JS, put the same `.modal` panel
|
|
134
|
+
inside a `.modal-overlay` scrim and toggle the overlay: the `hidden` attribute
|
|
135
|
+
(`.modal-overlay[hidden]` is styled out for you), a conditional server render, or a
|
|
136
|
+
`:target` anchor. This does **not** trap focus, so use `role="dialog"` +
|
|
137
|
+
`aria-labelledby` but **omit** `aria-modal` (claiming it would mislead assistive
|
|
138
|
+
tech). For a middle ground, mark the background content `inert` while it's open —
|
|
139
|
+
that removes it from the tab order and a11y tree without a full focus-trap script.
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<div class="modal-overlay" hidden>
|
|
143
|
+
<div class="modal" role="dialog" aria-labelledby="prj-title">
|
|
144
|
+
<div class="modal-header">
|
|
145
|
+
<h2 id="prj-title" class="modal-title">Add new project</h2>
|
|
146
|
+
<button class="modal-close" type="button" aria-label="Close">×</button>
|
|
147
|
+
</div>
|
|
148
|
+
<div class="modal-body"><!-- content --></div>
|
|
149
|
+
<div class="modal-footer">
|
|
150
|
+
<button class="btn btn-outline" type="button">Cancel</button>
|
|
151
|
+
<button class="btn btn-primary" type="button">Create project</button>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`.modal-close` works on a `<button>` or an `<a>`.
|
|
158
|
+
|
|
94
159
|
## Forms
|
|
95
160
|
|
|
96
161
|
```html
|
|
97
162
|
<div class="form-group">
|
|
98
|
-
<label for="name">
|
|
99
|
-
<input id="name" class="form-control" type="text" placeholder="
|
|
100
|
-
<p class="form-hint">
|
|
163
|
+
<label for="name">Name</label>
|
|
164
|
+
<input id="name" class="form-control" type="text" placeholder="e.g. Marketing Website" />
|
|
165
|
+
<p class="form-hint">Shown to other users.</p>
|
|
101
166
|
</div>
|
|
102
167
|
|
|
103
168
|
<div class="form-group">
|
|
@@ -127,11 +192,11 @@ and textarea mono font are handled for you.
|
|
|
127
192
|
```html
|
|
128
193
|
<div class="app-shell">
|
|
129
194
|
<aside class="sidebar">
|
|
130
|
-
<div class="sidebar-brand">
|
|
195
|
+
<div class="sidebar-brand">Admin Console</div>
|
|
131
196
|
<nav>
|
|
132
197
|
<ul class="sidebar-nav">
|
|
133
198
|
<li class="nav-section">Data</li>
|
|
134
|
-
<li><a href="/
|
|
199
|
+
<li><a href="/projects" class="active">Projects</a></li>
|
|
135
200
|
</ul>
|
|
136
201
|
</nav>
|
|
137
202
|
<div class="sidebar-footer">Signed in as you</div>
|
|
@@ -139,8 +204,8 @@ and textarea mono font are handled for you.
|
|
|
139
204
|
|
|
140
205
|
<main class="main-content">
|
|
141
206
|
<header class="content-header">
|
|
142
|
-
<h1>
|
|
143
|
-
<p class="subtitle">All
|
|
207
|
+
<h1>Projects</h1>
|
|
208
|
+
<p class="subtitle">All projects across the workspace.</p>
|
|
144
209
|
</header>
|
|
145
210
|
<!-- page content -->
|
|
146
211
|
</main>
|
|
@@ -151,8 +216,8 @@ and textarea mono font are handled for you.
|
|
|
151
216
|
|
|
152
217
|
```html
|
|
153
218
|
<div class="toolbar">
|
|
154
|
-
<h2 class="text-base font-semibold text-ink">
|
|
155
|
-
<button class="btn btn-primary btn-sm">Add
|
|
219
|
+
<h2 class="text-base font-semibold text-ink">Projects</h2>
|
|
220
|
+
<button class="btn btn-primary btn-sm">Add project</button>
|
|
156
221
|
</div>
|
|
157
222
|
|
|
158
223
|
<div class="pagination">
|
|
@@ -10,36 +10,36 @@ The most common internal-tool screen. Search toolbar, sticky-header table, pager
|
|
|
10
10
|
```html
|
|
11
11
|
<div class="app-shell">
|
|
12
12
|
<aside class="sidebar">
|
|
13
|
-
<div class="sidebar-brand">
|
|
13
|
+
<div class="sidebar-brand">Admin Console</div>
|
|
14
14
|
<nav>
|
|
15
15
|
<ul class="sidebar-nav">
|
|
16
16
|
<li class="nav-section">Data</li>
|
|
17
|
-
<li><a href="/
|
|
17
|
+
<li><a href="/projects" class="active">Projects</a></li>
|
|
18
18
|
</ul>
|
|
19
19
|
</nav>
|
|
20
20
|
</aside>
|
|
21
21
|
|
|
22
22
|
<main class="main-content">
|
|
23
23
|
<header class="content-header">
|
|
24
|
-
<h1>
|
|
25
|
-
<p class="subtitle">All
|
|
24
|
+
<h1>Projects</h1>
|
|
25
|
+
<p class="subtitle">All projects across the workspace.</p>
|
|
26
26
|
</header>
|
|
27
27
|
|
|
28
28
|
<div class="toolbar">
|
|
29
29
|
<form method="get" role="search" class="grow">
|
|
30
|
-
<input class="form-control max-w-md" type="search" name="q" placeholder="Search
|
|
30
|
+
<input class="form-control max-w-md" type="search" name="q" placeholder="Search projects…" />
|
|
31
31
|
</form>
|
|
32
|
-
<button class="btn btn-primary btn-sm">Add
|
|
32
|
+
<button class="btn btn-primary btn-sm">Add project</button>
|
|
33
33
|
</div>
|
|
34
34
|
|
|
35
35
|
<div class="table-container table-sticky max-h-[60vh]">
|
|
36
36
|
<table>
|
|
37
37
|
<thead>
|
|
38
|
-
<tr><th>
|
|
38
|
+
<tr><th>Project</th><th>Status</th><th>Tasks</th></tr>
|
|
39
39
|
</thead>
|
|
40
40
|
<tbody>
|
|
41
41
|
<!-- rows; use .row-clickable + .row-anchor when rows navigate -->
|
|
42
|
-
<tr><td class="table-empty" colspan="3">No
|
|
42
|
+
<tr><td class="table-empty" colspan="3">No projects found.</td></tr>
|
|
43
43
|
</tbody>
|
|
44
44
|
</table>
|
|
45
45
|
</div>
|
|
@@ -57,7 +57,7 @@ The most common internal-tool screen. Search toolbar, sticky-header table, pager
|
|
|
57
57
|
```html
|
|
58
58
|
<main class="main-content">
|
|
59
59
|
<header class="content-header">
|
|
60
|
-
<h1>Edit
|
|
60
|
+
<h1>Edit project</h1>
|
|
61
61
|
</header>
|
|
62
62
|
|
|
63
63
|
<form>
|
|
@@ -72,7 +72,7 @@ The most common internal-tool screen. Search toolbar, sticky-header table, pager
|
|
|
72
72
|
|
|
73
73
|
<div class="form-actions">
|
|
74
74
|
<button class="btn btn-primary" type="submit">Save</button>
|
|
75
|
-
<a class="btn btn-outline" href="/
|
|
75
|
+
<a class="btn btn-outline" href="/projects">Cancel</a>
|
|
76
76
|
</div>
|
|
77
77
|
</section>
|
|
78
78
|
</form>
|
|
@@ -84,8 +84,8 @@ The most common internal-tool screen. Search toolbar, sticky-header table, pager
|
|
|
84
84
|
```html
|
|
85
85
|
<main class="main-content">
|
|
86
86
|
<header class="content-header">
|
|
87
|
-
<h1>
|
|
88
|
-
<p class="subtitle">
|
|
87
|
+
<h1>Marketing Website</h1>
|
|
88
|
+
<p class="subtitle">Project · 1,204 tasks</p>
|
|
89
89
|
</header>
|
|
90
90
|
|
|
91
91
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
|
package/src/theme.css
CHANGED
|
@@ -62,13 +62,18 @@
|
|
|
62
62
|
--danger-bg: var(--color-red-100); --danger-text: var(--color-red-700);
|
|
63
63
|
--info-bg: var(--color-blue-100); --info-text: var(--color-blue-600);
|
|
64
64
|
|
|
65
|
+
/* Overlay scrim behind modals/dialogs (slate-900 @ 50%, matching the
|
|
66
|
+
rgb(15 23 42 / …) convention below; no 1:1 palette match, so literal) */
|
|
67
|
+
--overlay: rgb(15 23 42 / 0.5);
|
|
68
|
+
|
|
65
69
|
/* Radius (matches Tailwind v4 defaults; redeclared so component CSS resolves) */
|
|
66
70
|
--radius-sm: 4px;
|
|
67
71
|
--radius-md: 6px;
|
|
68
72
|
--radius-lg: 8px;
|
|
69
73
|
|
|
70
|
-
/* Elevation (custom
|
|
74
|
+
/* Elevation (custom names so Tailwind's own shadow-sm/md stay untouched) */
|
|
71
75
|
--shadow-card: 0 1px 3px rgb(15 23 42 / 0.06), 0 0 0 1px rgb(15 23 42 / 0.03);
|
|
76
|
+
--shadow-overlay: 0 20px 25px -5px rgb(15 23 42 / 0.15), 0 8px 10px -6px rgb(15 23 42 / 0.12);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
/* Typography — override Tailwind's default font stacks. */
|