ply-css 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +17 -0
- package/PLY.md +36 -0
- package/README.md +49 -1
- package/bin/ply-purge.js +172 -0
- package/dist/css/ply-core.css +29 -47
- package/dist/css/ply-core.min.css +1 -1
- package/dist/css/ply-essentials.min.css +1 -1
- package/dist/css/ply-helpers.min.css +1 -1
- package/dist/css/ply.css +34 -52
- package/dist/css/ply.min.css +1 -1
- package/dist/css/ply.purged.min.css +1 -0
- package/dist/css/styles.css +34 -52
- package/dist/css/styles.min.css +1 -1
- package/llms-full.txt +37 -5
- package/llms.txt +1 -1
- package/package.json +18 -1
- package/ply-classes.json +18 -9
- package/purge.js +81 -0
- package/safelist.js +43 -0
- package/snippets/custom-theme.html +3 -3
- package/snippets/starter-page.html +2 -2
- package/src/scss/components/_colors.scss +22 -35
- package/src/scss/components/_forms.scss +5 -6
- package/src/scss/components/_helpers-core.scss +3 -3
- package/src/scss/components/_multi-step-form.scss +5 -5
- package/src/scss/components/_tables.scss +2 -1
package/CLAUDE.md
CHANGED
|
@@ -167,6 +167,20 @@ For quick demos — gives you ply's classes and dark mode, but no Sass variables
|
|
|
167
167
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ply-css@1/dist/css/ply.min.css">
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
+
## Tree-Shaking
|
|
171
|
+
|
|
172
|
+
For production builds, purge unused ply classes with the built-in `ply-purge` CLI or PostCSS plugin. Typical result: ~5KB gzipped per page.
|
|
173
|
+
|
|
174
|
+
- **PostCSS plugin**: `require('ply-css/purge')` — recommended for build pipelines
|
|
175
|
+
- **CLI**: `npx ply-purge --css <file> --content '<glob>' -o <output>`
|
|
176
|
+
- Auto-safelists dynamically-toggled classes (`active`, `sort-asc`, responsive grid variants)
|
|
177
|
+
|
|
178
|
+
See PLY.md "Tree-Shaking" section for full usage examples.
|
|
179
|
+
|
|
180
|
+
## Semantic Color Tokens
|
|
181
|
+
|
|
182
|
+
Use `--ply-color-error` and `--ply-color-success` for error/success states instead of hardcoding red/green. These tokens are used by `.input-error`, `.input-success`, `.error`, `.success`, `.required`, and multi-step form states. They're themeable via custom `data-theme` overrides.
|
|
183
|
+
|
|
170
184
|
## File Structure
|
|
171
185
|
|
|
172
186
|
- `src/scss/` — SCSS source (modern `@use`/`@forward` modules). **Use this when the project has a build step.**
|
|
@@ -174,6 +188,9 @@ For quick demos — gives you ply's classes and dark mode, but no Sass variables
|
|
|
174
188
|
- `components/_variables.scss` — Spacing, font sizes, breakpoints, border radius
|
|
175
189
|
- `components/_mixins.scss` — Button generator, clearfix, gradients, arrows, animations
|
|
176
190
|
- `dist/css/` — Compiled CSS bundles (for CDN or direct linking)
|
|
191
|
+
- `bin/ply-purge.js` — Standalone CLI for tree-shaking unused CSS
|
|
192
|
+
- `purge.js` — PostCSS plugin for tree-shaking in build pipelines
|
|
193
|
+
- `safelist.js` — Shared safelist for dynamically-toggled classes
|
|
177
194
|
- `PLY.md` — Complete AI instruction file with class reference
|
|
178
195
|
- `ply-classes.json` — Machine-readable class reference
|
|
179
196
|
- `snippets/` — Copy-paste HTML examples
|
package/PLY.md
CHANGED
|
@@ -729,3 +729,39 @@ Ready-to-use HTML examples are in the `snippets/` directory:
|
|
|
729
729
|
| `ply-core.min.css` | Grid, buttons, forms, nav, alerts, tables, typography, essential helpers | ~17KB |
|
|
730
730
|
| `ply-essentials.min.css` | Grid, helpers, alignments, blocks only | ~7KB |
|
|
731
731
|
| `ply-helpers.min.css` | Helper utilities only | ~5KB |
|
|
732
|
+
|
|
733
|
+
## Tree-Shaking (Purge Unused CSS)
|
|
734
|
+
|
|
735
|
+
For production builds, purge unused ply classes to get bundle sizes comparable
|
|
736
|
+
to Tailwind's JIT output (~5KB gzipped for a typical page).
|
|
737
|
+
|
|
738
|
+
### PostCSS Plugin (recommended for build pipelines)
|
|
739
|
+
|
|
740
|
+
```sh
|
|
741
|
+
npm install -D @fullhuman/postcss-purgecss
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
```js
|
|
745
|
+
// postcss.config.js
|
|
746
|
+
const plyPurge = require('ply-css/purge');
|
|
747
|
+
|
|
748
|
+
module.exports = {
|
|
749
|
+
plugins: [
|
|
750
|
+
plyPurge({ content: ['./src/**/*.{html,jsx,tsx,vue}'] }),
|
|
751
|
+
],
|
|
752
|
+
};
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### CLI (standalone or CI)
|
|
756
|
+
|
|
757
|
+
```sh
|
|
758
|
+
npm install -D purgecss
|
|
759
|
+
npx ply-purge --css node_modules/ply-css/dist/css/ply.min.css \
|
|
760
|
+
--content 'src/**/*.{html,jsx,tsx}' \
|
|
761
|
+
-o public/ply.css
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
The purge tool auto-safelists dynamically-toggled classes (`active`,
|
|
765
|
+
`sort-asc`, responsive grid variants) so they aren't incorrectly removed.
|
|
766
|
+
Extend the safelist with `--safelist <class>` (CLI) or `safelist` option
|
|
767
|
+
(PostCSS plugin).
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ CSS frameworks were designed for humans reading documentation. But increasingly,
|
|
|
37
37
|
- **Start semantic** — ply automatically styles `<nav>`, `<table>`, `<code>`, `<blockquote>`, `<details>`, `<dialog>`, and more. Start with what HTML gives you, then reach for classes when you need them.
|
|
38
38
|
- **AI-native** — ships with `PLY.md` (AI instruction file) and `ply-classes.json` (machine-readable class reference). Class names are predictable: `.alert-blue`, `.btn-sm`, `.unit-50`.
|
|
39
39
|
- **Accessible by default** — `:focus-visible` outlines on all interactive elements (including `<summary>` and legacy components), `prefers-reduced-motion`, `prefers-color-scheme` dark mode, semantic HTML styling, WCAG AA contrast in both light and dark themes. Published [VPAT 2.5](https://plycss.com/docs/vpat) documenting conformance against all WCAG 2.1 Level A and AA criteria.
|
|
40
|
-
- **Small footprint** — ~21KB gzipped (full), ~17KB (core). No JavaScript runtime, no build step
|
|
40
|
+
- **Small footprint** — ~21KB gzipped (full), ~17KB (core), ~5KB with tree-shaking. No JavaScript runtime, no build step required.
|
|
41
41
|
- **Ratio-based grid** — think in percentages, not arbitrary columns. `unit-50` is 50%, `unit-33` is 33%. Responsive prefixes: `tablet-unit-*`, `phone-unit-*`.
|
|
42
42
|
- **Custom theming** — override `--ply-*` CSS custom properties to create any theme. Light and dark modes built in.
|
|
43
43
|
|
|
@@ -132,6 +132,54 @@ For AI agents (Claude, Cursor, Copilot, Replit AI):
|
|
|
132
132
|
|
|
133
133
|
ply is standalone — it should not be used alongside Tailwind, Bootstrap, or other CSS frameworks.
|
|
134
134
|
|
|
135
|
+
## Tree-Shaking (Purge Unused CSS)
|
|
136
|
+
|
|
137
|
+
ply ships all 457 classes in every bundle. For production, you can purge unused
|
|
138
|
+
classes to get Tailwind-level bundle sizes (~5KB gzipped for a typical page).
|
|
139
|
+
|
|
140
|
+
### PostCSS Plugin
|
|
141
|
+
|
|
142
|
+
The recommended approach for projects with an existing PostCSS pipeline:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
npm install -D @fullhuman/postcss-purgecss
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
// postcss.config.js
|
|
150
|
+
const plyPurge = require('ply-css/purge');
|
|
151
|
+
|
|
152
|
+
module.exports = {
|
|
153
|
+
plugins: [
|
|
154
|
+
plyPurge({ content: ['./src/**/*.{html,jsx,tsx,vue}'] }),
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### CLI
|
|
160
|
+
|
|
161
|
+
For standalone use or CI pipelines:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
npm install -D purgecss
|
|
165
|
+
npx ply-purge --css node_modules/ply-css/dist/css/ply.min.css \
|
|
166
|
+
--content 'src/**/*.{html,jsx,tsx}' \
|
|
167
|
+
-o public/ply.css
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Results
|
|
171
|
+
|
|
172
|
+
| Scenario | Before | After (gzipped) | Reduction |
|
|
173
|
+
|----------|--------|-----------------|-----------|
|
|
174
|
+
| Single page (card) | 21 KB | ~5 KB | ~75% |
|
|
175
|
+
| All snippets (13 pages) | 21 KB | ~11 KB | ~48% |
|
|
176
|
+
| Real-world app page | 21 KB | ~5.5 KB | ~74% |
|
|
177
|
+
|
|
178
|
+
The purge tool auto-safelists dynamically-toggled classes (`active`,
|
|
179
|
+
`sort-asc`, etc.) and responsive grid variants so they aren't incorrectly
|
|
180
|
+
removed. Pass additional safelisted classes with `--safelist` (CLI) or the
|
|
181
|
+
`safelist` option (PostCSS).
|
|
182
|
+
|
|
135
183
|
## Development
|
|
136
184
|
|
|
137
185
|
```sh
|
package/bin/ply-purge.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ply-purge — Standalone CLI to tree-shake unused ply CSS.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx ply-purge --css dist/css/ply.min.css --content 'src/**\/*.html' -o dist/css/ply.purged.css
|
|
8
|
+
* npx ply-purge --css node_modules/ply-css/dist/css/ply.min.css --content 'app/**\/*.tsx' --content 'components/**\/*.tsx'
|
|
9
|
+
*
|
|
10
|
+
* Options:
|
|
11
|
+
* --css <file> Input CSS file (required)
|
|
12
|
+
* --content <glob> Content glob to scan for used classes (repeatable, required)
|
|
13
|
+
* -o, --output <file> Output file (defaults to <input>.purged.css)
|
|
14
|
+
* --safelist <class> Additional class names to keep (repeatable)
|
|
15
|
+
* --json Print stats as JSON instead of human-readable
|
|
16
|
+
* -h, --help Show help
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
const fs = require("fs");
|
|
22
|
+
const path = require("path");
|
|
23
|
+
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
|
|
26
|
+
if (args.includes("-h") || args.includes("--help") || args.length === 0) {
|
|
27
|
+
console.log(`
|
|
28
|
+
ply-purge — Tree-shake unused ply CSS
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
ply-purge --css <file> --content <glob> [-o <output>]
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
--css <file> Input CSS file to purge
|
|
35
|
+
--content <glob> Glob pattern for content files (repeatable)
|
|
36
|
+
-o, --output <file> Output file (default: <name>.purged.css)
|
|
37
|
+
--safelist <class> Extra class to preserve (repeatable)
|
|
38
|
+
--json Output stats as JSON
|
|
39
|
+
-h, --help Show this help
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
ply-purge --css node_modules/ply-css/dist/css/ply.min.css \\
|
|
43
|
+
--content 'src/**/*.{html,jsx,tsx}' \\
|
|
44
|
+
-o public/ply.css
|
|
45
|
+
|
|
46
|
+
ply-purge --css dist/css/ply.min.css \\
|
|
47
|
+
--content 'app/**/*.tsx' --content 'components/**/*.tsx'
|
|
48
|
+
`.trim());
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function parseArgs(argv) {
|
|
53
|
+
const result = { content: [], safelist: [], json: false };
|
|
54
|
+
let i = 0;
|
|
55
|
+
while (i < argv.length) {
|
|
56
|
+
const arg = argv[i];
|
|
57
|
+
if (arg === "--css" && argv[i + 1]) {
|
|
58
|
+
result.css = argv[++i];
|
|
59
|
+
} else if (arg === "--content" && argv[i + 1]) {
|
|
60
|
+
result.content.push(argv[++i]);
|
|
61
|
+
} else if ((arg === "-o" || arg === "--output") && argv[i + 1]) {
|
|
62
|
+
result.output = argv[++i];
|
|
63
|
+
} else if (arg === "--safelist" && argv[i + 1]) {
|
|
64
|
+
result.safelist.push(argv[++i]);
|
|
65
|
+
} else if (arg === "--json") {
|
|
66
|
+
result.json = true;
|
|
67
|
+
}
|
|
68
|
+
i++;
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function main() {
|
|
74
|
+
const opts = parseArgs(args);
|
|
75
|
+
|
|
76
|
+
if (!opts.css) {
|
|
77
|
+
console.error("Error: --css is required");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
if (opts.content.length === 0) {
|
|
81
|
+
console.error("Error: at least one --content glob is required");
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let PurgeCSS;
|
|
86
|
+
try {
|
|
87
|
+
PurgeCSS = require("purgecss").PurgeCSS;
|
|
88
|
+
} catch {
|
|
89
|
+
console.error(
|
|
90
|
+
"ply-purge requires purgecss.\n" +
|
|
91
|
+
"Install it: npm install -D purgecss"
|
|
92
|
+
);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const { safelistClasses, safelistPatterns } = require("../safelist");
|
|
97
|
+
|
|
98
|
+
const cssPath = path.resolve(opts.css);
|
|
99
|
+
if (!fs.existsSync(cssPath)) {
|
|
100
|
+
console.error(`Error: CSS file not found: ${cssPath}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const rawCss = fs.readFileSync(cssPath, "utf8");
|
|
105
|
+
const originalSize = Buffer.byteLength(rawCss, "utf8");
|
|
106
|
+
|
|
107
|
+
const purger = new PurgeCSS();
|
|
108
|
+
const results = await purger.purge({
|
|
109
|
+
content: opts.content,
|
|
110
|
+
css: [{ raw: rawCss }],
|
|
111
|
+
safelist: {
|
|
112
|
+
standard: [...safelistClasses, ...opts.safelist],
|
|
113
|
+
deep: safelistPatterns,
|
|
114
|
+
greedy: [/^:root$/, /^html$/, /^body$/],
|
|
115
|
+
},
|
|
116
|
+
defaultExtractor: (content) => {
|
|
117
|
+
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];
|
|
118
|
+
const innerMatches = content.match(/[^<>"'`\s.(){}[\]#,;]+/g) || [];
|
|
119
|
+
return [...new Set([...broadMatches, ...innerMatches])];
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (results.length === 0) {
|
|
124
|
+
console.error("Error: PurgeCSS returned no results");
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const purgedCss = results[0].css;
|
|
129
|
+
const purgedSize = Buffer.byteLength(purgedCss, "utf8");
|
|
130
|
+
|
|
131
|
+
const outputPath = opts.output
|
|
132
|
+
? path.resolve(opts.output)
|
|
133
|
+
: cssPath.replace(/(\.\w+)$/, ".purged$1");
|
|
134
|
+
|
|
135
|
+
const outputDir = path.dirname(outputPath);
|
|
136
|
+
if (!fs.existsSync(outputDir)) {
|
|
137
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fs.writeFileSync(outputPath, purgedCss, "utf8");
|
|
141
|
+
|
|
142
|
+
const reduction = (((originalSize - purgedSize) / originalSize) * 100).toFixed(1);
|
|
143
|
+
|
|
144
|
+
if (opts.json) {
|
|
145
|
+
console.log(
|
|
146
|
+
JSON.stringify({
|
|
147
|
+
input: opts.css,
|
|
148
|
+
output: path.relative(process.cwd(), outputPath),
|
|
149
|
+
originalBytes: originalSize,
|
|
150
|
+
purgedBytes: purgedSize,
|
|
151
|
+
reductionPercent: parseFloat(reduction),
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
} else {
|
|
155
|
+
console.log(`ply-purge complete`);
|
|
156
|
+
console.log(` Input: ${opts.css} (${formatBytes(originalSize)})`);
|
|
157
|
+
console.log(
|
|
158
|
+
` Output: ${path.relative(process.cwd(), outputPath)} (${formatBytes(purgedSize)})`
|
|
159
|
+
);
|
|
160
|
+
console.log(` Reduction: ${reduction}% removed`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function formatBytes(bytes) {
|
|
165
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
166
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
main().catch((err) => {
|
|
170
|
+
console.error(err.message || err);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
package/dist/css/ply-core.css
CHANGED
|
@@ -25,13 +25,16 @@
|
|
|
25
25
|
--ply-color-link-hover: #0347c6;
|
|
26
26
|
--ply-color-link-hover: color-mix(in oklch, var(--ply-btn-default-bg), black 15%);
|
|
27
27
|
--ply-color-focus: #0f62fe;
|
|
28
|
-
--ply-color-field-bg:
|
|
29
|
-
--ply-color-input-border:
|
|
30
|
-
--ply-color-input-bg:
|
|
31
|
-
--ply-color-
|
|
32
|
-
--ply-color-
|
|
33
|
-
--ply-color-
|
|
34
|
-
--ply-color-
|
|
28
|
+
--ply-color-field-bg: var(--ply-bg-surface-alt);
|
|
29
|
+
--ply-color-input-border: var(--ply-border-strong);
|
|
30
|
+
--ply-color-input-bg: var(--ply-bg-surface-alt);
|
|
31
|
+
--ply-color-error: var(--ply-red-1);
|
|
32
|
+
--ply-color-success: var(--ply-green-1);
|
|
33
|
+
--ply-color-code-bg: var(--ply-bg-surface-alt);
|
|
34
|
+
--ply-color-code-border: var(--ply-border-color);
|
|
35
|
+
--ply-color-table-border: var(--ply-border-color);
|
|
36
|
+
--ply-color-table-striped: #f4f4f4;
|
|
37
|
+
--ply-color-table-stripped: var(--ply-color-table-striped);
|
|
35
38
|
--ply-color-table-hovered: #e8e8e8;
|
|
36
39
|
--ply-color-accent: #0353e9;
|
|
37
40
|
--ply-btn-default-bg: #0353e9;
|
|
@@ -46,14 +49,14 @@
|
|
|
46
49
|
--ply-btn-secondary-bg-active: color-mix(in oklch, var(--ply-btn-secondary-bg), black 25%);
|
|
47
50
|
--ply-border-radius: 0.25rem;
|
|
48
51
|
--ply-btn-border-radius: 2rem;
|
|
49
|
-
--ply-nav-bg:
|
|
50
|
-
--ply-nav-color:
|
|
51
|
-
--ply-nav-border:
|
|
52
|
+
--ply-nav-bg: var(--ply-bg-body);
|
|
53
|
+
--ply-nav-color: var(--ply-color-body);
|
|
54
|
+
--ply-nav-border: var(--ply-color-body);
|
|
52
55
|
--ply-nav-hover: #e8e8e8;
|
|
53
56
|
--ply-nav-active-color: #525252;
|
|
54
|
-
--ply-layer-0:
|
|
55
|
-
--ply-layer-1:
|
|
56
|
-
--ply-layer-2:
|
|
57
|
+
--ply-layer-0: var(--ply-bg-body);
|
|
58
|
+
--ply-layer-1: var(--ply-bg-surface-alt);
|
|
59
|
+
--ply-layer-2: var(--ply-bg-muted);
|
|
57
60
|
--ply-layer-3: #c6c6c6;
|
|
58
61
|
--ply-shadow-1: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
59
62
|
--ply-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
@@ -150,13 +153,8 @@
|
|
|
150
153
|
--ply-color-link-hover: #619bff;
|
|
151
154
|
--ply-color-link-hover: color-mix(in oklch, #4589ff, white 15%);
|
|
152
155
|
--ply-color-focus: #0f62fe;
|
|
153
|
-
--ply-color-
|
|
154
|
-
--ply-color-
|
|
155
|
-
--ply-color-input-bg: #262626;
|
|
156
|
-
--ply-color-code-bg: #262626;
|
|
157
|
-
--ply-color-code-border: #393939;
|
|
158
|
-
--ply-color-table-border: #393939;
|
|
159
|
-
--ply-color-table-stripped: #1c1c1c;
|
|
156
|
+
--ply-color-table-striped: #1c1c1c;
|
|
157
|
+
--ply-color-table-stripped: var(--ply-color-table-striped);
|
|
160
158
|
--ply-color-table-hovered: #353535;
|
|
161
159
|
--ply-color-accent: #4589ff;
|
|
162
160
|
--ply-btn-default-bg: #0f62fe;
|
|
@@ -172,14 +170,8 @@
|
|
|
172
170
|
--ply-btn-default-color: #fff;
|
|
173
171
|
--ply-btn-secondary-color: #161616;
|
|
174
172
|
--ply-btn-ghost-color: #4589ff;
|
|
175
|
-
--ply-nav-bg: #161616;
|
|
176
|
-
--ply-nav-color: #f4f4f4;
|
|
177
|
-
--ply-nav-border: #f4f4f4;
|
|
178
173
|
--ply-nav-hover: #353535;
|
|
179
174
|
--ply-nav-active-color: #a8a8a8;
|
|
180
|
-
--ply-layer-0: #161616;
|
|
181
|
-
--ply-layer-1: #262626;
|
|
182
|
-
--ply-layer-2: #393939;
|
|
183
175
|
--ply-layer-3: #525252;
|
|
184
176
|
--ply-shadow-1: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
185
177
|
--ply-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
@@ -266,13 +258,8 @@
|
|
|
266
258
|
--ply-color-link-hover: #619bff;
|
|
267
259
|
--ply-color-link-hover: color-mix(in oklch, #4589ff, white 15%);
|
|
268
260
|
--ply-color-focus: #0f62fe;
|
|
269
|
-
--ply-color-
|
|
270
|
-
--ply-color-
|
|
271
|
-
--ply-color-input-bg: #262626;
|
|
272
|
-
--ply-color-code-bg: #262626;
|
|
273
|
-
--ply-color-code-border: #393939;
|
|
274
|
-
--ply-color-table-border: #393939;
|
|
275
|
-
--ply-color-table-stripped: #1c1c1c;
|
|
261
|
+
--ply-color-table-striped: #1c1c1c;
|
|
262
|
+
--ply-color-table-stripped: var(--ply-color-table-striped);
|
|
276
263
|
--ply-color-table-hovered: #353535;
|
|
277
264
|
--ply-color-accent: #4589ff;
|
|
278
265
|
--ply-btn-default-bg: #0f62fe;
|
|
@@ -288,14 +275,8 @@
|
|
|
288
275
|
--ply-btn-default-color: #fff;
|
|
289
276
|
--ply-btn-secondary-color: #161616;
|
|
290
277
|
--ply-btn-ghost-color: #4589ff;
|
|
291
|
-
--ply-nav-bg: #161616;
|
|
292
|
-
--ply-nav-color: #f4f4f4;
|
|
293
|
-
--ply-nav-border: #f4f4f4;
|
|
294
278
|
--ply-nav-hover: #353535;
|
|
295
279
|
--ply-nav-active-color: #a8a8a8;
|
|
296
|
-
--ply-layer-0: #161616;
|
|
297
|
-
--ply-layer-1: #262626;
|
|
298
|
-
--ply-layer-2: #393939;
|
|
299
280
|
--ply-layer-3: #525252;
|
|
300
281
|
--ply-shadow-1: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
301
282
|
--ply-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
@@ -1234,15 +1215,15 @@ meter {
|
|
|
1234
1215
|
.req,
|
|
1235
1216
|
.required {
|
|
1236
1217
|
font-weight: normal;
|
|
1237
|
-
color: var(--ply-
|
|
1218
|
+
color: var(--ply-color-error);
|
|
1238
1219
|
}
|
|
1239
1220
|
|
|
1240
1221
|
.error {
|
|
1241
|
-
color: var(--ply-
|
|
1222
|
+
color: var(--ply-color-error);
|
|
1242
1223
|
}
|
|
1243
1224
|
|
|
1244
1225
|
.success {
|
|
1245
|
-
color: var(--ply-
|
|
1226
|
+
color: var(--ply-color-success);
|
|
1246
1227
|
}
|
|
1247
1228
|
|
|
1248
1229
|
.text-xs {
|
|
@@ -2587,8 +2568,9 @@ table.table-stroked th {
|
|
|
2587
2568
|
border-bottom: 1px solid var(--ply-color-table-border, #ccc);
|
|
2588
2569
|
}
|
|
2589
2570
|
|
|
2571
|
+
table.table-striped tbody tr:nth-child(odd) td,
|
|
2590
2572
|
table.table-stripped tbody tr:nth-child(odd) td {
|
|
2591
|
-
background: var(--ply-color-table-stripped, #f8f8f8);
|
|
2573
|
+
background: var(--ply-color-table-striped, var(--ply-color-table-stripped, #f8f8f8));
|
|
2592
2574
|
}
|
|
2593
2575
|
|
|
2594
2576
|
table.table-hovered tbody tr:hover td {
|
|
@@ -3716,16 +3698,16 @@ input.input-error,
|
|
|
3716
3698
|
textarea.input-error,
|
|
3717
3699
|
select.input-error,
|
|
3718
3700
|
.input-error {
|
|
3719
|
-
border-color:
|
|
3720
|
-
box-shadow: 0 0 0 2px
|
|
3701
|
+
border-color: var(--ply-color-error);
|
|
3702
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--ply-color-error) 30%, transparent), 0 1px 2px rgba(0, 0, 0, 0.2) inset;
|
|
3721
3703
|
}
|
|
3722
3704
|
|
|
3723
3705
|
input.input-success,
|
|
3724
3706
|
textarea.input-success,
|
|
3725
3707
|
select.input-success,
|
|
3726
3708
|
.input-success {
|
|
3727
|
-
border-color:
|
|
3728
|
-
box-shadow: 0 0 0 2px
|
|
3709
|
+
border-color: var(--ply-color-success);
|
|
3710
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--ply-color-success) 30%, transparent), 0 1px 2px rgba(0, 0, 0, 0.2) inset;
|
|
3729
3711
|
}
|
|
3730
3712
|
|
|
3731
3713
|
input.input-gray,
|