diff --git a/package-lock.json b/package-lock.json
index 1defc825..ffa85c4b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -325,6 +325,7 @@
"integrity": "sha512-md5ikmdH0rM4jkVFwNQhN++onUUZPUDUfKijnb1XZArQisT9hPiNqTPbO+OZTBK/hQYYV/GfTOhDH30whG32xQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "2.3.0",
"@angular-devkit/architect": "0.2003.15",
@@ -520,6 +521,7 @@
"version": "20.3.16",
"integrity": "sha512-N83/GFY5lKNyWgPV3xHHy2rb3/eP1ZLzSVI+dmMVbf3jbqwY1YPQcMiAG8UDzaILY1Dkus91kWLF8Qdr3nHAzg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -681,6 +683,7 @@
"version": "20.3.16",
"integrity": "sha512-GRAziNlntwdnJy3F+8zCOvDdy7id0gITjDnM6P9+n2lXvtDuBLGJKU3DWBbvxcCjtD6JK/g/rEX5fbCxbUHkQQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -696,6 +699,7 @@
"version": "20.3.16",
"integrity": "sha512-Pt9Ms9GwTThgzdxWBwMfN8cH1JEtQ2DK5dc2yxYtPSaD+WKmG9AVL1PrzIYQEbaKcWk2jxASUHpEWSlNiwo8uw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -708,6 +712,7 @@
"integrity": "sha512-l3xF/fXfJAl/UrNnH9Ufkr79myjMgXdHq1mmmph2UnpeqilRB1b8lC9sLBV9MipQHVn3dwocxMIvtrcryfOaXw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/core": "7.28.3",
"@jridgewell/sourcemap-codec": "^1.4.14",
@@ -739,6 +744,7 @@
"version": "20.3.16",
"integrity": "sha512-KSFPKvOmWWLCJBbEO+CuRUXfecX2FRuO0jNi9c54ptXMOPHlK1lIojUnyXmMNzjdHgRug8ci9qDuftvC2B7MKg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -763,6 +769,7 @@
"version": "20.3.16",
"integrity": "sha512-1yzbXpExTqATpVcqA3wGrq4ACFIP3mRxA4pbso5KoJU+/4JfzNFwLsDaFXKpm5uxwchVnj8KM2vPaDOkvtp7NA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -780,6 +787,7 @@
"version": "20.3.16",
"integrity": "sha512-YsrLS6vyS77i4pVHg4gdSBW74qvzHjpQRTVQ5Lv/OxIjJdYYYkMmjNalCNgy1ZuyY6CaLIB11ccxhrNnxfKGOQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -801,6 +809,7 @@
"version": "20.3.16",
"integrity": "sha512-5mECCV9YeKH6ue239GXRTGeDSd/eTbM1j8dDejhm5cGnPBhTxRw4o+GgSrWTYtb6VmIYdwUGBTC+wCBphiaQ2A==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -818,6 +827,7 @@
"version": "20.3.16",
"integrity": "sha512-LxQscYd3UCWV8H3sdlnM05UB60MZVuVsdsHvXdkJ9+WOQjVDN1l1rYhj2aDL/5KkaRd/nqo0yFRnVjwceXDJhQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0",
"xhr2": "^0.2.0"
@@ -837,6 +847,7 @@
"version": "20.3.16",
"integrity": "sha512-e1LiQFZaajKqc00cY5FboIrWJZSMnZ64GDp5R0UejritYrqorQQQNOqP1W85BMuY2owibMmxVfX+dJg/Mc8PuQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"tslib": "^2.3.0"
},
@@ -878,6 +889,7 @@
"integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
@@ -3537,6 +3549,7 @@
"integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@inquirer/checkbox": "^4.2.1",
"@inquirer/confirm": "^5.1.14",
@@ -4043,6 +4056,7 @@
"integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/core": "^7.11.6",
"@jest/types": "^29.6.3",
@@ -4075,6 +4089,7 @@
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/schemas": "^29.6.3",
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -6906,6 +6921,7 @@
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
"dev": true,
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "7.18.0",
"@typescript-eslint/types": "7.18.0",
@@ -7292,6 +7308,7 @@
"version": "8.15.0",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -7395,6 +7412,7 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -7899,6 +7917,7 @@
"integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/transform": "^29.7.0",
"@types/babel__core": "^7.1.14",
@@ -8368,6 +8387,7 @@
"integrity": "sha512-mcYOIy4BW6sWSEnTSBjQwWsnbx2btZX78ajTTjdNfyC/EqQVcIe0nQR6894RNAMtvlfAnLaH9L2ka97zpvgenA==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"browser-sync-client": "^3.0.4",
"browser-sync-ui": "^3.0.4",
@@ -8589,6 +8609,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -8674,7 +8695,6 @@
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6"
},
@@ -8687,7 +8707,6 @@
"integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"semver": "^7.0.0"
}
@@ -9050,6 +9069,7 @@
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"readdirp": "^4.0.1"
},
@@ -10372,7 +10392,8 @@
"version": "0.0.1551306",
"integrity": "sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "BSD-3-Clause",
+ "peer": true
},
"node_modules/diff": {
"version": "4.0.4",
@@ -10783,6 +10804,7 @@
"integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"ansi-colors": "^4.1.1",
"strip-ansi": "^6.0.1"
@@ -11127,6 +11149,7 @@
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -11182,7 +11205,6 @@
"integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"semver": "^7.5.4"
},
@@ -11198,6 +11220,7 @@
"integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -11319,7 +11342,6 @@
"https://opencollective.com/eslint"
],
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.1.2",
"@eslint-community/regexpp": "^4.11.0",
@@ -11337,6 +11359,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -11455,7 +11478,6 @@
"integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"builtins": "^5.0.1",
@@ -11484,7 +11506,6 @@
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -11495,7 +11516,6 @@
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
- "peer": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -11589,6 +11609,7 @@
"integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==",
"dev": true,
"license": "ISC",
+ "peer": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -12733,7 +12754,6 @@
"integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
@@ -13670,7 +13690,6 @@
"integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"builtin-modules": "^3.3.0"
},
@@ -14274,6 +14293,7 @@
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -14927,6 +14947,7 @@
"integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@jest/types": "^29.6.3",
"@types/node": "*",
@@ -15049,6 +15070,7 @@
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"jiti": "bin/jiti.js"
}
@@ -15090,6 +15112,7 @@
"integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"abab": "^2.0.6",
"acorn": "^8.8.1",
@@ -15391,6 +15414,7 @@
"integrity": "sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"copy-anything": "^2.0.1",
"parse-node-version": "^1.0.1",
@@ -15545,6 +15569,7 @@
"integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"cli-truncate": "^4.0.0",
"colorette": "^2.0.20",
@@ -16576,6 +16601,7 @@
"integrity": "sha512-yW5ME0hqTz38r/th/7zVwX5oSIw1FviSA2PUlGZdVjghDme/KX6iiwmOBmlt9E9whNmwijEC6Gn3KKbrsBx8ig==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.3.0",
"@rollup/plugin-json": "^6.1.0",
@@ -18077,6 +18103,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -18223,6 +18250,7 @@
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -18869,7 +18897,6 @@
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
- "peer": true,
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
@@ -19034,6 +19061,7 @@
"integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -19161,6 +19189,7 @@
"version": "7.8.2",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
@@ -19248,6 +19277,7 @@
"integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^5.0.2",
@@ -20562,6 +20592,7 @@
"integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
"dev": true,
"license": "BSD-2-Clause",
+ "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.14.0",
@@ -21013,7 +21044,8 @@
"node_modules/tslib": {
"version": "2.8.1",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
+ "license": "0BSD",
+ "peer": true
},
"node_modules/tuf-js": {
"version": "4.1.0",
@@ -21559,6 +21591,7 @@
"integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -21714,6 +21747,7 @@
"integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -21791,6 +21825,7 @@
"integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/bonjour": "^3.5.13",
"@types/connect-history-api-fallback": "^1.5.4",
@@ -22553,6 +22588,7 @@
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
"dev": true,
"license": "ISC",
+ "peer": true,
"bin": {
"yaml": "bin.mjs"
},
@@ -22695,6 +22731,7 @@
"integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==",
"dev": true,
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
@@ -22711,7 +22748,8 @@
"node_modules/zone.js": {
"version": "0.15.1",
"integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
}
}
}
diff --git a/projects/composition/src/app/app.component.html b/projects/composition/src/app/app.component.html
index 806ac9db..75e5dfc2 100644
--- a/projects/composition/src/app/app.component.html
+++ b/projects/composition/src/app/app.component.html
@@ -1,11 +1,12 @@
diff --git a/projects/composition/src/app/components/navigation-sidebar/navigation-sidebar.component.scss b/projects/composition/src/app/components/navigation-sidebar/navigation-sidebar.component.scss
index 712d5b3e..21ff31c9 100644
--- a/projects/composition/src/app/components/navigation-sidebar/navigation-sidebar.component.scss
+++ b/projects/composition/src/app/components/navigation-sidebar/navigation-sidebar.component.scss
@@ -1,15 +1,15 @@
@use '../../../variables.scss' as vars;
:host {
- $item-hover-background: var(--cps-color-highlight-hover);
- $item-active-background: var(--cps-color-highlight-active);
- $item-border-color: var(--cps-color-line-light);
+ $item-hover-background: var(--cps-highlight-hover);
+ $item-active-background: var(--cps-highlight-active);
+ $item-border-color: var(--cps-color-line);
border-right: 1px solid $item-border-color;
- background-color: var(--cps-color-bg-light);
+ background-color: var(--cps-surface-body);
.sidebar {
transition: width 0.2s;
- background-color: white;
+ background-color: var(--cps-surface-body);
width: vars.$sidebar-width;
height: calc(100vh - vars.$top-tbar-height - 20px);
overflow: auto;
@@ -17,7 +17,7 @@
&-title {
margin: 0;
padding: 12px 0 12px 12px;
- color: vars.$color-text;
+ color: var(--cps-text-primary);
}
&-item {
border-bottom: 1px solid $item-border-color;
@@ -26,7 +26,7 @@
align-items: center;
padding-left: 30px;
text-decoration: none;
- color: vars.$color-text;
+ color: var(--cps-text-primary);
&:hover {
background: $item-hover-background;
}
diff --git a/projects/composition/src/app/components/theme-toggle/theme-toggle.component.html b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.html
new file mode 100644
index 00000000..38522a73
--- /dev/null
+++ b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.html
@@ -0,0 +1,133 @@
+
+
+ @if (menuOpen) {
+
+
+ }
+
+
diff --git a/projects/composition/src/app/components/theme-toggle/theme-toggle.component.scss b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.scss
new file mode 100644
index 00000000..ba0f26dc
--- /dev/null
+++ b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.scss
@@ -0,0 +1,187 @@
+.theme-controls {
+ --appearance-radius-sm: 8px;
+ --appearance-radius-md: 14px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ position: relative;
+}
+.theme-toggle-btn {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ height: 32px;
+ padding: 0 11px;
+ background: var(--cps-surface-elevated);
+ border: 1px solid var(--cps-border-color);
+ border-radius: var(--appearance-radius-sm);
+ color: var(--cps-text-primary);
+ cursor: pointer;
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 12px;
+ font-weight: 600;
+ transition: all 0.2s;
+ &:hover {
+ background: var(--cps-highlight-hover);
+ border-color: var(--cps-border-focus);
+ }
+ &:active {
+ background: var(--cps-highlight-active);
+ }
+ &:focus-visible {
+ outline: 2px solid var(--cps-ring-color);
+ outline-offset: 2px;
+ }
+}
+.theme-toggle-caret {
+ color: var(--cps-text-muted);
+ font-size: 11px;
+ line-height: 1;
+}
+.menu-backdrop {
+ position: fixed;
+ inset: 0;
+ margin: 0;
+ padding: 0;
+ background: var(--cps-surface-overlay);
+ opacity: 0.22;
+ border: 0;
+ border-radius: 0;
+ appearance: none;
+ -webkit-appearance: none;
+ z-index: 10;
+}
+.theme-menu {
+ position: absolute;
+ top: calc(100% + 10px);
+ right: 0;
+ width: min(320px, calc(100vw - 16px));
+ max-height: min(70vh, 520px);
+ overflow: auto;
+ background: var(--cps-surface-control);
+ border: 1px solid var(--cps-border-color);
+ border-radius: var(--appearance-radius-md);
+ box-shadow: var(--cps-shadow-md);
+ z-index: 20;
+ padding: 6px;
+ transform-origin: top right;
+ animation: menu-enter var(--cps-motion-fast) var(--cps-motion-easing);
+}
+@keyframes menu-enter {
+ from {
+ opacity: 0;
+ transform: translateY(-4px) scale(0.985);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+}
+@media (prefers-reduced-motion: reduce) {
+ .theme-menu {
+ animation: none;
+ }
+}
+.theme-menu-header {
+ padding: 10px 10px 9px;
+ border-bottom: 1px solid var(--cps-border-color);
+}
+.theme-menu-title {
+ color: var(--cps-text-primary);
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 13px;
+ font-weight: 700;
+ line-height: 1.2;
+}
+.theme-menu-subtitle {
+ margin-top: 3px;
+ color: var(--cps-text-muted);
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 11px;
+ line-height: 1.35;
+}
+.theme-section {
+ padding: 10px;
+}
+.theme-section + .theme-section {
+ border-top: 1px solid var(--cps-border-color);
+}
+.theme-section-title {
+ margin: 0 0 6px;
+ color: var(--cps-text-muted);
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+}
+.theme-section-hint {
+ margin: -1px 0 8px;
+ color: var(--cps-text-muted);
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 11px;
+ line-height: 1.35;
+}
+.theme-options {
+ display: flex;
+ flex-direction: column;
+ gap: 3px;
+}
+.theme-option {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 8px;
+ min-height: 32px;
+ padding: 7px 8px;
+ border: 1px solid transparent;
+ border-radius: var(--appearance-radius-sm);
+ background: transparent;
+ color: var(--cps-text-primary);
+ font-family: 'Source Sans Pro', sans-serif;
+ font-size: 12px;
+ line-height: 1;
+ text-align: left;
+ cursor: pointer;
+ &:hover {
+ background: var(--cps-highlight-hover);
+ }
+ &:focus-visible {
+ outline: 2px solid var(--cps-ring-color);
+ outline-offset: 2px;
+ }
+}
+.theme-option.selected {
+ background: var(--cps-highlight-active);
+ border-color: var(--cps-border-focus);
+}
+.theme-option.selected::after {
+ content: '✓';
+ margin-left: auto;
+ color: var(--cps-accent-primary);
+ font-weight: 700;
+ font-size: 12px;
+}
+.option-dot {
+ width: 9px;
+ height: 9px;
+ border-radius: 9999px;
+ background: transparent;
+ border: 1px solid var(--cps-border-color);
+ flex: 0 0 auto;
+}
+.theme-section-theme .theme-option:nth-child(1) .option-dot {
+ background: var(--cps-text-muted);
+}
+.theme-section-theme .theme-option:nth-child(2) .option-dot {
+ background: var(--cps-color-calm);
+}
+.theme-section-theme .theme-option:nth-child(3) .option-dot {
+ background: var(--cps-color-energy);
+}
+.theme-section-theme .theme-option:nth-child(4) .option-dot {
+ background: var(--cps-color-passion);
+}
+.theme-option.selected .option-dot {
+ border-color: transparent;
+}
diff --git a/projects/composition/src/app/components/theme-toggle/theme-toggle.component.ts b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.ts
new file mode 100644
index 00000000..58ab505c
--- /dev/null
+++ b/projects/composition/src/app/components/theme-toggle/theme-toggle.component.ts
@@ -0,0 +1,61 @@
+import {
+ ChangeDetectionStrategy,
+ Component,
+ HostListener,
+ inject
+} from '@angular/core';
+import {
+ CpsBaseTheme,
+ CpsColorTheme,
+ CpsIconComponent,
+ CpsRadiusTheme,
+ CpsThemeService
+} from 'cps-ui-kit';
+
+@Component({
+ selector: 'app-theme-toggle',
+ imports: [CpsIconComponent],
+ templateUrl: './theme-toggle.component.html',
+ styleUrl: './theme-toggle.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class ThemeToggleComponent {
+ private themeService = inject(CpsThemeService);
+
+ isDark = this.themeService.isDark;
+ colorTheme = this.themeService.colorTheme;
+ radiusTheme = this.themeService.radiusTheme;
+ baseTheme = this.themeService.baseTheme;
+ menuOpen = false;
+
+ toggleTheme(): void {
+ this.themeService.toggleTheme();
+ }
+
+ toggleMenu(): void {
+ this.menuOpen = !this.menuOpen;
+ }
+
+ closeMenu(): void {
+ this.menuOpen = false;
+ }
+
+ @HostListener('document:keydown.escape')
+ onEscapeKey(): void {
+ if (this.menuOpen) {
+ this.closeMenu();
+ }
+ }
+
+ setColorTheme(value: CpsColorTheme): void {
+ this.themeService.setColorTheme(value);
+ }
+
+ setRadiusTheme(value: CpsRadiusTheme): void {
+ this.themeService.setRadiusTheme(value);
+ }
+
+ setBaseTheme(value: CpsBaseTheme): void {
+ this.themeService.setBaseTheme(value);
+ }
+}
diff --git a/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.html b/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.html
index ab3bde80..85fa867e 100644
--- a/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.html
+++ b/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.html
@@ -12,7 +12,10 @@
@for (name of filteredIconsList; track name) {
-
+
{{ name }}
}
diff --git a/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.scss b/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.scss
index 4645cb80..6cbd8dca 100644
--- a/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.scss
+++ b/projects/composition/src/app/pages/icons-page/icons-page/icons-page.component.scss
@@ -17,6 +17,6 @@
cursor: pointer;
span {
margin-left: 16px;
- color: vars.$color-calm;
+ color: var(--cps-text-primary);
}
}
diff --git a/projects/composition/src/styles.scss b/projects/composition/src/styles.scss
index 210f2849..97428f8e 100644
--- a/projects/composition/src/styles.scss
+++ b/projects/composition/src/styles.scss
@@ -41,16 +41,20 @@ body {
font-weight: bold;
text-align: left;
padding: 0.75rem 1rem;
- border-bottom: 1px solid var(--cps-color-line-light);
+ background-color: var(--cps-surface-elevated);
+ border-bottom: 1px solid var(--cps-color-line);
}
tr {
transition: background-color 0.5s ease-in;
+ &:hover {
+ background-color: var(--cps-highlight-hover);
+ }
}
td {
padding: 0.75rem 1rem;
- border-bottom: 1px solid var(--cps-color-line-light);
+ border-bottom: 1px solid var(--cps-color-line);
white-space: pre-line;
span {
@@ -61,18 +65,18 @@ body {
&.highlighted-bg {
span {
- color: var(--cps-color-depth-darken4);
- background-color: var(--cps-color-human-lighten5);
+ color: var(--cps-text-on-accent);
+ background-color: var(--cps-accent-primary);
border-radius: 6px;
padding: 0.2rem 0.5rem;
}
}
&.highlighted-text {
- color: var(--cps-color-calm);
+ color: var(--cps-text-primary);
a {
- color: var(--cps-color-calm);
+ color: var(--cps-text-primary);
&:hover {
text-decoration: none;
@@ -92,8 +96,8 @@ body {
Consolas,
Liberation Mono,
monospace;
- background-color: var(--cps-color-bg-mid);
- border: 1px solid var(--cps-color-line-light);
+ background-color: var(--cps-surface-elevated);
+ border: 1px solid var(--cps-color-line);
}
}
}
diff --git a/projects/composition/src/variables.scss b/projects/composition/src/variables.scss
index ca663339..f26fb833 100644
--- a/projects/composition/src/variables.scss
+++ b/projects/composition/src/variables.scss
@@ -1,7 +1,7 @@
$sidebar-width: 300px;
-$composition-background: var(--cps-color-bg-light);
+$composition-background: var(--cps-background-color);
$top-tbar-height: 64px;
$inner-tbar-height: 45px;
-$color-calm: var(--cps-color-calm);
-$color-text: var(--cps-color-text-dark);
+$color-calm: var(--cps-accent-primary);
+$color-text: var(--cps-text-primary);
diff --git a/projects/cps-ui-kit/assets/icons.svg b/projects/cps-ui-kit/assets/icons.svg
index 7ac1852f..0f8d322c 100644
--- a/projects/cps-ui-kit/assets/icons.svg
+++ b/projects/cps-ui-kit/assets/icons.svg
@@ -513,4 +513,10 @@
+
+
+
+
+
+
diff --git a/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.html b/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.html
index 0c028173..e41060ab 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.html
+++ b/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.html
@@ -1,7 +1,7 @@
@@ -129,6 +129,7 @@
#autocompleteInput
class="cps-autocomplete-box-input"
spellcheck="false"
+ [attr.aria-label]="label || placeholder || 'Autocomplete input'"
[placeholder]="
(!multiple && isEmptyValue()) || (value?.length < 1 && multiple)
? placeholder
@@ -283,6 +284,7 @@
spellcheck="false"
[class]="inputClass"
[style]="inputStyle"
+ [attr.aria-label]="label || placeholder || 'Autocomplete input'"
[placeholder]="
(!multiple && isEmptyValue()) || (value?.length < 1 && multiple)
? placeholder
diff --git a/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.scss b/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.scss
index 1199eea0..ce8172b7 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.scss
+++ b/projects/cps-ui-kit/src/lib/components/cps-autocomplete/cps-autocomplete.component.scss
@@ -1,21 +1,21 @@
-$color-calm: var(--cps-color-calm);
-$color-error: var(--cps-color-error);
-$error-background: #fef3f2;
-$autocomplete-placeholder-color: var(--cps-color-text-lightest);
-$autocomplete-label-color: var(--cps-color-text-dark);
-$autocomplete-label-disabled-color: var(--cps-color-text-mild);
-$autocomplete-items-disabled-color: var(--cps-color-text-light);
-$autocomplete-hint-color: var(--cps-color-text-mild);
-$option-hover-background: var(--cps-color-highlight-hover);
-$selected-option-background: var(--cps-color-highlight-selected);
-$option-highlight-background: var(--cps-color-highlight-active);
-$option-highlight-selected-background: var(--cps-color-highlight-selected-dark);
-$autocomplete-option-info-color: var(--cps-color-text-light);
-$autocomplete-option-value-color: var(--cps-color-text-dark);
-$autocomplete-about-remove-color: var(--cps-color-text-light);
-$autocomplete-about-remove-background: var(--cps-color-bg-mid);
-$autocomplete-prefix-icon-color: var(--cps-color-text-dark);
-$autocomplete-border-color: var(--cps-color-line-light);
+$color-calm: var(--cps-accent-primary);
+$color-error: var(--cps-state-error);
+$error-background: var(--cps-error-background);
+$autocomplete-placeholder-color: var(--cps-input-placeholder);
+$autocomplete-label-color: var(--cps-text-primary);
+$autocomplete-label-disabled-color: var(--cps-text-secondary);
+$autocomplete-items-disabled-color: var(--cps-text-disabled);
+$autocomplete-hint-color: var(--cps-text-muted);
+$option-hover-background: var(--cps-highlight-hover);
+$selected-option-background: var(--cps-highlight-selected);
+$option-highlight-background: var(--cps-highlight-active);
+$option-highlight-selected-background: var(--cps-highlight-selected);
+$autocomplete-option-info-color: var(--cps-text-secondary);
+$autocomplete-option-value-color: var(--cps-text-primary);
+$autocomplete-about-remove-color: var(--cps-text-muted);
+$autocomplete-about-remove-background: var(--cps-surface-muted);
+$autocomplete-prefix-icon-color: var(--cps-text-secondary);
+$autocomplete-border-color: var(--cps-border-color);
$hover-transition-duration: 0.2s;
@@ -26,7 +26,7 @@ $hover-transition-duration: 0.2s;
position: relative;
width: 100%;
outline: none;
- font-family: 'Source Sans Pro', sans-serif;
+ font-family: inherit;
font-weight: normal;
display: grid;
@@ -40,7 +40,7 @@ $hover-transition-duration: 0.2s;
&.focused {
.cps-autocomplete-box {
- background: white !important;
+ background: var(--cps-input-background) !important;
}
}
@@ -62,6 +62,7 @@ $hover-transition-duration: 0.2s;
&.active {
.cps-autocomplete-box {
border: 1px solid $color-calm;
+ box-shadow: 0 0 0 3px var(--cps-highlight-selected);
.cps-autocomplete-box-area {
.prefix-icon {
color: $color-calm;
@@ -79,6 +80,7 @@ $hover-transition-duration: 0.2s;
display: inline-flex;
margin-bottom: 0.2rem;
color: $autocomplete-label-color;
+ background-color: var(--cps-surface-body);
font-size: 0.875rem;
font-weight: 600;
.cps-autocomplete-label-info-circle {
@@ -106,13 +108,16 @@ $hover-transition-duration: 0.2s;
min-height: 38px;
width: 100%;
cursor: text;
- background: white;
+ background: var(--cps-input-background);
font-size: 1rem;
outline: none;
padding: 0 12px 0 12px;
- border-radius: 4px;
+ border-radius: var(--cps-border-radius-medium);
border: 1px solid $autocomplete-border-color;
- transition-duration: $hover-transition-duration;
+ transition:
+ border-color $hover-transition-duration var(--cps-motion-easing),
+ box-shadow $hover-transition-duration var(--cps-motion-easing),
+ background-color $hover-transition-duration var(--cps-motion-easing);
&-area {
display: flex;
@@ -135,7 +140,7 @@ $hover-transition-duration: 0.2s;
color: $autocomplete-option-value-color;
border-style: none;
outline: none;
- font-family: 'Source Sans Pro', sans-serif;
+ font-family: inherit;
&::placeholder {
color: $autocomplete-placeholder-color;
font-style: italic;
@@ -206,7 +211,7 @@ $hover-transition-duration: 0.2s;
}
&:hover {
- border: 1px solid $color-calm;
+ border: 1px solid var(--cps-border-strong);
.cps-autocomplete-box-area {
.prefix-icon {
color: $color-calm;
@@ -248,6 +253,8 @@ $hover-transition-duration: 0.2s;
.cps-autocomplete-hint {
color: $autocomplete-hint-color;
+ background-color: var(--cps-surface-body);
+ display: inline-block;
font-size: 0.75rem;
min-height: 1.125rem;
line-height: 1.125rem;
@@ -267,7 +274,7 @@ $hover-transition-duration: 0.2s;
&.disabled {
pointer-events: none;
.cps-autocomplete-box {
- background: #f7f7f7;
+ background: var(--cps-background-disabled);
&-items {
color: $autocomplete-items-disabled-color;
.text-group,
@@ -297,8 +304,12 @@ $hover-transition-duration: 0.2s;
}
.cps-autocomplete-options {
- font-family: 'Source Sans Pro', sans-serif;
- background: white;
+ font-family: inherit;
+ background: var(--cps-popover-background);
+ color: var(--cps-popover-foreground);
+ border: 1px solid var(--cps-border-color);
+ border-radius: var(--cps-border-radius-medium);
+ box-shadow: var(--cps-shadow-md);
overflow-x: hidden;
max-height: 242px;
overflow-y: auto;
@@ -390,7 +401,7 @@ $hover-transition-duration: 0.2s;
}
.select-all-option {
- border-bottom: 1px solid lightgrey;
+ border-bottom: 1px solid var(--cps-border-color);
font-weight: 600;
}
diff --git a/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.html b/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.html
index 70e42d96..f249662a 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.html
+++ b/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.html
@@ -11,7 +11,7 @@
class="cps-chip-close-icon"
icon="close-x"
size="xsmall"
- color="text-darkest"
+ color="text-primary"
(click)="onCloseClick($event)">
}
diff --git a/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.scss b/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.scss
index 7f3e2bc9..2c91bc6a 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.scss
+++ b/projects/cps-ui-kit/src/lib/components/cps-chip/cps-chip.component.scss
@@ -7,8 +7,9 @@
.cps-chip {
align-items: center;
display: inline-flex;
- background-color: var(--cps-color-bg-dark);
- border-radius: 14px;
+ background-color: var(--cps-surface-elevated);
+ border: 1px solid var(--cps-border-color);
+ border-radius: var(--cps-radius-full);
line-height: 16px;
padding: 4px 12px;
cursor: default;
@@ -17,28 +18,28 @@
cursor: pointer;
&:hover {
::ng-deep .cps-icon {
- color: var(--cps-color-calm) !important;
+ color: var(--cps-accent-primary) !important;
}
}
}
&-label {
font-size: 14px;
- color: var(--cps-color-text-darkest);
- font-family: 'Source Sans Pro', sans-serif;
+ color: var(--cps-text-primary);
+ font-family: inherit;
font-style: normal;
font-weight: 400;
}
&.cps-chip-disabled {
pointer-events: none;
- background-color: var(--cps-color-bg-mid);
+ background-color: var(--cps-background-disabled);
.cps-chip-label {
- color: var(--cps-color-text-light);
+ color: var(--cps-text-muted);
}
.cps-chip-icon,
.cps-chip-close-icon {
::ng-deep .cps-icon {
- color: var(--cps-color-text-light) !important;
+ color: var(--cps-text-muted) !important;
}
}
}
diff --git a/projects/cps-ui-kit/src/lib/components/cps-icon/cps-icon.component.ts b/projects/cps-ui-kit/src/lib/components/cps-icon/cps-icon.component.ts
index 37308567..92f3e5d7 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-icon/cps-icon.component.ts
+++ b/projects/cps-ui-kit/src/lib/components/cps-icon/cps-icon.component.ts
@@ -7,8 +7,8 @@ import {
Input,
OnChanges
} from '@angular/core';
-import { convertSize } from '../../utils/internal/size-utils';
import { getCSSColor } from '../../utils/colors-utils';
+import { convertSize } from '../../utils/internal/size-utils';
/**
* Injection token that is used to provide the path to the icons.
@@ -94,6 +94,7 @@ export const iconNames = [
'menu-shrink',
'minimize',
'minus',
+ 'moon',
'move-grabber',
'open',
'ownership',
@@ -120,6 +121,7 @@ export const iconNames = [
'stepper-completed',
'success',
'suggestion',
+ 'sun',
'survivorship',
'table-row-error',
'table-row-success',
diff --git a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.html b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.html
index c078ce2a..1828435e 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.html
+++ b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.html
@@ -2,7 +2,10 @@
@if (label) {
+ [ngClass]="{
+ 'cps-input-label-disabled': disabled && !readonly,
+ 'cps-input-label-error': error
+ }">
@if (infoTooltip) {
diff --git a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.scss b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.scss
index 75c985f1..4d4f0a94 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.scss
+++ b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.scss
@@ -1,17 +1,17 @@
-$color-calm: var(--cps-color-calm);
-$input-hint-color: var(--cps-color-text-mild);
-$input-label-disabled-color: var(--cps-color-text-mild);
-$input-pass-show-btn-color: var(--cps-color-text-mild);
-$input-placeholder-color: var(--cps-color-text-lightest);
-$input-border-color: var(--cps-color-line-light);
-$input-label-color: var(--cps-color-text-dark);
-$input-text-color: var(--cps-color-text-dark);
-$input-text-disabled-color: var(--cps-color-text-light);
-$input-prefix-text-color: var(--cps-color-text-mild);
-$input-prefix-icon-color: var(--cps-color-text-dark);
-
-$color-error: var(--cps-color-error);
-$error-background: #fef3f2;
+$color-calm: var(--cps-accent-primary);
+$input-hint-color: var(--cps-text-muted);
+$input-label-disabled-color: var(--cps-text-muted);
+$input-pass-show-btn-color: var(--cps-text-muted);
+$input-placeholder-color: var(--cps-input-placeholder);
+$input-border-color: var(--cps-border-color);
+$input-label-color: var(--cps-text-primary); // --cps-color-text-dark
+$input-text-color: var(--cps-text-primary); // --cps-color-text-dark
+$input-text-disabled-color: var(--cps-text-disabled);
+$input-prefix-text-color: var(--cps-text-muted);
+$input-prefix-icon-color: var(--cps-text-primary); // --cps-color-text-dark
+
+$color-error: var(--cps-state-error);
+$error-background: var(--cps-error-background);
$hover-transition-duration: 0.2s;
@@ -22,14 +22,14 @@ $hover-transition-duration: 0.2s;
gap: 0.2rem !important;
display: flex !important;
flex-direction: column !important;
- font-family: 'Source Sans Pro', sans-serif;
+ font-family: inherit;
.cps-input-wrap {
position: relative;
overflow: hidden;
&:hover {
input:enabled:not(:read-only) {
- border: 1px solid $color-calm;
+ border-color: var(--cps-border-strong);
}
}
&-error {
@@ -46,39 +46,37 @@ $hover-transition-duration: 0.2s;
input {
min-height: 38px;
- font-family: 'Source Sans Pro', sans-serif;
+ font-family: inherit;
font-size: 1rem;
color: $input-text-color;
- background: #ffffff;
+ background: var(--cps-input-background);
padding: 0.375rem 0.75rem;
line-height: 1.5;
border: 1px solid $input-border-color;
transition-duration: $hover-transition-duration;
appearance: none;
- border-radius: 4px;
+ border-radius: var(--cps-border-radius-medium);
width: 100%;
&:focus {
outline: 0;
}
&:focus:not(:read-only) {
- border: 1px solid $color-calm;
+ border-color: $color-calm;
+ box-shadow: 0 0 0 3px var(--cps-highlight-selected);
}
&:read-only {
cursor: default;
}
&:disabled {
- opacity: 1;
+ opacity: 0.7;
}
&:disabled:not([readonly]) {
- color: $input-text-disabled-color;
- background-color: #f7f7f7;
+ color: $input-text-disabled-color !important;
+ -webkit-text-fill-color: $input-text-disabled-color !important;
+ background-color: var(--cps-background-disabled);
pointer-events: none;
}
-
- &[type='password'] {
- font-family: Verdana;
- }
}
input:focus:not(:read-only) + .cps-input-prefix > .cps-input-prefix-icon,
@@ -116,7 +114,7 @@ $hover-transition-duration: 0.2s;
.clear-btn {
display: flex;
cursor: pointer;
- color: $color-calm;
+ color: var(--cps-state-error);
cps-icon {
opacity: 0;
transition-duration: $hover-transition-duration;
@@ -188,6 +186,26 @@ $hover-transition-duration: 0.2s;
&.underlined {
input {
border-bottom: 1px solid $input-border-color !important;
+ background: transparent;
+ box-shadow: none !important;
+ }
+ }
+
+ &.borderless {
+ input {
+ background: var(--cps-surface-muted);
+ box-shadow: none !important;
+ }
+
+ &:hover {
+ input:enabled:not(:read-only) {
+ background: var(--cps-highlight-hover);
+ }
+ }
+
+ input:focus:not(:read-only) {
+ background: var(--cps-highlight-selected);
+ border-color: transparent !important;
}
}
}
@@ -213,6 +231,7 @@ $hover-transition-duration: 0.2s;
.cps-input-hint {
color: $input-hint-color;
+ font-family: inherit;
font-size: 0.75rem;
min-height: 1.125rem;
line-height: 1.125rem;
@@ -220,6 +239,7 @@ $hover-transition-duration: 0.2s;
}
.cps-input-error {
color: $color-error;
+ font-family: inherit;
font-weight: bold;
font-size: 0.75rem;
min-height: 1.125rem;
@@ -240,9 +260,13 @@ $hover-transition-duration: 0.2s;
&-disabled {
color: $input-label-disabled-color;
}
+
+ &-error {
+ color: $color-error;
+ }
}
::placeholder {
- font-family: 'Source Sans Pro', sans-serif;
+ font-family: inherit;
color: $input-placeholder-color;
font-style: italic;
opacity: 1; /* Firefox */
diff --git a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.ts b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.ts
index 5995a28f..237d7f44 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.ts
+++ b/projects/cps-ui-kit/src/lib/components/cps-input/cps-input.component.ts
@@ -14,16 +14,16 @@ import {
ViewChild
} from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';
+import { Subscription } from 'rxjs';
+import { CpsTooltipPosition } from '../../directives/cps-tooltip/cps-tooltip.directive';
+import { convertSize } from '../../utils/internal/size-utils';
import {
CpsIconComponent,
IconType,
iconSizeType
} from '../cps-icon/cps-icon.component';
-import { Subscription } from 'rxjs';
-import { convertSize } from '../../utils/internal/size-utils';
-import { CpsProgressLinearComponent } from '../cps-progress-linear/cps-progress-linear.component';
import { CpsInfoCircleComponent } from '../cps-info-circle/cps-info-circle.component';
-import { CpsTooltipPosition } from '../../directives/cps-tooltip/cps-tooltip.directive';
+import { CpsProgressLinearComponent } from '../cps-progress-linear/cps-progress-linear.component';
/**
* CpsInputAppearanceType is used to define the border of the input field.
diff --git a/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.scss b/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.scss
index 98d14147..5905270b 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.scss
+++ b/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.scss
@@ -1,5 +1,5 @@
-$color-outer: var(--cps-color-calm);
-$color-middle: var(--cps-color-warmth);
+$color-outer: var(--cps-accent-primary);
+$color-middle: var(--cps-accent-secondary);
$color-inner: var(--cps-color-energy);
:host {
diff --git a/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.ts b/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.ts
index 6a37f298..875d3290 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.ts
+++ b/projects/cps-ui-kit/src/lib/components/cps-loader/cps-loader.component.ts
@@ -29,7 +29,7 @@ export class CpsLoaderComponent implements OnInit {
* Color of the label.
* @group Props
*/
- @Input() labelColor = 'depth';
+ @Input() labelColor = 'text-primary';
/**
* Determines whether to show 'Loading...' label.
@@ -37,7 +37,7 @@ export class CpsLoaderComponent implements OnInit {
*/
@Input() showLabel = true;
- backgroundColor = 'rgba(0, 0, 0, 0.1)';
+ backgroundColor = 'var(--cps-surface-overlay)';
// eslint-disable-next-line no-useless-constructor
constructor(@Inject(DOCUMENT) private document: Document) {}
diff --git a/projects/cps-ui-kit/src/lib/components/cps-progress-linear/cps-progress-linear.component.ts b/projects/cps-ui-kit/src/lib/components/cps-progress-linear/cps-progress-linear.component.ts
index 7d853bec..af4fe6d4 100644
--- a/projects/cps-ui-kit/src/lib/components/cps-progress-linear/cps-progress-linear.component.ts
+++ b/projects/cps-ui-kit/src/lib/components/cps-progress-linear/cps-progress-linear.component.ts
@@ -1,7 +1,7 @@
import { CommonModule, DOCUMENT } from '@angular/common';
import { Component, Inject, Input, OnInit } from '@angular/core';
-import { convertSize } from '../../utils/internal/size-utils';
import { getCSSColor } from '../../utils/colors-utils';
+import { convertSize } from '../../utils/internal/size-utils';
/**
* CpsProgressLinearComponent is a process status indicator of a rectangular form.
@@ -30,7 +30,7 @@ export class CpsProgressLinearComponent implements OnInit {
* Color of the progress bar.
* @group Props
*/
- @Input() color = 'calm';
+ @Input() color = 'var(--cps-accent-primary)';
/**
* Background color of the progress bar.
diff --git a/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.spec.ts b/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.spec.ts
new file mode 100644
index 00000000..79ab4a63
--- /dev/null
+++ b/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.spec.ts
@@ -0,0 +1,62 @@
+import { TestBed } from '@angular/core/testing';
+import { CpsThemeService } from './cps-theme.service';
+
+describe('CpsThemeService', () => {
+ let service: CpsThemeService;
+
+ beforeEach(() => {
+ localStorage.clear();
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(CpsThemeService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+
+ it('should initialize with system preference', () => {
+ expect(['light', 'dark']).toContain(service.theme());
+ });
+
+ it('should toggle theme', () => {
+ const initialTheme = service.theme();
+ service.toggleTheme();
+ const newTheme = service.theme();
+ expect(newTheme).not.toBe(initialTheme);
+ });
+
+ it('should save theme preference to localStorage', () => {
+ service.setTheme('dark', false);
+ expect(localStorage.getItem('cps-theme-preference')).toBe('dark');
+ });
+
+ it('should compute isDark correctly', () => {
+ service.setTheme('dark', false);
+ expect(service.isDark()).toBe(true);
+ service.setTheme('light', false);
+ expect(service.isDark()).toBe(false);
+ });
+
+ it('should initialize with calm color theme by default', () => {
+ expect(service.colorTheme()).toBe('calm');
+ });
+
+ it('should save color theme preference to localStorage', () => {
+ service.setColorTheme('energy', false);
+ expect(localStorage.getItem('cps-color-theme-preference')).toBe('energy');
+ });
+
+ it('should save base theme preference to localStorage', () => {
+ service.setBaseTheme('midnight', false);
+ expect(localStorage.getItem('cps-base-theme-preference')).toBe('midnight');
+ });
+
+ it('should save radius theme preference to localStorage', () => {
+ service.setRadiusTheme('rounded', false);
+ expect(localStorage.getItem('cps-radius-theme-preference')).toBe('rounded');
+ });
+
+ it('should initialize with compact radius theme by default', () => {
+ expect(service.radiusTheme()).toBe('compact');
+ });
+});
diff --git a/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.ts b/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.ts
new file mode 100644
index 00000000..c47bea99
--- /dev/null
+++ b/projects/cps-ui-kit/src/lib/services/cps-theme/cps-theme.service.ts
@@ -0,0 +1,297 @@
+import { DOCUMENT } from '@angular/common';
+import { computed, effect, inject, Injectable, signal } from '@angular/core';
+
+/**
+ * Available theme options
+ * @group Types
+ */
+export type CpsTheme = 'light' | 'dark';
+export type CpsColorTheme = 'neutral' | 'calm' | 'energy' | 'passion';
+export type CpsBaseTheme = 'default' | 'graphite' | 'midnight' | 'aubergine';
+export type CpsRadiusTheme = 'none' | 'compact' | 'rounded' | 'pill';
+
+/**
+ * CpsThemeService manages application theming including dark mode support.
+ *
+ * This service provides:
+ * - Light and dark theme switching with smooth transitions
+ * - Automatic persistence of theme preference in localStorage
+ * - System preference detection (prefers-color-scheme)
+ * - Reactive state management using Angular signals
+ *
+ * @example
+ * ```typescript
+ * class MyComponent {
+ * private themeService = inject(CpsThemeService);
+ *
+ * isDark = this.themeService.isDark;
+ *
+ * toggleTheme() {
+ * this.themeService.toggleTheme();
+ * }
+ * }
+ * ```
+ *
+ * @group Services
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class CpsThemeService {
+ private document = inject(DOCUMENT);
+ private readonly THEME_STORAGE_KEY = 'cps-theme-preference';
+ private readonly COLOR_THEME_STORAGE_KEY = 'cps-color-theme-preference';
+ private readonly BASE_THEME_STORAGE_KEY = 'cps-base-theme-preference';
+ private readonly RADIUS_THEME_STORAGE_KEY = 'cps-radius-theme-preference';
+ private readonly TRANSITION_CLASS = 'cps-theme-transition';
+ private readonly TRANSITION_DURATION = 500;
+
+ private _theme = signal(this.getInitialTheme());
+ private _colorTheme = signal(this.getInitialColorTheme());
+ private _baseTheme = signal(this.getInitialBaseTheme());
+ private _radiusTheme = signal(this.getInitialRadiusTheme());
+
+ /**
+ * Current active theme (readonly)
+ */
+ readonly theme = this._theme.asReadonly();
+
+ /**
+ * Current active color theme (readonly)
+ */
+ readonly colorTheme = this._colorTheme.asReadonly();
+
+ /**
+ * Current active base theme (readonly)
+ */
+ readonly baseTheme = this._baseTheme.asReadonly();
+
+ /**
+ * Current active radius theme (readonly)
+ */
+ readonly radiusTheme = this._radiusTheme.asReadonly();
+
+ /**
+ * Whether dark mode is currently active
+ */
+ readonly isDark = computed(() => this._theme() === 'dark');
+
+ constructor() {
+ // Apply theme changes to DOM whenever theme signal changes
+ effect(() => {
+ this.applyTheme(
+ this._theme(),
+ this._colorTheme(),
+ this._baseTheme(),
+ this._radiusTheme()
+ );
+ });
+
+ // Listen for system theme changes
+ this.watchSystemTheme();
+ }
+
+ /**
+ * Toggle between light and dark themes with smooth transition
+ */
+ toggleTheme(): void {
+ const newTheme: CpsTheme = this._theme() === 'light' ? 'dark' : 'light';
+ this.setTheme(newTheme);
+ }
+
+ /**
+ * Set specific theme
+ * @param theme - Theme to apply ('light' or 'dark')
+ * @param animated - Whether to animate the transition (default: true)
+ */
+ setTheme(theme: CpsTheme, animated = true): void {
+ if (this._theme() === theme) return;
+
+ if (animated) {
+ this.enableTransition();
+ }
+
+ this._theme.set(theme);
+ this.saveThemePreference(theme);
+
+ if (animated) {
+ setTimeout(() => this.disableTransition(), this.TRANSITION_DURATION);
+ }
+ }
+
+ /**
+ * Set specific color theme independently from mode
+ * @param colorTheme - Color theme to apply
+ * @param animated - Whether to animate the transition (default: true)
+ */
+ setColorTheme(colorTheme: CpsColorTheme, animated = true): void {
+ if (this._colorTheme() === colorTheme) return;
+
+ if (animated) {
+ this.enableTransition();
+ }
+
+ this._colorTheme.set(colorTheme);
+ this.saveColorThemePreference(colorTheme);
+
+ if (animated) {
+ setTimeout(() => this.disableTransition(), this.TRANSITION_DURATION);
+ }
+ }
+
+ /**
+ * Set base background theme (primarily affects dark mode)
+ */
+ setBaseTheme(baseTheme: CpsBaseTheme, animated = true): void {
+ if (this._baseTheme() === baseTheme) return;
+
+ if (animated) {
+ this.enableTransition();
+ }
+
+ this._baseTheme.set(baseTheme);
+ this.saveBaseThemePreference(baseTheme);
+
+ if (animated) {
+ setTimeout(() => this.disableTransition(), this.TRANSITION_DURATION);
+ }
+ }
+
+ /**
+ * Set radius profile
+ */
+ setRadiusTheme(radiusTheme: CpsRadiusTheme, animated = true): void {
+ if (this._radiusTheme() === radiusTheme) return;
+
+ if (animated) {
+ this.enableTransition();
+ }
+
+ this._radiusTheme.set(radiusTheme);
+ this.saveRadiusThemePreference(radiusTheme);
+
+ if (animated) {
+ setTimeout(() => this.disableTransition(), this.TRANSITION_DURATION);
+ }
+ }
+
+ private applyTheme(
+ theme: CpsTheme,
+ colorTheme: CpsColorTheme,
+ baseTheme: CpsBaseTheme,
+ radiusTheme: CpsRadiusTheme
+ ): void {
+ this.document.documentElement.setAttribute('data-theme', theme);
+ this.document.documentElement.setAttribute('data-color-theme', colorTheme);
+ this.document.documentElement.setAttribute('data-base-theme', baseTheme);
+ this.document.documentElement.setAttribute(
+ 'data-radius-theme',
+ radiusTheme
+ );
+ }
+
+ private enableTransition(): void {
+ this.document.documentElement.classList.add(this.TRANSITION_CLASS);
+ }
+
+ private disableTransition(): void {
+ this.document.documentElement.classList.remove(this.TRANSITION_CLASS);
+ }
+
+ private getInitialTheme(): CpsTheme {
+ // Check saved preference first
+ const stored = localStorage.getItem(
+ this.THEME_STORAGE_KEY
+ ) as CpsTheme | null;
+ if (stored === 'light' || stored === 'dark') {
+ return stored;
+ }
+
+ // Fall back to system preference
+ return this.getSystemTheme();
+ }
+
+ private getInitialColorTheme(): CpsColorTheme {
+ const stored = localStorage.getItem(
+ this.COLOR_THEME_STORAGE_KEY
+ ) as CpsColorTheme | null;
+
+ if (
+ stored === 'neutral' ||
+ stored === 'calm' ||
+ stored === 'energy' ||
+ stored === 'passion'
+ ) {
+ return stored;
+ }
+
+ return 'calm';
+ }
+
+ private getInitialBaseTheme(): CpsBaseTheme {
+ const stored = localStorage.getItem(
+ this.BASE_THEME_STORAGE_KEY
+ ) as CpsBaseTheme | null;
+
+ if (
+ stored === 'default' ||
+ stored === 'graphite' ||
+ stored === 'midnight' ||
+ stored === 'aubergine'
+ ) {
+ return stored;
+ }
+
+ return 'default';
+ }
+
+ private getInitialRadiusTheme(): CpsRadiusTheme {
+ const stored = localStorage.getItem(
+ this.RADIUS_THEME_STORAGE_KEY
+ ) as CpsRadiusTheme | null;
+
+ if (
+ stored === 'none' ||
+ stored === 'compact' ||
+ stored === 'rounded' ||
+ stored === 'pill'
+ ) {
+ return stored;
+ }
+
+ return 'compact';
+ }
+
+ private getSystemTheme(): CpsTheme {
+ const prefersDark = window.matchMedia(
+ '(prefers-color-scheme: dark)'
+ ).matches;
+ return prefersDark ? 'dark' : 'light';
+ }
+
+ private watchSystemTheme(): void {
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+ mediaQuery.addEventListener('change', (e) => {
+ // Only auto-switch if user hasn't set a preference
+ if (!localStorage.getItem(this.THEME_STORAGE_KEY)) {
+ this.setTheme(e.matches ? 'dark' : 'light');
+ }
+ });
+ }
+
+ private saveThemePreference(theme: CpsTheme): void {
+ localStorage.setItem(this.THEME_STORAGE_KEY, theme);
+ }
+
+ private saveColorThemePreference(colorTheme: CpsColorTheme): void {
+ localStorage.setItem(this.COLOR_THEME_STORAGE_KEY, colorTheme);
+ }
+
+ private saveBaseThemePreference(baseTheme: CpsBaseTheme): void {
+ localStorage.setItem(this.BASE_THEME_STORAGE_KEY, baseTheme);
+ }
+
+ private saveRadiusThemePreference(radiusTheme: CpsRadiusTheme): void {
+ localStorage.setItem(this.RADIUS_THEME_STORAGE_KEY, radiusTheme);
+ }
+}
diff --git a/projects/cps-ui-kit/src/public-api.ts b/projects/cps-ui-kit/src/public-api.ts
index 0141399e..97b6370c 100644
--- a/projects/cps-ui-kit/src/public-api.ts
+++ b/projects/cps-ui-kit/src/public-api.ts
@@ -2,53 +2,53 @@
* Public API Surface of cps-ui-kit
*/
-export * from './lib/components/cps-icon/cps-icon.component';
-export * from './lib/components/cps-input/cps-input.component';
-export * from './lib/components/cps-select/cps-select.component';
-export * from './lib/components/cps-tree-select/cps-tree-select.component';
export * from './lib/components/cps-autocomplete/cps-autocomplete.component';
-export * from './lib/components/cps-tree-autocomplete/cps-tree-autocomplete.component';
-export * from './lib/components/cps-info-circle/cps-info-circle.component';
+export * from './lib/components/cps-button-toggle/cps-button-toggle.component';
export * from './lib/components/cps-button/cps-button.component';
export * from './lib/components/cps-checkbox/cps-checkbox.component';
-export * from './lib/components/cps-radio-group/cps-radio/cps-radio.component';
+export * from './lib/components/cps-chip/cps-chip.component';
+export * from './lib/components/cps-datepicker/cps-datepicker.component';
+export * from './lib/components/cps-divider/cps-divider.component';
+export * from './lib/components/cps-expansion-panel/cps-expansion-panel.component';
+export * from './lib/components/cps-file-upload/cps-file-upload.component';
+export * from './lib/components/cps-icon/cps-icon.component';
+export * from './lib/components/cps-info-circle/cps-info-circle.component';
+export * from './lib/components/cps-input/cps-input.component';
+export * from './lib/components/cps-loader/cps-loader.component';
+export * from './lib/components/cps-menu/cps-menu.component';
+export * from './lib/components/cps-paginator/cps-paginator.component';
+export * from './lib/components/cps-paginator/pipes/cps-paginate.pipe';
+export * from './lib/components/cps-progress-circular/cps-progress-circular.component';
+export * from './lib/components/cps-progress-linear/cps-progress-linear.component';
export * from './lib/components/cps-radio-group/cps-radio-group.component';
+export * from './lib/components/cps-radio-group/cps-radio/cps-radio.component';
+export * from './lib/components/cps-scheduler/cps-scheduler.component';
+export * from './lib/components/cps-select/cps-select.component';
+export * from './lib/components/cps-sidebar-menu/cps-sidebar-menu.component';
+export * from './lib/components/cps-switch/cps-switch.component';
+export * from './lib/components/cps-tab-group/cps-tab-group.component';
+export * from './lib/components/cps-tab-group/cps-tab/cps-tab.component';
+export * from './lib/components/cps-table/cps-column-filter-types';
export * from './lib/components/cps-table/cps-table.component';
-export * from './lib/components/cps-table/directives/cps-table-column-sortable.directive';
export * from './lib/components/cps-table/directives/cps-table-column-filter.directive';
export * from './lib/components/cps-table/directives/cps-table-column-resizable.directive';
+export * from './lib/components/cps-table/directives/cps-table-column-sortable.directive';
export * from './lib/components/cps-table/directives/cps-table-header-selectable.directive';
export * from './lib/components/cps-table/directives/cps-table-row-selectable.directive';
-export * from './lib/components/cps-table/cps-column-filter-types';
export * from './lib/components/cps-table/pipes/cps-table-detect-filter-type.pipe';
+export * from './lib/components/cps-tag/cps-tag.component';
+export * from './lib/components/cps-textarea/cps-textarea.component';
+export * from './lib/components/cps-timepicker/cps-timepicker.component';
+export * from './lib/components/cps-tree-autocomplete/cps-tree-autocomplete.component';
+export * from './lib/components/cps-tree-select/cps-tree-select.component';
export * from './lib/components/cps-tree-table/cps-tree-table.component';
-export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-sortable.directive';
export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-filter.directive';
export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-resizable.directive';
-export * from './lib/components/cps-tree-table/directives/cps-tree-table-row-toggler.directive';
+export * from './lib/components/cps-tree-table/directives/cps-tree-table-column-sortable.directive';
export * from './lib/components/cps-tree-table/directives/cps-tree-table-header-selectable.directive';
export * from './lib/components/cps-tree-table/directives/cps-tree-table-row-selectable.directive';
+export * from './lib/components/cps-tree-table/directives/cps-tree-table-row-toggler.directive';
export * from './lib/components/cps-tree-table/pipes/cps-tree-table-detect-filter-type.pipe';
-export * from './lib/components/cps-tag/cps-tag.component';
-export * from './lib/components/cps-chip/cps-chip.component';
-export * from './lib/components/cps-menu/cps-menu.component';
-export * from './lib/components/cps-paginator/cps-paginator.component';
-export * from './lib/components/cps-paginator/pipes/cps-paginate.pipe';
-export * from './lib/components/cps-loader/cps-loader.component';
-export * from './lib/components/cps-expansion-panel/cps-expansion-panel.component';
-export * from './lib/components/cps-progress-circular/cps-progress-circular.component';
-export * from './lib/components/cps-progress-linear/cps-progress-linear.component';
-export * from './lib/components/cps-datepicker/cps-datepicker.component';
-export * from './lib/components/cps-sidebar-menu/cps-sidebar-menu.component';
-export * from './lib/components/cps-textarea/cps-textarea.component';
-export * from './lib/components/cps-button-toggle/cps-button-toggle.component';
-export * from './lib/components/cps-tab-group/cps-tab-group.component';
-export * from './lib/components/cps-tab-group/cps-tab/cps-tab.component';
-export * from './lib/components/cps-timepicker/cps-timepicker.component';
-export * from './lib/components/cps-file-upload/cps-file-upload.component';
-export * from './lib/components/cps-scheduler/cps-scheduler.component';
-export * from './lib/components/cps-switch/cps-switch.component';
-export * from './lib/components/cps-divider/cps-divider.component';
export * from './lib/directives/cps-tooltip/cps-tooltip.directive';
@@ -59,4 +59,5 @@ export * from './lib/services/cps-dialog/utils/cps-dialog-ref';
export * from './lib/services/cps-notification/cps-notification.service';
export * from './lib/services/cps-notification/utils/cps-notification-config';
+export * from './lib/services/cps-theme/cps-theme.service';
export * from './lib/utils/colors-utils';
diff --git a/projects/cps-ui-kit/styles/_colors-dark.scss b/projects/cps-ui-kit/styles/_colors-dark.scss
new file mode 100644
index 00000000..bbb76e6e
--- /dev/null
+++ b/projects/cps-ui-kit/styles/_colors-dark.scss
@@ -0,0 +1,449 @@
+// Dark theme color palette
+// Using color theory: warm reds with cool teal/cyan complements
+// Cool blue-gray backgrounds provide temperature balance with warm red accents
+// Proper contrast ratios for WCAG AA compliance
+
+[data-theme='dark'] {
+ // Main brand colors - slightly desaturated and lighter for dark backgrounds
+ --cps-color-energy: #f47721;
+ --cps-color-energy-highlighten: #faece5;
+ --cps-color-energy-lighten5: #ffff9f;
+ --cps-color-energy-lighten4: #ffe883;
+ --cps-color-energy-lighten3: #ffcb68;
+ --cps-color-energy-lighten2: #ffaf4d;
+ --cps-color-energy-lighten1: #ff9331;
+ --cps-color-energy-darken1: #de5d00;
+ --cps-color-energy-darken2: #be4300;
+ --cps-color-energy-darken3: #9f2800;
+ --cps-color-energy-darken4: #820100;
+
+ --cps-color-prepared: #fa551e;
+ --cps-color-prepared-highlighten: #f9e9e5;
+ --cps-color-prepared-lighten5: #ffe4a1;
+ --cps-color-prepared-lighten4: #ffc786;
+ --cps-color-prepared-lighten3: #ffaa6c;
+ --cps-color-prepared-lighten2: #ff8e52;
+ --cps-color-prepared-lighten1: #ff7138;
+ --cps-color-prepared-darken1: #d93700;
+ --cps-color-prepared-darken2: #b91000;
+ --cps-color-prepared-darken3: #990000;
+ --cps-color-prepared-darken4: #7c0000;
+
+ --cps-color-agile: #f52d28;
+ --cps-color-agile-highlighten: #f9e6e6;
+ --cps-color-agile-lighten5: #ffc8a6;
+ --cps-color-agile-lighten4: #ffaa8b;
+ --cps-color-agile-lighten3: #ff8d71;
+ --cps-color-agile-lighten2: #ff6f58;
+ --cps-color-agile-lighten1: #ff5040;
+ --cps-color-agile-darken1: #d40010;
+ --cps-color-agile-darken2: #b30000;
+ --cps-color-agile-darken3: #930000;
+ --cps-color-agile-darken4: #760000;
+
+ --cps-color-passion: #dc0032;
+ --cps-color-passion-highlighten: #f7e3e7;
+ --cps-color-passion-lighten5: #ffb3ae;
+ --cps-color-passion-lighten4: #ff9693;
+ --cps-color-passion-lighten3: #ff7879;
+ --cps-color-passion-lighten2: #ff5a61;
+ --cps-color-passion-lighten1: #fd3849;
+ --cps-color-passion-darken1: #bc001d;
+ --cps-color-passion-darken2: #9b0007;
+ --cps-color-passion-darken3: #7d0000;
+ --cps-color-passion-darken4: #600000;
+
+ --cps-color-warmth: #be0028;
+ --cps-color-warmth-highlighten: #f3e3e6;
+ --cps-color-warmth-lighten5: #ffa9a2;
+ --cps-color-warmth-lighten4: #ff8d87;
+ --cps-color-warmth-lighten3: #ff706e;
+ --cps-color-warmth-lighten2: #fe5255;
+ --cps-color-warmth-lighten1: #de333e;
+ --cps-color-warmth-darken1: #9e0013;
+ --cps-color-warmth-darken2: #800000;
+ --cps-color-warmth-darken3: #630000;
+ --cps-color-warmth-darken4: #4b0000;
+
+ --cps-color-human: #aa052d;
+ --cps-color-human-highlighten: #f1e3e6;
+ --cps-color-human-lighten5: #ffa4a7;
+ --cps-color-human-lighten4: #ff888d;
+ --cps-color-human-lighten3: #ff6c73;
+ --cps-color-human-lighten2: #e84f5a;
+ --cps-color-human-lighten1: #c93143;
+ --cps-color-human-darken1: #8b0019;
+ --cps-color-human-darken2: #6d0000;
+ --cps-color-human-darken3: #520000;
+ --cps-color-human-darken4: #400000;
+
+ --cps-color-grounded: #960528;
+ --cps-color-grounded-highlighten: #f0e3e6;
+ --cps-color-grounded-lighten5: #ff9ea1;
+ --cps-color-grounded-lighten4: #ff8286;
+ --cps-color-grounded-lighten3: #f2666d;
+ --cps-color-grounded-lighten2: #d34b55;
+ --cps-color-grounded-lighten1: #b42e3e;
+ --cps-color-grounded-darken1: #780014;
+ --cps-color-grounded-darken2: #5c0000;
+ --cps-color-grounded-darken3: #440000;
+ --cps-color-grounded-darken4: #390000;
+
+ --cps-color-care: #f05a78;
+ --cps-color-care-highlighten: #f8e9ed;
+ --cps-color-care-lighten5: #ffe9ff;
+ --cps-color-care-lighten4: #ffcce9;
+ --cps-color-care-lighten3: #ffafcd;
+ --cps-color-care-lighten2: #ff93b1;
+ --cps-color-care-lighten1: #ff7697;
+ --cps-color-care-darken1: #d13d64;
+ --cps-color-care-darken2: #b31a4c;
+ --cps-color-care-darken3: #950036;
+ --cps-color-care-darken4: #770021;
+
+ --cps-color-smile: #f0325a;
+ --cps-color-smile-highlighten: #f8e7e9;
+ --cps-color-smile-lighten5: #ffcbdd;
+ --cps-color-smile-lighten4: #ffadc1;
+ --cps-color-smile-lighten3: #ff90a6;
+ --cps-color-smile-lighten2: #ff728c;
+ --cps-color-smile-lighten1: #ff5472;
+ --cps-color-smile-darken1: #d00043;
+ --cps-color-smile-darken2: #b0002d;
+ --cps-color-smile-darken3: #910019;
+ --cps-color-smile-darken4: #720000;
+
+ --cps-color-surprise: #af144b;
+ --cps-color-surprise-highlighten: #f2e4e9;
+ --cps-color-surprise-lighten5: #ffaccb;
+ --cps-color-surprise-lighten4: #ff8fb0;
+ --cps-color-surprise-lighten3: #ff7395;
+ --cps-color-surprise-lighten2: #ec577b;
+ --cps-color-surprise-lighten1: #cd3963;
+ --cps-color-surprise-darken1: #910035;
+ --cps-color-surprise-darken2: #730020;
+ --cps-color-surprise-darken3: #560008;
+ --cps-color-surprise-darken4: #400000;
+
+ --cps-color-calm: #870a3c;
+ --cps-color-calm-highlighten: #efe4e7;
+ --cps-color-calm-lighten5: #ff9bb9;
+ --cps-color-calm-lighten4: #fd809e;
+ --cps-color-calm-lighten3: #df6584;
+ --cps-color-calm-lighten2: #c14a6b;
+ --cps-color-calm-lighten1: #a42e53;
+ --cps-color-calm-darken1: #6b0027;
+ --cps-color-calm-darken2: #4f0012;
+ --cps-color-calm-darken3: #390000;
+ --cps-color-calm-darken4: #300000;
+
+ --cps-color-luxury: #640032;
+ --cps-color-luxury-highlighten: #ebe3e6;
+ --cps-color-luxury-lighten5: #f28bad;
+ --cps-color-luxury-lighten4: #d57192;
+ --cps-color-luxury-lighten3: #b85779;
+ --cps-color-luxury-lighten2: #9b3d60;
+ --cps-color-luxury-lighten1: #7f2248;
+ --cps-color-luxury-darken1: #49001d;
+ --cps-color-luxury-darken2: #340002;
+ --cps-color-luxury-darken3: #290000;
+ --cps-color-luxury-darken4: #1c0000;
+
+ --cps-color-depth: #500a28;
+ --cps-color-depth-highlighten: #e9e3e6;
+ --cps-color-depth-lighten5: #d989a0;
+ --cps-color-depth-lighten4: #bc6f86;
+ --cps-color-depth-lighten3: #a0566d;
+ --cps-color-depth-lighten2: #853d55;
+ --cps-color-depth-lighten1: #6a253e;
+ --cps-color-depth-darken1: #370013;
+ --cps-color-depth-darken2: #290000;
+ --cps-color-depth-darken3: #1b0000;
+ --cps-color-depth-darken4: #000000;
+
+ //Darks
+ --cps-color-silver: #736464;
+ --cps-color-silver-highlighten: #edeaea;
+ --cps-color-silver-lighten5: #fbe9e9;
+ --cps-color-silver-lighten4: #decdcd;
+ --cps-color-silver-lighten3: #c2b2b1;
+ --cps-color-silver-lighten2: #a79797;
+ --cps-color-silver-lighten1: #8d7d7d;
+ --cps-color-silver-darken1: #5a4c4c;
+ --cps-color-silver-darken2: #433535;
+ --cps-color-silver-darken3: #2c2020;
+ --cps-color-silver-darken4: #190909;
+
+ --cps-color-platinum: #5a4b4b;
+ --cps-color-platinum-highlighten: #eae8e8;
+ --cps-color-platinum-lighten5: #decccc;
+ --cps-color-platinum-lighten4: #c2b0b0;
+ --cps-color-platinum-lighten3: #a79695;
+ --cps-color-platinum-lighten2: #8c7c7c;
+ --cps-color-platinum-lighten1: #736363;
+ --cps-color-platinum-darken1: #423434;
+ --cps-color-platinum-darken2: #2c1f1f;
+ --cps-color-platinum-darken3: #190707;
+ --cps-color-platinum-darken4: #000000;
+
+ --cps-color-graphite: #2d2323;
+ --cps-color-graphite-highlighten: #e7e5e5;
+ --cps-color-graphite-lighten5: #a79a9a;
+ --cps-color-graphite-lighten4: #8d8080;
+ --cps-color-graphite-lighten3: #736767;
+ --cps-color-graphite-lighten2: #5b4f4f;
+ --cps-color-graphite-lighten1: #433838;
+ --cps-color-graphite-darken1: #190d0d;
+ --cps-color-graphite-darken2: #000000;
+ --cps-color-graphite-darken3: #000000;
+ --cps-color-graphite-darken4: #000000;
+
+ //States
+ --cps-color-info: #099ef3;
+ --cps-color-info-highlighten: #e5eff8;
+ --cps-color-info-lighten5: #d0ffff;
+ --cps-color-info-lighten4: #b0ffff;
+ --cps-color-info-lighten3: #90f1ff;
+ --cps-color-info-lighten2: #6fd4ff;
+ --cps-color-info-lighten1: #49b9ff;
+ --cps-color-info-darken1: #0084d6;
+ --cps-color-info-darken2: #006bba;
+ --cps-color-info-darken3: #00539f;
+ --cps-color-info-darken4: #003d84;
+
+ --cps-color-success: #3bb719;
+ --cps-color-success-highlighten: #e8f2e6;
+ --cps-color-success-lighten5: #d5ffaa;
+ --cps-color-success-lighten4: #b7ff8e;
+ --cps-color-success-lighten3: #99ff72;
+ --cps-color-success-lighten2: #7bf057;
+ --cps-color-success-lighten1: #5dd33a;
+ --cps-color-success-darken1: #059b00;
+ --cps-color-success-darken2: #008100;
+ --cps-color-success-darken3: #006600;
+ --cps-color-success-darken4: #004d00;
+
+ --cps-color-warn: #ff9f00;
+ --cps-color-warn-highlighten: #faefe5;
+ --cps-color-warn-lighten5: #ffffa3;
+ --cps-color-warn-lighten4: #ffff87;
+ --cps-color-warn-lighten3: #fff26b;
+ --cps-color-warn-lighten2: #ffd64e;
+ --cps-color-warn-lighten1: #ffba30;
+ --cps-color-warn-darken1: #df8500;
+ --cps-color-warn-darken2: #c06b00;
+ --cps-color-warn-darken3: #a15300;
+ --cps-color-warn-darken4: #843b00;
+
+ --cps-color-error-highlighten: #f9e4e5;
+ --cps-color-error-lighten5: #f5d9d9;
+ --cps-color-error-lighten4: #f2cece;
+ --cps-color-error-lighten3: #e9a7a7;
+ --cps-color-error-lighten2: #df8080;
+ --cps-color-error-lighten1: #d55959;
+ --cps-color-error-darken1: #a32828;
+ --cps-color-error-darken2: #7a1e1e;
+ --cps-color-error-darken3: #511414;
+ --cps-color-error-darken4: #300c0c;
+
+ // States backgrounds
+ --cps-color-info-bg: rgba(73, 185, 255, 0.16);
+ --cps-color-success-bg: rgba(93, 211, 58, 0.16);
+ --cps-color-warn-bg: rgba(255, 186, 48, 0.16);
+ --cps-color-error-bg: rgba(255, 90, 103, 0.16);
+
+ // Highlights
+ --cps-color-highlight-hover: rgba(251, 251, 251, 0.06);
+ --cps-color-highlight-active: rgba(251, 251, 251, 0.1);
+ --cps-color-highlight-selected: rgba(244, 119, 33, 0.16);
+ --cps-color-highlight-selected-dark: rgba(244, 119, 33, 0.24);
+
+ //Backgrounds
+ --cps-color-bg-lightest: #2a2a31;
+ --cps-color-bg-light: #1f1f24;
+ --cps-color-bg-mid: #1b1b1e;
+ --cps-color-bg-dark: #151419;
+
+ //Lines
+ --cps-color-line-light: #3f3f46;
+ --cps-color-line-mid: #50505a;
+ --cps-color-line-dark: #666670;
+ --cps-color-line-darkest: #7a7a86;
+
+ //Text
+ --cps-color-text-lightest: #fbfbfb;
+ --cps-color-text-light: #d0d0d2;
+ --cps-color-text-mild: #a8a8ad;
+ --cps-color-text-dark: #878787;
+ --cps-color-text-darkest: #151419;
+
+ // Semantic design tokens (use these inside components)
+ --cps-accent-primary: var(--cps-color-energy);
+ --cps-accent-primary-contrast: #151419;
+ --cps-accent-secondary: #fbfbfb;
+ --cps-accent-secondary-contrast: #151419;
+ --cps-color-error: #b91c1c;
+ --cps-error-background: rgba(255, 90, 103, 0.16);
+
+ // Lines and borders
+ --cps-color-line: rgba(251, 251, 251, 0.12);
+ --cps-surface-body: #151419;
+ --cps-surface-highlight: #1b1b1e;
+ --cps-surface-muted: #202028;
+ --cps-surface-elevated: #262626;
+ --cps-surface-control: #262626;
+ --cps-surface-overlay: rgba(21, 20, 25, 0.85);
+ --cps-background-color: #151419;
+ --cps-background-disabled: rgba(
+ 255,
+ 255,
+ 255,
+ 0.05
+ ); // oklch(55.096% 0.02679 264.351 / 0.452);
+
+ // Tab component
+ --cps-tab-subtabs-background: var(--cps-surface-highlight);
+ --cps-tabs-subtabs-active-background: var(--cps-color-highlight-selected);
+ --cps-tabs-subtabs-background-hover: var(--cps-highlight-hover);
+ --cps-tabs-subtabs-text-hover: var(--cps-text-primary);
+
+ // Text
+ --cps-text-primary: #fbfbfb;
+ --cps-text-secondary: #d0d0d2;
+ --cps-text-muted: #878787;
+ --cps-text-inverse: var(--cps-color-depth-darken4);
+ --cps-text-on-accent: #151419;
+ --cps-text-disabled: #6f6f74;
+
+ --cps-border-color: #3a3a3a;
+ --cps-border-strong: #505050;
+ --cps-border-focus: var(--cps-accent-primary);
+
+ --cps-highlight-hover: rgba(251, 251, 251, 0.1);
+ --cps-highlight-active: rgba(251, 251, 251, 0.16);
+ --cps-highlight-selected: var(--cps-color-highlight-selected-dark);
+
+ --cps-state-info: #49b9ff;
+ --cps-state-info-contrast: #151419;
+ --cps-state-info-surface: rgba(73, 185, 255, 0.16);
+ --cps-state-success: #5dd33a;
+ --cps-state-success-contrast: #151419;
+ --cps-state-success-surface: rgba(93, 211, 58, 0.16);
+ --cps-state-warn: #ffba30;
+ --cps-state-warn-contrast: #151419;
+ --cps-state-warn-surface: rgba(255, 186, 48, 0.16);
+ --cps-state-error: var(--cps-color-error);
+ --cps-state-error-contrast: #ffffff;
+ --cps-state-error-surface: rgba(185, 28, 28, 0.28);
+
+ // Modern semantic surfaces
+ --cps-card-background: var(--cps-surface-highlight);
+ --cps-card-foreground: var(--cps-text-primary);
+ --cps-popover-background: var(--cps-surface-elevated);
+ --cps-popover-foreground: var(--cps-text-primary);
+ --cps-input-background: var(--cps-surface-highlight);
+ --cps-input-foreground: var(--cps-text-primary);
+ --cps-input-placeholder: var(--cps-text-muted);
+
+ // Focus ring and outlines
+ --cps-ring-color: var(--cps-border-focus);
+ --cps-ring-offset-color: var(--cps-surface-body);
+
+ // Radius scale
+ --cps-radius-xs: 2px;
+ --cps-radius-sm: 4px;
+ --cps-radius-md: 8px;
+ --cps-radius-lg: 12px;
+ --cps-radius-xl: 16px;
+ --cps-radius-full: 9999px;
+
+ // Backward compatible radius aliases
+ --cps-border-radius-small: var(--cps-radius-sm);
+ --cps-border-radius-medium: var(--cps-radius-md);
+ --cps-border-radius-large: var(--cps-radius-lg);
+ --cps-border-radius-round: var(--cps-radius-full);
+
+ // Elevation shadows
+ --cps-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
+ --cps-shadow-sm: 0 4px 10px rgba(0, 0, 0, 0.34);
+ --cps-shadow-md: 0 12px 24px rgba(0, 0, 0, 0.4);
+ --cps-shadow-lg: 0 24px 48px rgba(0, 0, 0, 0.5);
+
+ // Motion tokens
+ --cps-motion-fast: 120ms;
+ --cps-motion-base: 180ms;
+ --cps-motion-slow: 260ms;
+ --cps-motion-easing: cubic-bezier(0.2, 0, 0, 1);
+}
+
+[data-theme='dark'][data-color-theme='neutral'] {
+ --cps-accent-primary: #e4e4e7;
+ --cps-accent-primary-contrast: #151419;
+ --cps-accent-secondary: #f4f4f5;
+ --cps-accent-secondary-contrast: #151419;
+ --cps-border-focus: #e4e4e7;
+ --cps-highlight-selected: rgba(228, 228, 231, 0.22);
+}
+
+[data-theme='dark'][data-color-theme='calm'] {
+ --cps-accent-primary: var(--cps-color-calm-lighten4);
+ --cps-accent-primary-contrast: #151419;
+ --cps-accent-secondary: var(--cps-color-care-lighten3);
+ --cps-accent-secondary-contrast: #151419;
+ --cps-border-focus: var(--cps-color-calm-lighten4);
+ --cps-highlight-selected: rgba(253, 128, 158, 0.28);
+}
+
+[data-theme='dark'][data-color-theme='energy'] {
+ --cps-accent-primary: var(--cps-color-energy);
+ --cps-accent-primary-contrast: #151419;
+ --cps-accent-secondary: var(--cps-color-prepared-lighten4);
+ --cps-accent-secondary-contrast: #151419;
+ --cps-border-focus: var(--cps-color-energy);
+ --cps-highlight-selected: var(--cps-color-highlight-selected-dark);
+}
+
+[data-theme='dark'][data-color-theme='passion'] {
+ --cps-accent-primary: var(--cps-color-passion-lighten3);
+ --cps-accent-primary-contrast: #151419;
+ --cps-accent-secondary: var(--cps-color-care-lighten4);
+ --cps-accent-secondary-contrast: #151419;
+ --cps-border-focus: var(--cps-color-passion-lighten3);
+ --cps-highlight-selected: rgba(255, 120, 121, 0.3);
+}
+
+[data-theme='dark'][data-base-theme='graphite'] {
+ --cps-surface-body: #121216;
+ --cps-surface-highlight: #191a20;
+ --cps-surface-muted: #1d1f26;
+ --cps-surface-elevated: #23252f;
+ --cps-surface-control: #23252f;
+ --cps-background-color: #121216;
+ --cps-border-color: #3f424d;
+ --cps-border-strong: #555968;
+ --cps-ring-offset-color: #121216;
+}
+
+[data-theme='dark'][data-base-theme='midnight'] {
+ --cps-surface-body: #0f1624;
+ --cps-surface-highlight: #172033;
+ --cps-surface-muted: #1b263c;
+ --cps-surface-elevated: #21304a;
+ --cps-surface-control: #21304a;
+ --cps-background-color: #0f1624;
+ --cps-border-color: #32445f;
+ --cps-border-strong: #4a6388;
+ --cps-ring-offset-color: #0f1624;
+}
+
+[data-theme='dark'][data-base-theme='aubergine'] {
+ --cps-surface-body: #1a1320;
+ --cps-surface-highlight: #231a2c;
+ --cps-surface-muted: #2b2136;
+ --cps-surface-elevated: #332943;
+ --cps-surface-control: #332943;
+ --cps-background-color: #1a1320;
+ --cps-border-color: #534363;
+ --cps-border-strong: #6d5683;
+ --cps-ring-offset-color: #1a1320;
+}
diff --git a/projects/cps-ui-kit/styles/_colors.scss b/projects/cps-ui-kit/styles/_colors.scss
index c63e637a..dfd461a9 100644
--- a/projects/cps-ui-kit/styles/_colors.scss
+++ b/projects/cps-ui-kit/styles/_colors.scss
@@ -272,4 +272,165 @@
--cps-color-text-mild: #787272;
--cps-color-text-dark: #524a4a;
--cps-color-text-darkest: #2d2323;
+
+ // Semantic design tokens (use these inside components)
+ --cps-accent-primary: var(--cps-color-passion);
+ --cps-accent-primary-contrast: #ffffff;
+ --cps-accent-secondary: var(--cps-color-energy);
+ --cps-accent-secondary-contrast: #2d2323;
+ --cps-color-error: #b91c1c;
+ --cps-error-background: #fef3f2;
+
+ // Lines and borders
+ --cps-color-line: #e3e2e2;
+
+ --cps-surface-body: var(--cps-color-bg-light);
+ --cps-surface-highlight: #ffffff;
+ --cps-surface-muted: var(
+ --cps-color-bg-lightest
+ ); //switched with --cps-color-bg-light, investigate impact
+ --cps-surface-elevated: var(--cps-color-bg-mid);
+ --cps-surface-control: #ffffff;
+ --cps-surface-overlay: rgba(0, 0, 0, 0.45);
+ --cps-background-color: var(--cps-color-bg-lightest);
+ --cps-background-disabled: #f7f7f7;
+
+ // Tab component
+ --cps-tab-subtabs-background: #d7d7d759;
+ --cps-tabs-subtabs-active-background: #fff;
+ --cps-tabs-subtabs-background-hover: var(--cps-highlight-active);
+ --cps-tabs-subtabs-text-hover: var(--cps-accent-primary);
+
+ --cps-text-primary: var(--cps-color-text-darkest);
+ --cps-text-secondary: var(--cps-color-text-dark);
+ --cps-text-muted: var(--cps-color-text-mild);
+ --cps-text-inverse: var(--cps-color-depth-darken4);
+ --cps-text-on-accent: #ffffff;
+ --cps-text-disabled: var(--cps-color-text-light);
+
+ --cps-border-color: var(--cps-color-line-mid);
+ --cps-border-strong: var(--cps-color-line-dark);
+ --cps-border-focus: var(--cps-color-passion);
+
+ --cps-highlight-hover: var(--cps-color-highlight-hover);
+ --cps-highlight-active: var(--cps-color-highlight-active);
+ --cps-highlight-selected: var(--cps-color-highlight-selected);
+
+ --cps-state-info: var(--cps-color-info);
+ --cps-state-info-contrast: #2d2323;
+ --cps-state-info-surface: var(--cps-color-info-bg);
+ --cps-state-success: var(--cps-color-success);
+ --cps-state-success-contrast: #2d2323;
+ --cps-state-success-surface: var(--cps-color-success-bg);
+ --cps-state-warn: var(--cps-color-warn);
+ --cps-state-warn-contrast: #3b2500;
+ --cps-state-warn-surface: var(--cps-color-warn-bg);
+ --cps-state-error: var(--cps-color-error);
+ --cps-state-error-contrast: #ffffff;
+ --cps-state-error-surface: rgba(185, 28, 28, 0.14);
+
+ // Modern semantic surfaces
+ --cps-card-background: var(--cps-surface-highlight);
+ --cps-card-foreground: var(--cps-text-primary);
+ --cps-popover-background: var(--cps-surface-control);
+ --cps-popover-foreground: var(--cps-text-primary);
+ --cps-input-background: var(--cps-surface-control);
+ --cps-input-foreground: var(--cps-text-primary);
+ --cps-input-placeholder: var(--cps-text-muted);
+
+ // Focus ring and outlines
+ --cps-ring-color: var(--cps-border-focus);
+ --cps-ring-offset-color: var(--cps-surface-body);
+
+ // Radius scale
+ --cps-radius-xs: 2px;
+ --cps-radius-sm: 4px;
+ --cps-radius-md: 8px;
+ --cps-radius-lg: 12px;
+ --cps-radius-xl: 16px;
+ --cps-radius-full: 9999px;
+
+ // Backward compatible radius aliases
+ --cps-border-radius-small: var(--cps-radius-sm);
+ --cps-border-radius-medium: var(--cps-radius-md);
+ --cps-border-radius-large: var(--cps-radius-lg);
+ --cps-border-radius-round: var(--cps-radius-full);
+
+ // Elevation shadows
+ --cps-shadow-xs: 0 1px 2px rgba(45, 35, 35, 0.08);
+ --cps-shadow-sm: 0 2px 6px rgba(45, 35, 35, 0.12);
+ --cps-shadow-md: 0 8px 20px rgba(45, 35, 35, 0.14);
+ --cps-shadow-lg: 0 16px 40px rgba(45, 35, 35, 0.2);
+
+ // Motion tokens
+ --cps-motion-fast: 120ms;
+ --cps-motion-base: 180ms;
+ --cps-motion-slow: 260ms;
+ --cps-motion-easing: cubic-bezier(0.2, 0, 0, 1);
+}
+
+:root[data-color-theme='neutral'] {
+ --cps-accent-primary: #27272a;
+ --cps-accent-primary-contrast: #ffffff;
+ --cps-accent-secondary: #3f3f46;
+ --cps-accent-secondary-contrast: #ffffff;
+ --cps-border-focus: #27272a;
+ --cps-highlight-selected: rgba(39, 39, 42, 0.14);
+}
+
+:root[data-color-theme='calm'] {
+ --cps-accent-primary: var(--cps-color-calm);
+ --cps-accent-primary-contrast: #ffffff;
+ --cps-accent-secondary: var(--cps-color-care);
+ --cps-accent-secondary-contrast: #2d2323;
+ --cps-border-focus: var(--cps-color-calm);
+ --cps-highlight-selected: rgba(135, 10, 60, 0.16);
+}
+
+:root[data-color-theme='energy'] {
+ --cps-accent-primary: var(--cps-color-energy);
+ --cps-accent-primary-contrast: #2d2323;
+ --cps-text-on-accent: #2d2323;
+ --cps-accent-secondary: var(--cps-color-prepared);
+ --cps-accent-secondary-contrast: #2d2323;
+ --cps-border-focus: var(--cps-color-energy);
+ --cps-highlight-selected: var(--cps-color-highlight-selected);
+}
+
+:root[data-color-theme='passion'] {
+ --cps-accent-primary: var(--cps-color-passion);
+ --cps-accent-primary-contrast: #ffffff;
+ --cps-accent-secondary: var(--cps-color-warmth);
+ --cps-accent-secondary-contrast: #ffffff;
+ --cps-border-focus: var(--cps-color-passion);
+ --cps-highlight-selected: rgba(220, 0, 50, 0.16);
+}
+
+:root[data-radius-theme='none'] {
+ --cps-radius-xs: 0px;
+ --cps-radius-sm: 0px;
+ --cps-radius-md: 0px;
+ --cps-radius-lg: 0px;
+ --cps-radius-xl: 0px;
+}
+
+:root[data-radius-theme='compact'] {
+ --cps-radius-sm: 3px;
+ --cps-radius-md: 6px;
+ --cps-radius-lg: 10px;
+ --cps-radius-xl: 14px;
+}
+
+:root[data-radius-theme='rounded'] {
+ --cps-radius-sm: 6px;
+ --cps-radius-md: 10px;
+ --cps-radius-lg: 14px;
+ --cps-radius-xl: 20px;
+}
+
+:root[data-radius-theme='pill'] {
+ --cps-radius-sm: 9999px;
+ --cps-radius-md: 9999px;
+ --cps-radius-lg: 9999px;
+ --cps-radius-xl: 9999px;
}
diff --git a/projects/cps-ui-kit/styles/styles.scss b/projects/cps-ui-kit/styles/styles.scss
index 79e63a09..84dfb7d1 100644
--- a/projects/cps-ui-kit/styles/styles.scss
+++ b/projects/cps-ui-kit/styles/styles.scss
@@ -1,5 +1,6 @@
@use './_bootstrap-grid';
@use './_colors.scss';
+@use './_colors-dark.scss';
@use './_fonts.scss';
@use './_cps-tooltip-style.scss';
@use 'primeicons/primeicons.css';
@@ -18,3 +19,38 @@
position: absolute;
top: -9999px;
}
+
+/* Custom scrollbar */
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+::-webkit-scrollbar-track {
+ background: var(--cps-background-color);
+}
+::-webkit-scrollbar-thumb {
+ background: var(--cps-border-color);
+ border-radius: var(--cps-radius-sm);
+}
+::-webkit-scrollbar-thumb:hover {
+ background: var(--cps-accent-primary);
+}
+
+html,
+body {
+ font-family: 'Source Sans Pro', sans-serif;
+ background: var(--cps-background-color);
+ color: var(--cps-text-primary);
+}
+
+// Theme transition hook used by CpsThemeService
+.cps-theme-transition,
+.cps-theme-transition *,
+.cps-theme-transition *::before,
+.cps-theme-transition *::after {
+ transition:
+ background-color var(--cps-motion-base) var(--cps-motion-easing),
+ border-color var(--cps-motion-base) var(--cps-motion-easing),
+ color var(--cps-motion-base) var(--cps-motion-easing),
+ box-shadow var(--cps-motion-base) var(--cps-motion-easing) !important;
+}