From e87201b774395fbb2e99c1058dacb3d05f1db542 Mon Sep 17 00:00:00 2001 From: ross-nics Date: Wed, 10 Jun 2026 17:29:02 +0800 Subject: [PATCH 1/2] chore: add husky pre-commit hook to lint staged styles - add husky and lint-staged dev dependencies - run stylelint --fix on staged .css/.scss files via pre-commit hook - include .scss in lint:styles and lint:fix:styles globs --- .husky/pre-commit | 1 + package-lock.json | 554 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 10 +- 3 files changed, 562 insertions(+), 3 deletions(-) create mode 100644 .husky/pre-commit diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/package-lock.json b/package-lock.json index d9ba6ca0..5151fa87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,12 @@ { - "name": "guide_test", + "name": "guide", "lockfileVersion": 3, "requires": true, "packages": { "": { "devDependencies": { + "husky": "^9.1.7", + "lint-staged": "^17.0.7", "stylelint": "^16.12.0", "stylelint-config-standard-scss": "^14.0.0", "stylelint-order": "^6.0.4" @@ -180,6 +182,22 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -255,6 +273,131 @@ "node": ">=6" } }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -383,6 +526,19 @@ "node": ">=6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -392,6 +548,13 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -491,6 +654,19 @@ "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -585,6 +761,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/ignore": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", @@ -760,12 +952,205 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/lint-staged": { + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.7.tgz", + "integrity": "sha512-JrSobt+tW3rH8IOMi8tDZd3foorM5yPEkLD/V2NxobgHrFfHWGee4MOLVuZeScgxftEwbHrPHIFA/ZL+nUJeuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "listr2": "^10.2.1", + "picomatch": "^4.0.4", + "string-argv": "^0.3.2", + "tinyexec": "^1.2.4" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=22.22.1" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + }, + "optionalDependencies": { + "yaml": "^2.9.0" + } + }, + "node_modules/lint-staged/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/listr2": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.1.tgz", + "integrity": "sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^10.0.0" + }, + "engines": { + "node": ">=22.13.0" + } + }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -816,6 +1201,19 @@ "node": ">=8.6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -849,6 +1247,22 @@ "node": ">=0.10.0" } }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1064,6 +1478,23 @@ "node": ">=8" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1074,6 +1505,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -1144,6 +1582,16 @@ "node": ">=0.10.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1409,6 +1857,16 @@ "node": ">=10.0.0" } }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1439,6 +1897,83 @@ "which": "bin/which" } }, + "node_modules/wrap-ansi": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -1451,6 +1986,23 @@ "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } } } } diff --git a/package.json b/package.json index 644e1d74..694ba440 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,15 @@ { "scripts": { - "lint:styles": "npx stylelint '**/*.css' --ignore-path .gitignore", - "lint:fix:styles": "npx stylelint '**/*.css' --ignore-path .gitignore --fix" + "lint:styles": "npx stylelint '**/*.{css,scss}' --ignore-path .gitignore", + "lint:fix:styles": "npx stylelint '**/*.{css,scss}' --ignore-path .gitignore --fix", + "prepare": "husky" + }, + "lint-staged": { + "*.{css,scss}": "stylelint --fix" }, "devDependencies": { + "husky": "^9.1.7", + "lint-staged": "^17.0.7", "stylelint": "^16.12.0", "stylelint-config-standard-scss": "^14.0.0", "stylelint-order": "^6.0.4" From 8ea6995d6ff343f0f2bd682209f04dae3aac87f3 Mon Sep 17 00:00:00 2001 From: ross-nics Date: Wed, 10 Jun 2026 17:50:38 +0800 Subject: [PATCH 2/2] chore: configure stylelint for libsass and fix style lint errors - adjust .stylelintrc.json for libsass compatibility (legacy color notation, prefix media-feature range, allow global sass functions) - relax selector-class-pattern to allow BEM naming; disable no-descending-specificity - fix remaining lint errors: duplicate selectors/properties, property order, variable kebab-case, extend placeholder, number precision, comment spacing - apply stylelint --fix property ordering across css/scss files --- .stylelintrc.json | 8 ++ assets/css/color.css | 27 +++--- assets/css/components/accordion.scss | 34 +++---- assets/css/components/breadcrumb.scss | 37 ++++--- assets/css/components/carousel.scss | 106 ++++++++++----------- assets/css/components/checkable.scss | 2 +- assets/css/components/cookie-banner.scss | 6 +- assets/css/components/ctas.scss | 32 ++++--- assets/css/components/date-picker.scss | 103 ++++++++++---------- assets/css/components/footer.scss | 31 +++--- assets/css/components/form.scss | 35 +++---- assets/css/components/header.scss | 45 ++++----- assets/css/components/layout.scss | 6 +- assets/css/components/list.scss | 2 +- assets/css/components/modal.scss | 90 ++++++++--------- assets/css/components/nav.scss | 6 +- assets/css/components/password-input.scss | 14 +-- assets/css/components/search-feedback.scss | 52 +++++----- assets/css/components/skip-to.css | 20 ++-- assets/css/components/table.scss | 26 ++--- assets/css/components/tabs.css | 31 +++--- assets/css/components/toolbar.scss | 81 ++++++++-------- assets/css/components/warning-text.scss | 12 +-- assets/css/guide.scss | 46 ++++----- assets/css/lang/ja.css | 2 +- assets/css/lang/th.css | 2 +- assets/css/lang/vi.css | 2 +- assets/css/lang/zh.css | 2 +- assets/css/main.scss | 32 +++---- assets/css/typography.scss | 20 ++-- assets/css/variables.scss | 16 ++-- 31 files changed, 463 insertions(+), 465 deletions(-) diff --git a/.stylelintrc.json b/.stylelintrc.json index fe865a81..591306d0 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -7,6 +7,14 @@ "custom-property-pattern": null, "scss/comment-no-empty": null, "scss/at-rule-no-unknown": true, + "scss/no-global-function-names": null, + "no-descending-specificity": null, + "media-feature-range-notation": "prefix", + "color-function-notation": "legacy", + "selector-class-pattern": [ + "^[a-z][a-z0-9]*(-[a-z0-9]+)*(__[a-z0-9]+(-[a-z0-9]+)*)?(--[a-z0-9]+(-[a-z0-9]+)*)?$", + { "message": "Expected class selector to be BEM kebab-case (block__element--modifier)" } + ], "order/order": [ "custom-properties", "declarations" diff --git a/assets/css/color.css b/assets/css/color.css index d39a2372..7381fa95 100644 --- a/assets/css/color.css +++ b/assets/css/color.css @@ -51,11 +51,6 @@ --gov-amber-700: #b85814; --gov-amber-800: #8a3c0f; --gov-amber-900: #62361c; - - - - - --gov-blue: #0d6efd; --gov-indigo: #6610f2; --gov-purple: #6f42c1; @@ -109,9 +104,9 @@ --gov-dark-border-subtle: #adb5bd; --gov-white-rgb: 255, 255, 255; --gov-black-rgb: 0, 0, 0; - --gov-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --gov-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --gov-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --gov-font-sans-serif: system-ui, -apple-system, "Segoe UI", roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --gov-font-monospace: sfmono-regular, menlo, monaco, consolas, "Liberation Mono", "Courier New", monospace; + --gov-gradient: linear-gradient(180deg, rgba(255, 255, 255, 15%), rgba(255, 255, 255, 0%)); --gov-body-font-family: var(--gov-font-sans-serif); --gov-body-font-size: 1rem; --gov-body-font-weight: 400; @@ -122,11 +117,11 @@ --gov-body-bg-rgb: 255, 255, 255; --gov-emphasis-color: #000; --gov-emphasis-color-rgb: 0, 0, 0; - --gov-secondary-color: rgba(33, 37, 41, 0.75); + --gov-secondary-color: rgba(33, 37, 41, 75%); --gov-secondary-color-rgb: 33, 37, 41; --gov-secondary-bg: #e9ecef; --gov-secondary-bg-rgb: 233, 236, 239; - --gov-tertiary-color: rgba(33, 37, 41, 0.5); + --gov-tertiary-color: rgba(33, 37, 41, 50%); --gov-tertiary-color-rgb: 33, 37, 41; --gov-tertiary-bg: #f8f9fa; --gov-tertiary-bg-rgb: 248, 249, 250; @@ -142,7 +137,7 @@ --gov-border-width: 1px; --gov-border-style: solid; --gov-border-color: #dee2e6; - --gov-border-color-translucent: rgba(0, 0, 0, 0.175); + --gov-border-color-translucent: rgba(0, 0, 0, 17.5%); --gov-border-radius: 0.375rem; --gov-border-radius-sm: 0.25rem; --gov-border-radius-lg: 0.5rem; @@ -150,13 +145,13 @@ --gov-border-radius-xxl: 2rem; --gov-border-radius-2xl: var(--gov-border-radius-xxl); --gov-border-radius-pill: 50rem; - --gov-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - --gov-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); - --gov-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); - --gov-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); + --gov-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 15%); + --gov-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 7.5%); + --gov-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 17.5%); + --gov-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 7.5%); --gov-focus-ring-width: 0.25rem; --gov-focus-ring-opacity: 0.25; - --gov-focus-ring-color: rgba(13, 110, 253, 0.25); + --gov-focus-ring-color: rgba(13, 110, 253, 25%); --gov-form-valid-color: #198754; --gov-form-valid-border-color: #198754; --gov-form-invalid-color: #dc3545; diff --git a/assets/css/components/accordion.scss b/assets/css/components/accordion.scss index 8ad9e3ca..5674cb10 100644 --- a/assets/css/components/accordion.scss +++ b/assets/css/components/accordion.scss @@ -2,35 +2,35 @@ $accordion-header-bg: var(--backgroundColor); $accordion-header-active-bg: var(--primaryColor); $accordion-body-bg: var(--backgroundColor); -$accordion-header-fontColor: var(--textColor); -$accordion-header-active-fontColor: var(--backgroundColor); +$accordion-header-fontcolor: var(--textColor); +$accordion-header-active-fontcolor: var(--backgroundColor); $accordion-body-border: var(--borderColor); -$accordion-body-active-border:var(--secondaryTextColor); +$accordion-body-active-border: var(--secondaryTextColor); + /* 相對路徑:部署時 baseURL 含路徑(如 GCS guide-dev/RUN_ID)時,絕對路徑 /svgs/* 會漏掉路徑導致 403 */ $accordion-icon-url: url("svgs/downarrow.svg"); $accordion-icon-active-url: url("svgs/uparrow.svg"); .accordion { - width: 100%; margin: 0 auto; + width: 100%; input[type="checkbox"] { display: none; } label { - display: block; - padding: 16px 20px; background: $accordion-header-bg; - color: $accordion-header-fontColor; + color: $accordion-header-fontcolor; cursor: pointer; - margin-bottom: 0; - position: relative; - + display: block; font-size: 16px; font-weight: 600; - line-height: 1.4; letter-spacing: 0.32px; + line-height: 1.4; + margin-bottom: 0; + padding: 16px 20px; + position: relative; text-align: left; .main-title { @@ -47,22 +47,22 @@ $accordion-icon-active-url: url("svgs/uparrow.svg"); } &::after { - content: ''; background-image: $accordion-icon-url; background-repeat: no-repeat; background-size: 20px; - width: 20px; + content: ''; height: 20px; position: absolute; right: 15px; top: 50%; transform: translateY(-50%); + width: 20px; } } input[type="checkbox"]:checked + label { background: $accordion-header-active-bg; - color: $accordion-header-active-fontColor; + color: $accordion-header-active-fontcolor; &::after { background-image: $accordion-icon-active-url; @@ -70,13 +70,13 @@ $accordion-icon-active-url: url("svgs/uparrow.svg"); } .accordion-body { - max-height: 0; - overflow: hidden; background: $accordion-body-bg; font-size: 14px; font-weight: normal; - line-height: 1.4; letter-spacing: 0.56px; + line-height: 1.4; + max-height: 0; + overflow: hidden; text-align: left; input[type="checkbox"]:checked ~ & { diff --git a/assets/css/components/breadcrumb.scss b/assets/css/components/breadcrumb.scss index 04758338..097c0dcf 100644 --- a/assets/css/components/breadcrumb.scss +++ b/assets/css/components/breadcrumb.scss @@ -1,13 +1,13 @@ nav.breadcrumb { - padding: 0.8em 1em; - border: 0px solid var(--textColor); - border-radius: 4px; background: var(--backgroundColor); + border: 0 solid var(--textColor); + border-radius: 4px; + padding: 0.8em 1em; ol { + list-style: none; margin: 0; padding-left: 0; - list-style: none; } li { @@ -23,18 +23,19 @@ nav.breadcrumb { // render as slash separator // use li + li::before to skip the first item li + li::before { + border-right: 0.1em solid currentcolor; + content: ""; display: inline-block; + height: 0.8em; margin: 0 0.25em; transform: rotate(15deg); - border-right: 0.1em solid currentcolor; - height: 0.8em; - content: ""; } // render as slash separator &.arrow-separator { // Size of chevron (excluding border) 7/16 px ≅ 0.4375 $chevron-size: 0.4375em; + // Size of chevron border $chevron-border-min-width: 1px; $chevron-border-width: 0.0625em; @@ -43,29 +44,25 @@ nav.breadcrumb { // of length 8 (7px + 1px border): // // √(8² + 8²) * 0.5 ≅ 5.655 - // 5.655 / 16 ≅ 0.3534375 - $chevron-altitude-calculated: 0.3534375em; + // 5.655 / 16 ≅ 0.3534 + $chevron-altitude-calculated: 0.3534em; // use li + li::before to skip the first item li + li::before { + border: solid; + border-color: var(--textColor); + border-width: $chevron-border-min-width $chevron-border-min-width 0 0; + bottom: 0; + // ref: https://github.com/alphagov/govuk-frontend/blob/main/packages/govuk-frontend/src/govuk/components/breadcrumbs/_index.scss // Create a chevron using a box with borders on two sides, rotated 45deg. content: ""; display: inline-block; - - top: 0; - bottom: 0; - - width: $chevron-size; height: $chevron-size; - margin: auto 0.25em; - + top: 0; transform: translateX(-25%) rotate(45deg); - - border: solid; - border-width: $chevron-border-min-width $chevron-border-min-width 0 0; - border-color: var(--textColor); + width: $chevron-size; } } } diff --git a/assets/css/components/carousel.scss b/assets/css/components/carousel.scss index 3fa50be1..2e5adf4c 100644 --- a/assets/css/components/carousel.scss +++ b/assets/css/components/carousel.scss @@ -1,11 +1,11 @@ /* .carousel */ img.reload { - padding: 0.25em; display: inline-block; + height: 0.9em; + padding: 0.25em; position: relative; top: 6px; - height: 0.9em; } .carousel { @@ -20,8 +20,8 @@ img.reload { padding: 5px; &.focus { - padding: 2px; border: solid 3px #005a9c; + padding: 2px; } } @@ -29,8 +29,8 @@ img.reload { display: none; max-height: 400px; max-width: 900px; - position: relative; overflow: hidden; + position: relative; width: 100%; &.active { @@ -43,44 +43,44 @@ img.reload { } .carousel-caption { - position: absolute; - right: 15%; bottom: 0; + color: #fff; left: 15%; - padding-top: 20px; padding-bottom: 20px; - color: #fff; + padding-top: 20px; + position: absolute; + right: 15%; text-align: center; a { - cursor: pointer; - text-decoration: underline; color: #fff; + cursor: pointer; font-weight: 600; + text-decoration: underline; &:hover { - background-color: rgba(0, 0, 0, 1); + background-color: rgba(0, 0, 0, 100%); } &:focus { - padding: 4px; + background-color: rgba(0, 0, 0, 100%); border: 2px solid #fff; - background-color: rgba(0, 0, 0, 1); - outline: none; color: #fff; + outline: none; + padding: 4px; } } span.contrast { + background-color: rgba(0, 0, 0, 65%); + border: 0 solid transparent; + border-radius: 5px; display: inline-block; margin: 0; padding: 6px; - background-color: rgba(0, 0, 0, 0.65); - border-radius: 5px; - border: 0 solid transparent; &:hover { - background-color: rgba(0, 0, 0, 1); + background-color: rgba(0, 0, 0, 100%); } } @@ -94,22 +94,22 @@ img.reload { .controls { box-sizing: border-box; + display: flex; + padding: 0.25em 1.25em 0; position: absolute; top: 1em; - z-index: 10; - display: flex; width: 100%; - padding: 0.25em 1.25em 0; + z-index: 10; button { - position: absolute; - z-index: 10; + background: transparent; + border: none; flex: 0 0 auto; margin: 0; - padding: 0; - border: none; - background: transparent; outline: none; + padding: 0; + position: absolute; + z-index: 10; &.previous { right: 70px; @@ -123,8 +123,8 @@ img.reload { &:hover svg .background, &:hover svg .border { fill: #005a9c; - stroke: #005a9c; opacity: 1; + stroke: #005a9c; } &:focus svg .border { @@ -133,10 +133,10 @@ img.reload { svg { .background { - stroke: black; fill: black; - stroke-width: 1px; opacity: 0.6; + stroke: black; + stroke-width: 1px; } .border { @@ -146,15 +146,15 @@ img.reload { } .pause { - stroke-width: 4; fill: transparent; stroke: transparent; + stroke-width: 4; } .play { - stroke-width: 1; fill: transparent; stroke: transparent; + stroke-width: 1; } polygon { @@ -179,21 +179,21 @@ img.reload { /* More like bootstrap, less accessible */ .carousel-moreaccessible { - padding: 0; - margin: 0; - position: relative; border: #eee solid 4px; border-radius: 5px; + margin: 0; + padding: 0; + position: relative; .controls { - position: relative; - top: 0; left: 0; padding: 0.25em 0.25em 0; + position: relative; + top: 0; &.carousel-moreaccessible { - position: static; height: 36px; + position: static; button.previous { right: 60px; @@ -207,57 +207,57 @@ img.reload { .carousel-items, .carousel-items.focus { - padding: 0; border: none; + padding: 0; &.focus .carousel-image a { - padding: 2px; border: 3px solid #005a9c; + padding: 2px; } } .carousel-item { - padding: 0; margin: 0; max-height: none; + padding: 0; .carousel-caption { - position: static; - padding: 0; - margin: 0; - height: 60px; color: black; + height: 60px; + margin: 0; + padding: 0; + position: static; p { - padding: 0; margin: 0; + padding: 0; } h3 { font-size: 1.1em; - padding: 0; margin: 0; + padding: 0; } a { - display: inline-block; - margin: 0; - padding: 6px; - color: black; background-color: transparent; border: none; border-radius: 5px; + color: black; + display: inline-block; + margin: 0; + padding: 6px; &:hover { - background-color: rgba(0, 0, 0, 0.2); + background-color: rgba(0, 0, 0, 20%); } &:focus { - padding: 4px; - border: 2px solid #005a9c; background-color: transparent; + border: 2px solid #005a9c; color: black; outline: none; + padding: 4px; } } diff --git a/assets/css/components/checkable.scss b/assets/css/components/checkable.scss index 563a50b5..bfda4c3f 100644 --- a/assets/css/components/checkable.scss +++ b/assets/css/components/checkable.scss @@ -4,8 +4,8 @@ } & ~ .fields { + margin-left: 1.7em; margin-top: 1em; width: 100%; - margin-left: 1.7em; } } diff --git a/assets/css/components/cookie-banner.scss b/assets/css/components/cookie-banner.scss index 9f9ad02f..3dba1674 100644 --- a/assets/css/components/cookie-banner.scss +++ b/assets/css/components/cookie-banner.scss @@ -2,15 +2,15 @@ $border-bottom-width: 10px; .cookie-banner { - padding-top: 20px; + background-color: var(--backgroundColorLayer1); + // The component does not set bottom spacing. The bottom spacing should be // created by the items inside the component. // Visually separate the cookie banner from content underneath when user // changes colours in their browser. border-bottom: $border-bottom-width solid transparent; - - background-color: var(--backgroundColorLayer1); + padding-top: 20px; } // Support older browsers which don't hide elements with the `hidden` attribute diff --git a/assets/css/components/ctas.scss b/assets/css/components/ctas.scss index 339b51df..5fe920c1 100644 --- a/assets/css/components/ctas.scss +++ b/assets/css/components/ctas.scss @@ -1,11 +1,11 @@ a.link-block { - display: inline-block; - padding: 0.6em 1.2em; + border: 1px solid var(--backgroundColorLayer2); color: var(--linkColor); + display: inline-block; font-weight: 600; + padding: 0.6em 1.2em; text-decoration-thickness: 1px; text-underline-position: from-font; - border: 1px solid var(--backgroundColorLayer2); &:hover, &:focus { text-decoration-thickness: 2px; @@ -16,32 +16,33 @@ button.button, summary.button { --buttonColor: var(--backgroundColor); --buttonBorderColor: var(--borderColor); - font-size: 0.9rem; - padding: 0.6rem 1.2rem; + + background: var(--backgroundColor); border: 1px solid var(--buttonBorderColor); border-radius: 0.45rem; color: var(--textColor); - background: var(--backgroundColor); cursor: pointer; + font-size: 0.9rem; + padding: 0.6rem 1.2rem; - &:hover:not(.button-disabled):not(:disabled), &:focus { + &:hover:not(.button-disabled, :disabled), &:focus { + border-color: var(--buttonBorderColor); box-shadow: inset 0 0 1000px var(--hoverOverlay), 0 0 0 2px var(--hoverOverlay); - border-color: var(--buttonBorderColor); } - &:active:not(:disabled):not(.button-disabled) { + &:active:not(:disabled, .button-disabled) { transform: translateY(1px); } &.button-danger, &.button-primary { - color: var(--backgroundColor); background: var(--buttonColor); border-color: var(--buttonBorderColor); + color: var(--backgroundColor); - &:hover:not(:disabled):not(.button-disabled), &:focus { + &:hover:not(:disabled, .button-disabled), &:focus { box-shadow: inset 0 0 1000px var(--hoverOverlay), 0 0 0 1px var(--backgroundColor), @@ -61,12 +62,13 @@ summary.button { &[disabled], &.button-disabled { --buttonBorderColor: var(--borderColor); - cursor: not-allowed; - outline: 1px dashed var(--borderColor); - border-width: 2px; + border-radius: 0.45rem; - opacity: 0.8; + border-width: 2px; box-shadow: inset 0 0 1000px var(--hoverOverlay); + cursor: not-allowed; + opacity: 0.8; + outline: 1px dashed var(--borderColor); } &.button-mini { diff --git a/assets/css/components/date-picker.scss b/assets/css/components/date-picker.scss index 6e8d8482..50616651 100644 --- a/assets/css/components/date-picker.scss +++ b/assets/css/components/date-picker.scss @@ -21,43 +21,43 @@ // ── 主要 block ──────────────────────────────────────────────── .dp { - position: relative; display: inline-block; + position: relative; // ── 標籤 ────────────────────────────────────────────────── &__label { display: block; - margin-block-end: 0.25rem; - font-weight: 500; font-size: 0.9375rem; + font-weight: 500; + margin-block-end: 0.25rem; } // ── 輸入列容器 ──────────────────────────────────────────── &__input-group { - display: flex; align-items: center; + display: flex; gap: 0.5rem; } // ── Input 元件 ──────────────────────────────────────────── &__input { - flex: 1; - min-width: 10rem; - padding: 0.375rem 0.75rem; + background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ border: 1px solid var(--borderColor); border-radius: 0.375rem; + color: var(--textColor, #111827) /* 專案 token: --textColor(variables.scss) */; + flex: 1; font-size: 1rem; line-height: 1.5; - background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ - color: var(--textColor, #111827) /* 專案 token: --textColor(variables.scss) */; + min-width: 10rem; + padding: 0.375rem 0.75rem; &:focus { + border-color: var(--dp-focus-color, #005fcc); outline: 2px solid var(--dp-focus-color, #005fcc); outline-offset: 2px; - border-color: var(--dp-focus-color, #005fcc); } // 原生 date input: @@ -103,19 +103,19 @@ // ── 日曆開啟按鈕 ────────────────────────────────────────── &__button { - flex-shrink: 0; - display: inline-flex; align-items: center; - justify-content: center; - width: 2.25rem; - height: 2.25rem; - padding: 0; + background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ border: 1px solid var(--borderColor); border-radius: 0.375rem; - background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ color: var(--secondaryTextColor, #374151) /* 專案 token: --secondaryTextColor(variables.scss) */; cursor: pointer; + display: inline-flex; + flex-shrink: 0; + height: 2.25rem; + justify-content: center; + padding: 0; transition: background-color 0.15s ease, border-color 0.15s ease; + width: 2.25rem; &:hover { background: var(--backgroundColorLayer1, #f3f4f6) /* 專案 token: --backgroundColorLayer1(variables.scss) */; @@ -133,16 +133,16 @@ // ── 月曆 Dialog(浮層面板) ─────────────────────────────── &__dialog { - position: absolute; - inset-block-start: calc(100% + 0.25rem); - inset-inline-start: 0; - z-index: 100; background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ border: 1px solid var(--borderColor); border-radius: var(--dp-panel-radius, 0.5rem); - box-shadow: var(--dp-panel-shadow, 0 4px 16px rgba(0, 0, 0, 0.18)); - padding: 1rem; + box-shadow: var(--dp-panel-shadow, 0 4px 16px rgba(0, 0, 0, 18%)); + inset-block-start: calc(100% + 0.25rem); + inset-inline-start: 0; min-width: 20rem; + padding: 1rem; + position: absolute; + z-index: 100; // hidden attribute 控制顯示狀態 &[hidden] { @@ -153,25 +153,25 @@ // ── 月份導覽列 ──────────────────────────────────────────── &__nav { - display: flex; align-items: center; + display: flex; justify-content: space-between; margin-block-end: 0.75rem; } &__nav-btn { - display: inline-flex; align-items: center; - justify-content: center; - width: 2.75rem; - height: 2.75rem; - padding: 0; + background: transparent; border: 1px solid transparent; border-radius: 0.375rem; - background: transparent; color: var(--secondaryTextColor, #374151) /* 專案 token: --secondaryTextColor(variables.scss) */; cursor: pointer; + display: inline-flex; + height: 2.75rem; + justify-content: center; + padding: 0; transition: background-color 0.15s ease; + width: 2.75rem; &:hover { background: var(--backgroundColorLayer1, #f3f4f6) /* 專案 token: --backgroundColorLayer1(variables.scss) */; @@ -184,26 +184,26 @@ } &__month-heading { + flex: 1; font-size: 1rem; font-weight: 600; margin: 0; text-align: center; - flex: 1; } // ── 月曆表格(Grid) ────────────────────────────────────── &__grid { - width: 100%; border-collapse: collapse; table-layout: fixed; + width: 100%; [role="columnheader"] { - text-align: center; + color: var(--mutedTextColor, #6b7280) /* 專案 token: --mutedTextColor(variables.scss) */; font-size: 0.75rem; font-weight: 600; padding-block-end: 0.5rem; - color: var(--mutedTextColor, #6b7280) /* 專案 token: --mutedTextColor(variables.scss) */; + text-align: center; } } @@ -214,18 +214,18 @@ // 確保 NVDA 在 role="grid" 下自動切換至 Focus mode &__cell { - text-align: center; - vertical-align: middle; - height: var(--dp-cell-size, 2.75rem); - padding: 0; + background: transparent; border: 1px solid transparent; border-radius: 50%; - background: transparent; - font-size: 0.875rem; color: var(--textColor, #111827) /* 專案 token: --textColor(variables.scss) */; cursor: pointer; - user-select: none; + font-size: 0.875rem; + height: var(--dp-cell-size, 2.75rem); + padding: 0; + text-align: center; transition: background-color 0.15s ease; + user-select: none; + vertical-align: middle; // 焦點樣式(必須清晰可見,不依賴瀏覽器預設) &:focus { @@ -271,8 +271,9 @@ // 使用 aria-disabled 而非 disabled,保持可聚焦性 &--disabled, &[aria-disabled="true"] { - opacity: var(--dp-disabled-opacity, 0.4); cursor: not-allowed; + opacity: var(--dp-disabled-opacity, 0.4); + // 不加 pointer-events: none,保留 hover 以利 tooltip 提示 } } @@ -280,21 +281,21 @@ // ── 動作列(面板底部) ──────────────────────────────────── &__actions { + border-block-start: 1px solid var(--borderColor); /* 專案 token: --borderColor(variables.scss),深色模式自動切換 */ display: flex; justify-content: flex-end; margin-block-start: 0.75rem; padding-block-start: 0.75rem; - border-block-start: 1px solid var(--borderColor); /* 專案 token: --borderColor(variables.scss),深色模式自動切換 */ } &__close-btn { - padding: 0.375rem 0.875rem; + background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ border: 1px solid var(--borderColor); border-radius: 0.375rem; - background: var(--backgroundColor, #fff); /* 專案 token: --backgroundColor(variables.scss) */ color: var(--secondaryTextColor, #374151) /* 專案 token: --secondaryTextColor(variables.scss) */; - font-size: 0.875rem; cursor: pointer; + font-size: 0.875rem; + padding: 0.375rem 0.875rem; transition: background-color 0.15s ease; &:hover { @@ -310,14 +311,14 @@ // ── 即時回饋(視覺隱藏,僅輔助科技可讀)────────────────── &__feedback { - position: absolute; - width: 1px; + border: 0; + clip: rect(0, 0, 0, 0); height: 1px; - padding: 0; margin: -1px; overflow: hidden; - clip: rect(0, 0, 0, 0); + padding: 0; + position: absolute; white-space: nowrap; - border: 0; + width: 1px; } } diff --git a/assets/css/components/footer.scss b/assets/css/components/footer.scss index a99c31d8..ce90156e 100644 --- a/assets/css/components/footer.scss +++ b/assets/css/components/footer.scss @@ -2,15 +2,16 @@ /* Footer Styles */ .footer { background-color: var(--backgroundColorLayer1); + // color: #FFFFFF; padding: 20px 0; } .footer-content { - display: flex; - justify-content: space-between; align-items: center; + display: flex; flex-wrap: wrap; + justify-content: space-between; text-align: left; } @@ -26,8 +27,8 @@ .footer-legal, .footer-section { flex: 1; - min-width: 250px; margin: 10px 0; + min-width: 250px; p { margin: 5px 0; @@ -37,8 +38,8 @@ .footer-inline-list { display: flex; list-style: none; - padding: 0; margin-bottom: 20px; + padding: 0; } .footer-inline-list-item { @@ -46,28 +47,28 @@ } .footer-support-links { - width: 100%; text-align: center; + width: 100%; } .footer-list { - list-style: none; - padding: 0; display: flex; flex-wrap: wrap; justify-content: flex-start; + list-style: none; + padding: 0; } .footer-list-item { - margin: 5px 0; flex: 0 0 50%; + margin: 5px 0; } .footer-navigation { - margin-top: 20px; display: flex; - justify-content: space-between; flex-wrap: wrap; + justify-content: space-between; + margin-top: 20px; } .footer-heading { @@ -82,14 +83,14 @@ } .visually-hidden { - position: absolute; - width: 1px; + border: 0; + clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; - padding: 0; overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; + padding: 0; + position: absolute; + width: 1px; } /* Responsive Design */ diff --git a/assets/css/components/form.scss b/assets/css/components/form.scss index e234a1b1..1a94a1ca 100644 --- a/assets/css/components/form.scss +++ b/assets/css/components/form.scss @@ -1,26 +1,27 @@ -@import 'list.scss'; +@import 'list'; .fields { - gap: 1.2rem; display: flex; flex-direction: column; + gap: 1.2rem; } .fieldset { - padding: 0; + align-items: start; border: none; - gap: 0.8rem; display: flex; flex-direction: column; - align-items: start; + gap: 0.8rem; + padding: 0; position: relative; &.fieldset-has-error { - .field-label:before { - content: '⚹'; + .field-label::before { color: var(--dangerColor); + content: '⚹'; margin-right: 0.6em; } + .field-description { color: var(--dangerColor); } @@ -38,9 +39,11 @@ .field-description { font-size: var(--description-font-size); letter-spacing: var(--description-letter-spacing); - margin-top: 0; margin-bottom: 0; + margin-top: 0; padding-left: 0; + + // stylelint-disable-next-line scss/at-extend-no-missing-placeholder @extend .list; } @@ -53,12 +56,12 @@ } .field-input-fixes { - display: flex; align-items: center; - width: 100%; background-color: var(--backgroundColorLayer1); border-radius: 0.45rem; + display: flex; overflow: hidden; + width: 100%; .field-input { flex: 1 1 auto; @@ -75,16 +78,16 @@ .field-input-prefix, .field-input-suffix { - padding: 0 0.8rem; font-size: 0.95em; + padding: 0 0.8rem; } } .checkable-wrapper-v, .checkable-wrapper-h { display: flex; - gap: 1em; flex-wrap: wrap; + gap: 1em; width: 100%; } @@ -100,14 +103,14 @@ } .checkable-item { - display: flex; align-items: baseline; - justify-content: stretch; column-gap: 1em; + display: flex; flex-wrap: wrap; + justify-content: stretch; - input[type=radio], - input[type=checkbox] { + input[type="radio"], + input[type="checkbox"] { flex: 0 1 auto; } diff --git a/assets/css/components/header.scss b/assets/css/components/header.scss index c36b7c02..41a8b7ed 100644 --- a/assets/css/components/header.scss +++ b/assets/css/components/header.scss @@ -1,6 +1,7 @@ /* Header Styles */ .headerfordemo { background-color: var(--backgroundColorLayer1); + // color: #FFFFFF; } @@ -20,15 +21,15 @@ } .header-top-container { + align-items: center; display: flex; justify-content: flex-end; - align-items: center; } .header-container { + align-items: center; display: flex; justify-content: space-between; - align-items: center; position: relative; } @@ -41,10 +42,10 @@ } .header-content { - display: flex; - justify-content: flex-end; align-items: center; + display: flex; flex: 1; + justify-content: flex-end; position: relative; } @@ -53,16 +54,16 @@ } .service-name { + cursor: pointer; font-size: 1.2em; margin: 0 20px; - cursor: pointer; position: relative; } .header-navigation { + background-color: var(--backgroundColorLayer1); display: none; position: absolute; - background-color: var(--backgroundColorLayer1); top: 100%; z-index: 1000; } @@ -80,29 +81,29 @@ } .header-actions { - display: flex; align-items: center; + display: flex; } .header-menu-button { - display: none; - font-size: 2em; background: none; border: none; color: var(--textColor); cursor: pointer; + display: none; + font-size: 2em; padding: 10px; } .visually-hidden { - position: absolute; - width: 1px; + border: 0; + clip: rect(0, 0, 0, 0); height: 1px; margin: -1px; - padding: 0; overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; + padding: 0; + position: absolute; + width: 1px; } .small-text { @@ -124,8 +125,8 @@ /* Responsive Design */ @media (max-width: 768px) { .header-container { - flex-direction: row; align-items: center; + flex-direction: row; justify-content: space-between; } @@ -152,21 +153,21 @@ } .header-content.is-visible { - display: flex; background-color: var(--backgroundColorLayer1); + display: flex; + min-width: 200px; padding: 10px; position: absolute; - top: 100%; right: 0; - min-width: 200px; + top: 100%; width: 30%; } .header-menu-button { display: block; - margin-left: auto; - font-size: 2.5em; flex: 0 0 20%; + font-size: 2.5em; + margin-left: auto; text-align: right; } @@ -175,16 +176,16 @@ } .header-additional-links { + align-items: center; display: flex; flex-direction: column; - align-items: center; } .header-actions-row { display: flex; justify-content: center; - width: 100%; padding: 5px 0; + width: 100%; a { margin: 0 10px; diff --git a/assets/css/components/layout.scss b/assets/css/components/layout.scss index a2038c6d..fe86f35e 100644 --- a/assets/css/components/layout.scss +++ b/assets/css/components/layout.scss @@ -18,8 +18,8 @@ body > :first-child { } .width-container { - max-width: 1200px; margin: 0 auto; + max-width: 1200px; padding: 0 20px; } @@ -35,10 +35,10 @@ body > :first-child { .two-col, .three-col { - gap: 2rem; + align-items: start; display: flex; flex-wrap: wrap; - align-items: start; + gap: 2rem; justify-content: space-between; & > * { diff --git a/assets/css/components/list.scss b/assets/css/components/list.scss index a95d565c..5d7ae4cc 100644 --- a/assets/css/components/list.scss +++ b/assets/css/components/list.scss @@ -1,8 +1,8 @@ .list { list-style: disc; + list-style-position: inside; margin: 0; padding: 0 0 0 1em; - list-style-position: inside; &:has(li:only-child) { list-style: none; diff --git a/assets/css/components/modal.scss b/assets/css/components/modal.scss index 38059c9b..05266f0f 100644 --- a/assets/css/components/modal.scss +++ b/assets/css/components/modal.scss @@ -3,16 +3,16 @@ // 背景遮罩採用 dialog::backdrop(瀏覽器原生支援) // ── 變數 ─────────────────────────────────────────────── -$modal-bg: var(--backgroundColor); -$modal-text: var(--textColor); -$modal-border: var(--borderColor); -$modal-backdrop-bg: rgba(0, 0, 0, 0.55); -$modal-shadow: 0 8px 32px rgba(0, 0, 0, 0.18); -$modal-radius: 0.5rem; -$modal-max-width: 640px; -$modal-max-height: 90vh; -$modal-header-bg: var(--backgroundColorLayer1); -$modal-close-size: 2.25rem; +$modal-bg: var(--backgroundColor); +$modal-text: var(--textColor); +$modal-border: var(--borderColor); +$modal-backdrop-bg: rgba(0, 0, 0, 55%); +$modal-shadow: 0 8px 32px rgba(0, 0, 0, 18%); +$modal-radius: 0.5rem; +$modal-max-width: 640px; +$modal-max-height: 90vh; +$modal-header-bg: var(--backgroundColorLayer1); +$modal-close-size: 2.25rem; // ── 動畫 ─────────────────────────────────────────────── @keyframes modal-fade-in { @@ -20,6 +20,7 @@ $modal-close-size: 2.25rem; opacity: 0; transform: translateY(-0.5rem); } + to { opacity: 1; transform: translateY(0); @@ -29,19 +30,19 @@ $modal-close-size: 2.25rem; // ── Dialog 主體 ──────────────────────────────────────── dialog.modal, dialog[id^="modal"] { - // 重設瀏覽器預設 - padding: 0; + background-color: $modal-bg; border: 1px solid $modal-border; border-radius: $modal-radius; - background-color: $modal-bg; - color: $modal-text; box-shadow: $modal-shadow; + color: $modal-text; + max-height: $modal-max-height; + max-width: $modal-max-width; + overflow: hidden; // dialog 本身不捲動,body 區塊捲動 + // 重設瀏覽器預設 + padding: 0; // 尺寸與定位 width: 90vw; - max-width: $modal-max-width; - max-height: $modal-max-height; - overflow: hidden; // dialog 本身不捲動,body 區塊捲動 // dialog 本身設有 tabindex="-1" 以支援程式化聚焦 // 僅對非鍵盤觸發的聚焦隱藏 outline(:focus-visible 保留鍵盤使用者的視覺反饋) @@ -61,8 +62,8 @@ dialog[id^="modal"] { // Backdrop 遮罩(原生 ::backdrop) &::backdrop { - background-color: $modal-backdrop-bg; animation: modal-fade-in 0.2s ease-out; + background-color: $modal-backdrop-bg; @media (prefers-reduced-motion: reduce) { animation: none; @@ -72,40 +73,40 @@ dialog[id^="modal"] { // ── Header ───────────────────────────────────────────── .modal-header { - display: flex; align-items: center; - justify-content: space-between; - gap: 1rem; - padding: 1rem 1.25rem; background-color: $modal-header-bg; border-bottom: 1px solid $modal-border; border-radius: $modal-radius $modal-radius 0 0; + display: flex; flex-shrink: 0; + gap: 1rem; + justify-content: space-between; + padding: 1rem 1.25rem; } .modal-title { - margin: 0; + color: $modal-text; font-size: 1.125rem; font-weight: 600; line-height: 1.4; - color: $modal-text; + margin: 0; } // ── 關閉按鈕(圖示型)────────────────────────────────── .modal-close { - display: inline-flex; align-items: center; - justify-content: center; - flex-shrink: 0; - width: $modal-close-size; - height: $modal-close-size; - padding: 0; + background: transparent; border: 1px solid transparent; border-radius: 0.25rem; - background: transparent; color: var(--mutedTextColor); cursor: pointer; + display: inline-flex; + flex-shrink: 0; + height: $modal-close-size; + justify-content: center; + padding: 0; transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; + width: $modal-close-size; @media (prefers-reduced-motion: reduce) { transition: none; @@ -113,8 +114,8 @@ dialog[id^="modal"] { &:hover { background-color: var(--backgroundColorLayer2); - color: $modal-text; border-color: $modal-border; + color: $modal-text; } // 清晰的 focus indicator(WCAG AA 符合) @@ -131,13 +132,14 @@ dialog[id^="modal"] { // ── Body(可捲動)───────────────────────────────────── .modal-body { - padding: 1.25rem; - overflow-y: auto; - // 扣除 header(約 3.5rem + 1px border)與 footer(約 4rem + 1px border)後的最大高度 - max-height: calc(#{$modal-max-height} - 8rem); color: $modal-text; line-height: 1.6; + // 扣除 header(約 3.5rem + 1px border)與 footer(約 4rem + 1px border)後的最大高度 + max-height: calc(#{$modal-max-height} - 8rem); + overflow-y: auto; + padding: 1.25rem; + p:last-child { margin-bottom: 0; } @@ -145,15 +147,15 @@ dialog[id^="modal"] { // ── Footer ───────────────────────────────────────────── .modal-footer { - display: flex; align-items: center; - justify-content: flex-end; - gap: 0.75rem; - padding: 1rem 1.25rem; - border-top: 1px solid $modal-border; background-color: $modal-bg; border-radius: 0 0 $modal-radius $modal-radius; + border-top: 1px solid $modal-border; + display: flex; flex-shrink: 0; + gap: 0.75rem; + justify-content: flex-end; + padding: 1rem 1.25rem; // Footer 內的按鈕通用 focus indicator button:focus-visible { @@ -166,10 +168,10 @@ dialog[id^="modal"] { @media (max-width: 480px) { dialog.modal, dialog[id^="modal"] { - width: 100%; - max-width: 100%; - margin: auto 0 0; // 靠底部置中,初版不採用 bottom sheet 變體 border-bottom-left-radius: 0; border-bottom-right-radius: 0; + margin: auto 0 0; // 靠底部置中,初版不採用 bottom sheet 變體 + max-width: 100%; + width: 100%; } } diff --git a/assets/css/components/nav.scss b/assets/css/components/nav.scss index 8ece79fb..96e1f869 100644 --- a/assets/css/components/nav.scss +++ b/assets/css/components/nav.scss @@ -1,12 +1,12 @@ .nav-link { - position: relative; - padding: 0.6em 1.4em; display: block; + padding: 0.6em 1.4em; + position: relative; &[aria-current="page"] { - text-decoration: none; background-color: var(--backgroundColorLayer1); color: inherit; font-weight: 700; + text-decoration: none; } } diff --git a/assets/css/components/password-input.scss b/assets/css/components/password-input.scss index 0f1a87c6..1d7f4a71 100644 --- a/assets/css/components/password-input.scss +++ b/assets/css/components/password-input.scss @@ -14,10 +14,10 @@ } &__toggle { - flex-shrink: 0; flex-basis: auto; - margin-top: 0.25rem; + flex-shrink: 0; margin-left: 0; + margin-top: 0.25rem; /* JS 尚未執行前保持隱藏(progressive enhancement) */ &[hidden] { @@ -27,14 +27,14 @@ /* 螢幕閱讀器專用的狀態訊息,視覺上隱藏 */ &__sr-status { - position: absolute; - width: 1px; + border: 0; + clip: rect(0, 0, 0, 0); height: 1px; - padding: 0; margin: -1px; overflow: hidden; - clip: rect(0, 0, 0, 0); + padding: 0; + position: absolute; white-space: nowrap; - border: 0; + width: 1px; } } diff --git a/assets/css/components/search-feedback.scss b/assets/css/components/search-feedback.scss index a150d888..b622d9ed 100644 --- a/assets/css/components/search-feedback.scss +++ b/assets/css/components/search-feedback.scss @@ -7,66 +7,66 @@ // ============================================================================= // --- 狀態顏色變數 --- -$sf-color-loading: var(--secondaryTextColor, #6b7280); -$sf-color-found: var(--primaryColor, #005ea2); +$sf-color-loading: var(--secondaryTextColor, #6b7280); +$sf-color-found: var(--primaryColor, #005ea2); $sf-color-not-found: var(--secondaryTextColor, #6b7280); -$sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token(自動適應暗色模式) +$sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token(自動適應暗色模式) // --- Status Region 核心 --- .search-feedback__status { - min-height: 1.5rem; // 保留空間,避免版面跳動 - padding: 0.5rem 0.75rem; + border-radius: 0.25rem; font-size: 0.9375rem; // 15px line-height: 1.5; - border-radius: 0.25rem; + min-height: 1.5rem; // 保留空間,避免版面跳動 + padding: 0.5rem 0.75rem; transition: opacity 0.2s ease, background-color 0.2s ease; // 初始狀態:不顯示任何視覺效果(內容為空) // 不可用 display:none,否則 AT 會忽略 live region。 // 改用 position:absolute 讓空容器脫離 flex 佈局,不佔 gap 間距。 &:empty { - position: absolute; - padding: 0; min-height: 0; + padding: 0; + position: absolute; } // --loading:搜尋中 &--loading { - color: $sf-color-loading; background-color: var(--backgroundColorLayer1); border-left: 3px solid $sf-color-loading; + color: $sf-color-loading; } // --found:有結果 &--found { - color: $sf-color-found; background-color: var(--backgroundColorLayer2); border-left: 3px solid $sf-color-found; + color: $sf-color-found; } // --not-found:無結果 &--not-found { - color: $sf-color-not-found; background-color: var(--backgroundColorLayer1); border-left: 3px solid $sf-color-not-found; + color: $sf-color-not-found; } // --error:錯誤 // 不可只靠顏色傳達狀態,文字本身已說明錯誤情境 &--error { - color: $sf-color-error; background-color: var(--backgroundColorLayer1); border-left: 3px solid $sf-color-error; + color: $sf-color-error; font-weight: 600; } } // --- Demo 外框 --- .search-feedback-demo { - position: relative; // 供空的 live region(position:absolute)定位 display: flex; flex-direction: column; gap: 1rem; + position: relative; // 供空的 live region(position:absolute)定位 } // --- Demo:輸入群組 --- @@ -77,23 +77,23 @@ $sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token( } .search-feedback-demo__label { + color: var(--textColor); font-size: 0.9375rem; font-weight: 600; - color: var(--textColor); } .search-feedback-demo__input-row { + align-items: flex-start; display: flex; gap: 0.5rem; - align-items: flex-start; } .search-feedback-demo__input { - flex: 1; - padding: 0.5rem 0.75rem; - font-size: 1rem; border: 1px solid var(--borderColor, #d1d5db); border-radius: 0.25rem; + flex: 1; + font-size: 1rem; + padding: 0.5rem 0.75rem; &:focus { outline: 3px solid var(--primaryColor, #005ea2); @@ -103,20 +103,20 @@ $sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token( // --- Demo:結果列表 --- .search-feedback-demo__results { - list-style: none; - margin: 0; - padding: 0; display: flex; flex-direction: column; gap: 0.25rem; + list-style: none; + margin: 0; + padding: 0; } .search-feedback-demo__result-item { - padding: 0.5rem 0.75rem; background-color: var(--backgroundColor, #fff); border: 1px solid var(--borderColor, #e5e7eb); border-radius: 0.25rem; font-size: 0.9375rem; + padding: 0.5rem 0.75rem; &[hidden] { display: none; @@ -127,15 +127,15 @@ $sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token( .search-feedback-demo__controls { border: none; border-top: 1px solid var(--borderColor, #e5e7eb); - padding: 0.75rem 0 0; margin: 0; + padding: 0.75rem 0 0; } .search-feedback-demo__controls-label { - font-size: 0.875rem; color: var(--secondaryTextColor, #6b7280); - padding: 0; + font-size: 0.875rem; margin: 0 0 0.5rem; + padding: 0; } .search-feedback-demo__buttons { @@ -146,8 +146,8 @@ $sf-color-error: var(--dangerColor); // 錯誤狀態使用 design token( // --- 無 JS 提示 --- .search-feedback-demo__noscript { - font-size: 0.875rem; color: var(--secondaryTextColor, #6b7280); + font-size: 0.875rem; font-style: italic; } diff --git a/assets/css/components/skip-to.css b/assets/css/components/skip-to.css index 44044537..0192b061 100644 --- a/assets/css/components/skip-to.css +++ b/assets/css/components/skip-to.css @@ -3,19 +3,19 @@ body:has(skip-to:focus-within) { } skip-to { - position: absolute; + left: 0; + position: absolute; right: 0; top: 0; - left: 0; right: 0; } skip-to .skip-to { - display: block; background: var(--linkColor); color: #fff; - text-decoration: none; - padding: 1em; - line-height: 1; + display: block; font-size: 1em; + line-height: 1; + padding: 1em; + text-decoration: none; } skip-to .skip-to:focus { @@ -24,12 +24,12 @@ skip-to .skip-to:focus { } skip-to .skip-to:not(:focus) { - width: 1px; + border: 0; + clip: rect(0, 0, 0, 0); height: 1px; - padding: 0; margin: -1px; overflow: hidden; - clip: rect(0, 0, 0, 0); + padding: 0; white-space: nowrap; - border: 0; + width: 1px; } \ No newline at end of file diff --git a/assets/css/components/table.scss b/assets/css/components/table.scss index e5607f1f..65b24a40 100644 --- a/assets/css/components/table.scss +++ b/assets/css/components/table.scss @@ -1,22 +1,22 @@ .table { - text-align: left; border-spacing: 0; - width: 100%; margin: 0.8em 0; + text-align: left; + width: 100%; .table-caption { + font-size: 1.4em; font-weight: 600; padding-bottom: 0.4em; - font-size: 1.4em; + text-align: left; } .table-cell, .table-head { + border-bottom: 1px solid var(--borderColor); padding: 0.6em 1em; - } - - .table-caption { - text-align: left; + padding-left: 0; + vertical-align: top; } .table-head { @@ -27,13 +27,6 @@ min-width: 3em; } - .table-head, - .table-cell { - border-bottom: 1px solid var(--borderColor); - padding-left: 0; - vertical-align: top; - } - .table-row:last-of-type .table-cell { border-bottom: 0; } @@ -62,8 +55,8 @@ overflow: auto; .table { - width: max-content; min-width: 100%; + width: max-content; } .table-cell { @@ -72,8 +65,8 @@ } .table.table-separator { - border-radius: 0.4em; border: 1px solid var(--borderColor); + border-radius: 0.4em; .table-caption { margin-bottom: 0.6em; @@ -85,6 +78,7 @@ &:not(:last-of-type) { border-right: 1px solid var(--borderColor); } + // border-radius: 0.2em; } } diff --git a/assets/css/components/tabs.css b/assets/css/components/tabs.css index 1904378a..5b1665ab 100644 --- a/assets/css/components/tabs.css +++ b/assets/css/components/tabs.css @@ -10,23 +10,22 @@ } .tabs { - width: 100%; display: flex; flex-wrap: wrap; + width: 100%; } .tabs-label { - cursor: pointer; background: var(--tabs-header-bg); - color: var(--tabs-header-fontColor); - border-radius: 0.5rem 0.5rem 0 0; border: 2px solid var(--tabs-border); border-bottom: none; - padding: 10px 15px; + border-radius: 0.5rem 0.5rem 0 0; + color: var(--tabs-header-fontColor); + cursor: pointer; float: left; - margin-right: 2px; font: italic 1em; - cursor: pointer; + margin-right: 2px; + padding: 10px 15px; } label:hover { @@ -35,9 +34,9 @@ label:hover { } .tabs-radio:checked+.tabs-label { - font-weight: bold; background: var(--tabs-header-active-bg); color: var(--tabs-header-active-fontColor); + font-weight: bold; } .tabs-radio:checked+.tabs-label+.tabs-content { @@ -49,15 +48,15 @@ label:hover { } .tabs-content { - order: 1; - width: 100%; - float: left; - clear: both; - position: relative; background: var(--tabs-body-bg); - border-radius: 0 10px 10px 10px; border: 2px solid var(--tabs-border); - padding: 1rem; - height: auto; + border-radius: 0 10px 10px; + clear: both; display: none; + float: left; + height: auto; + order: 1; + padding: 1rem; + position: relative; + width: 100%; } \ No newline at end of file diff --git a/assets/css/components/toolbar.scss b/assets/css/components/toolbar.scss index 9a6e0b33..993594b0 100644 --- a/assets/css/components/toolbar.scss +++ b/assets/css/components/toolbar.scss @@ -3,57 +3,54 @@ // 色彩對比需符合 WCAG AA:文字 4.5:1、非文字 UI 元素 3:1 // ── 變數 ─────────────────────────────────────────────── -$toolbar-bg: var(--backgroundColorLayer1); -$toolbar-border: var(--borderColor); -$toolbar-btn-color: var(--textColor); -$toolbar-btn-radius: 0.25rem; -$toolbar-btn-size: 2.75rem; // 最小觸控目標(WCAG 2.5.5 建議 44px = 2.75rem) -$toolbar-gap: 0.25rem; -$toolbar-padding: 0.25rem; +$toolbar-bg: var(--backgroundColorLayer1); +$toolbar-border: var(--borderColor); +$toolbar-btn-color: var(--textColor); +$toolbar-btn-radius: 0.25rem; +$toolbar-btn-size: 2.75rem; // 最小觸控目標(WCAG 2.5.5 建議 44px = 2.75rem) +$toolbar-gap: 0.25rem; +$toolbar-padding: 0.25rem; // Toggle 按下(pressed)狀態:沿用 accordion active 慣例 // 背景 var(--primaryColor)(亮色 #262927、暗色 #ffffff)+ 反色文字 var(--backgroundColor) // 亮色對比:#262927 vs 頁面底色 #fdfdfd ≈ 16:1;文字 #fdfdfd on #262927 ≈ 16:1 // 暗色對比:#ffffff vs 頁面底色 #151615 ≈ 18:1;文字 #151615 on #ffffff ≈ 18:1 -$toolbar-pressed-bg: var(--primaryColor); -$toolbar-pressed-border: var(--primaryColor); -$toolbar-pressed-color: var(--backgroundColor); +$toolbar-pressed-bg: var(--primaryColor); +$toolbar-pressed-border: var(--primaryColor); +$toolbar-pressed-color: var(--backgroundColor); // ── Toolbar 容器 ─────────────────────────────────────── .toolbar { - display: inline-flex; - flex-direction: row; align-items: center; - gap: $toolbar-gap; - padding: $toolbar-padding; background-color: $toolbar-bg; border: 1px solid $toolbar-border; border-radius: 0.375rem; - position: relative; // 供子選單 absolute 定位基準 + display: inline-flex; + flex-flow: row wrap; // 允許換行(空間不足時) - flex-wrap: wrap; + gap: $toolbar-gap; + padding: $toolbar-padding; + position: relative; // 供子選單 absolute 定位基準 } // ── 按鈕基礎樣式 ─────────────────────────────────────── .toolbar__button { - display: inline-flex; align-items: center; - justify-content: center; - gap: 0.375rem; - - // 固定最小尺寸(觸控目標) - min-width: $toolbar-btn-size; - min-height: $toolbar-btn-size; - padding: 0.25rem 0.5rem; - + background: transparent; border: 1px solid transparent; border-radius: $toolbar-btn-radius; - background: transparent; color: $toolbar-btn-color; cursor: pointer; + display: inline-flex; + gap: 0.375rem; + justify-content: center; line-height: 1; + min-height: $toolbar-btn-size; + // 固定最小尺寸(觸控目標) + min-width: $toolbar-btn-size; + padding: 0.25rem 0.5rem; transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease; @media (prefers-reduced-motion: reduce) { @@ -76,6 +73,7 @@ $toolbar-pressed-color: var(--backgroundColor); &:focus-visible { outline: 3px solid var(--linkColor, #0052cc); outline-offset: 2px; + // 確保 focus ring 在按下狀態仍清楚可見 z-index: 1; } @@ -98,8 +96,9 @@ $toolbar-pressed-color: var(--backgroundColor); // ── Disabled 狀態(aria-disabled,非 HTML disabled)── // 視覺降低 opacity + 禁止游標;焦點仍可到達(roving tabindex 維持) &[aria-disabled="true"] { - opacity: 0.45; cursor: not-allowed; + opacity: 0.45; + // 不改變 pointer-events,讓 JS 攔截 click(而非 CSS 阻擋) } } @@ -127,15 +126,15 @@ $toolbar-pressed-color: var(--backgroundColor); // ── Separator ───────────────────────────────────────── // role="separator" + aria-orientation="vertical" .toolbar__separator { - display: inline-block; align-self: stretch; // 撐滿容器高度 - width: 1px; + background-color: currentcolor; + display: inline-block; + flex-shrink: 0; + margin: 0.25rem 0.125rem; min-height: 1.25rem; - background-color: currentColor; opacity: 0.2; - margin: 0.25rem 0.125rem; pointer-events: none; - flex-shrink: 0; + width: 1px; } // ── 示意選單(Menu Button 的 popup)────────────────── @@ -143,17 +142,17 @@ $toolbar-pressed-color: var(--backgroundColor); // 定位於 toolbar 容器下方(top: 100%),避免遮蔽 toolbar 內可聚焦元素 // 符合 SC 2.4.11 / SC 2.4.12 .toolbar__menu { - position: absolute; - top: calc(100% + 0.25rem); // toolbar 下方,留 4px 間距 - right: 0; // 靠右對齊(插入按鈕在最右側) - list-style: none; - margin: 0; - padding: 0.25rem 0; background-color: var(--backgroundColor); border: 1px solid var(--borderColor); border-radius: 0.25rem; - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); + box-shadow: 0 4px 16px rgba(0, 0, 0, 12%); + list-style: none; + margin: 0; min-width: 8rem; + padding: 0.25rem 0; + position: absolute; + right: 0; // 靠右對齊(插入按鈕在最右側) + top: calc(100% + 0.25rem); // toolbar 下方,留 4px 間距 z-index: 100; &[hidden] { @@ -161,10 +160,10 @@ $toolbar-pressed-color: var(--backgroundColor); } [role="menuitem"] { + color: var(--textColor); + cursor: pointer; display: block; padding: 0.5rem 1rem; - cursor: pointer; - color: var(--textColor); white-space: nowrap; &:hover, diff --git a/assets/css/components/warning-text.scss b/assets/css/components/warning-text.scss index 073a6252..ae5319b5 100644 --- a/assets/css/components/warning-text.scss +++ b/assets/css/components/warning-text.scss @@ -1,15 +1,15 @@ .warning-text { + box-shadow: inset 0.4em 0 0 0 var(--warningColor); padding: 0.8em 1.2em 0.8em 1.6em; position: relative; - box-shadow: inset 0.4em 0 0 0 var(--warningColor); - &:before { - content: ''; - border-radius: 0.2em; + &::before { background: var(--warningColor); - position: absolute; - top: 0; left: 0; right: 0; bottom: 0; + border-radius: 0.2em; + content: ''; + inset: 0; opacity: 0.1; + position: absolute; z-index: -1; } diff --git a/assets/css/guide.scss b/assets/css/guide.scss index 6b094c9c..372505da 100644 --- a/assets/css/guide.scss +++ b/assets/css/guide.scss @@ -1,7 +1,7 @@ -@import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@400&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=Inconsolata:wght@400&display=swap'; code, kbd { - font-family: 'Inconsolata', monospace; + font-family: Inconsolata, monospace; } summary.cursor-help { @@ -20,16 +20,16 @@ summary.cursor-help { .logo-svg { height: 2em; - width: 2em; margin-right: 1em; + width: 2em; } .logo { - color: inherit; align-items: center; - display: inline-flex; background-color: var(--backgroundColor); border-color: var(--borderColor); + color: inherit; + display: inline-flex; &:not(:hover) path, &:not(:hover) circle { fill: var(--borderColor); @@ -42,48 +42,48 @@ summary.cursor-help { .circle { transition-delay: 0.3s; } + .triangle { transition-delay: 0.6s; } } .sr-only { - position: absolute; - width: 1px; + border: 0; + clip: rect(0,0,0,0); + clip-path: inset(50%); height: 1px; - padding: 0; overflow: hidden; - clip: rect(0,0,0,0); + padding: 0; + position: absolute; white-space: nowrap; - -webkit-clip-path: inset(50%); - clip-path: inset(50%); - border: 0; + width: 1px; } .highlight { - margin: 0; line-height: 1.6; + margin: 0; pre { margin: 0; code { - padding: 0; font-size: 1em; + padding: 0; } } } /* code-example / live-example 程式碼區塊:margin 與行距 */ .display-code-example pre { - margin-top: 0; - margin-bottom: 0; line-height: 1.6; + margin-bottom: 0; + margin-top: 0; } .display-code-example pre code { - line-height: inherit; font-size: 1em; + line-height: inherit; } .tabular-nums { @@ -95,8 +95,8 @@ summary.cursor-help { } svg { - max-width: 100%; height: auto; + max-width: 100%; } .maxh { @@ -105,17 +105,17 @@ svg { } .hero-h1 { + font-size: unquote("max(min(1.8em, 6vw), 2cqw)"); left: 50%; - top: 50%; - transform: translate(-50%, -50%); - line-height: 1em; letter-spacing: 0.04em; + line-height: 1em; + position: absolute; text-shadow: 0.1 0.1em var(--backgroundColor) 0.1 -0.1em var(--backgroundColor) -0.1 0.1em var(--backgroundColor) -0.1 -0.1em var(--backgroundColor); - font-size: unquote("max(min(1.8em, 6vw), 2cqw)"); + top: 50%; + transform: translate(-50%, -50%); white-space: nowrap; - position: absolute; } diff --git a/assets/css/lang/ja.css b/assets/css/lang/ja.css index 5a8aad34..90a1bc52 100644 --- a/assets/css/lang/ja.css +++ b/assets/css/lang/ja.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;600;700&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;600;700&display=swap'; [lang^="ja"] { font-family: helvetica, 'Noto Sans JP', system-ui, sans-serif; diff --git a/assets/css/lang/th.css b/assets/css/lang/th.css index a50d85ad..7ee29620 100644 --- a/assets/css/lang/th.css +++ b/assets/css/lang/th.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@400;600;700&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@400;600;700&display=swap'; [lang^="th"] { font-family: helvetica, 'Noto Sans Thai', system-ui, sans-serif; diff --git a/assets/css/lang/vi.css b/assets/css/lang/vi.css index 4423fb16..019a5ca8 100644 --- a/assets/css/lang/vi.css +++ b/assets/css/lang/vi.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=inter:wght@400;600;700&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=inter:wght@400;600;700&display=swap'; [lang^="vi"] { font-family: inter, system-ui, sans-serif; diff --git a/assets/css/lang/zh.css b/assets/css/lang/zh.css index 3c9c25ed..2d582522 100644 --- a/assets/css/lang/zh.css +++ b/assets/css/lang/zh.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;600;700&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;600;700&display=swap'; [lang^="zh"] { font-family: helvetica, 'Noto Sans TC', system-ui, sans-serif; diff --git a/assets/css/main.scss b/assets/css/main.scss index 726a4fd6..c3be3d17 100644 --- a/assets/css/main.scss +++ b/assets/css/main.scss @@ -1,12 +1,12 @@ -@import "variables"; //背景黑底設定 +@import "variables"; // 背景黑底設定 @import "reset"; @import "tachyons"; @import "color"; @import "typography"; -@import "components/footer.scss"; -@import "components/header.scss"; +@import "components/footer"; +@import "components/header"; @import "components/ctas"; -@import "components/skip-to"; //首頁 "跳至內容區字樣" 消失 +@import "components/skip-to"; // 首頁 "跳至內容區字樣" 消失 @import "components/warning-text"; @import "components/form"; @import "components/table"; @@ -30,8 +30,8 @@ body, button, textarea, input { - font-weight: 400; color: var(--textColor); + font-weight: 400; } u { @@ -39,8 +39,8 @@ u { } hr { - border-style: solid; border-bottom: 0; + border-style: solid; } input:not([type]), @@ -50,29 +50,29 @@ input[type="tel"], input[type="url"], input[type="password"], textarea { - display: block; - width: 100%; - padding: 0.4em; + background-color: var(--backgroundColor); border: 1px solid var(--borderColor); - box-sizing: border-box; border-radius: 0.45rem; - background-color: var(--backgroundColor); + box-sizing: border-box; color: var(--textColor); + display: block; + padding: 0.4em; + width: 100%; } select { - padding: 0.4em; + background-color: var(--backgroundColor); border: 1px solid var(--borderColor); - box-sizing: border-box; border-radius: 0.45rem; - background-color: var(--backgroundColor); + box-sizing: border-box; color: var(--textColor); + padding: 0.4em; } code { - font-size: 0.9em; - border-radius: 1em; background-color: var(--backgroundColorLayer1); + border-radius: 1em; + font-size: 0.9em; padding: 0.1em 0.4em; } diff --git a/assets/css/typography.scss b/assets/css/typography.scss index c338d43f..6f83068e 100644 --- a/assets/css/typography.scss +++ b/assets/css/typography.scss @@ -3,44 +3,40 @@ :root { --body-line-height: 1.7em; --body-font-size: #{px-to-rem(16px)}; - --description-font-size: #{px-to-rem(14px)}; --description-font-weight: 400; --description-letter-spacing: 0.04em; - --paragraph-font-size: #{px-to-rem(18px)}; --paragraph-width: 35em; - --h6-font-size: #{px-to-rem(18px)}; --h6-font-weight: 700; - --h5-font-size: #{px-to-rem(20px)}; --h5-font-weight: 400; - --h4-font-size: #{px-to-rem(24px)}; --h4-font-weight: 600; - --h3-font-size: #{px-to-rem(28px)}; --h3-font-weight: 600; - --h2-font-size: #{px-to-rem(32px)}; --h2-font-weight: 600; - --h1-font-size: #{px-to-rem(36px)}; --h1-font-weight: 600; &:lang(zh) { --body-font-family: helvetica, 'Noto Sans TC', system-ui, sans-serif; } + &:lang(en) { --body-font-family: helvetica, system-ui, sans-serif; } + &:lang(ja) { --body-font-family: helvetica, 'Noto Sans JP', system-ui, sans-serif; } + &:lang(th) { --body-font-family: helvetica, 'Noto Sans Thai', system-ui, sans-serif; } + &:lang(vi) { --body-font-family: inter, system-ui, sans-serif; } @@ -61,9 +57,9 @@ b, strong { } mark { - color: var(--textColor); background: none; box-shadow: inset 0 -0.6em var(--highlightColor); + color: var(--textColor); padding: 0 0.1em; } @@ -73,7 +69,7 @@ mark { :lang(en, vi) { --body-line-height: 1.45em; - --body-font-family: Helvetica, Arial, sans-serif; + --body-font-family: helvetica, arial, sans-serif; --description-letter-spacing: 0.01em; } @@ -99,13 +95,13 @@ body, a, button, input, textarea, select { } body { - line-height: var(--body-line-height); font-size: var(--body-font-size); + line-height: var(--body-line-height); } p { - line-height: var(--body-line-height); font-size: var(--paragraph-font-size); + line-height: var(--body-line-height); } .desc { diff --git a/assets/css/variables.scss b/assets/css/variables.scss index 0f214305..4d421a4e 100644 --- a/assets/css/variables.scss +++ b/assets/css/variables.scss @@ -9,9 +9,9 @@ --borderColor: #ccc; --primaryColor: #262927; --dangerColor: #CC3100; - --warningColor: #ff6600; - --highlightColor: rgba(255, 255, 0, 0.8); - --hoverOverlay: rgba(0, 0, 0, 0.05); + --warningColor: #f60; + --highlightColor: rgba(255, 255, 0, 80%); + --hoverOverlay: rgba(0, 0, 0, 5%); } @media (prefers-color-scheme: dark) { @@ -24,11 +24,11 @@ --backgroundColorLayer2: #292928; --linkColor: #2a8be5; --borderColor: #414141; - --primaryColor: #ffffff; + --primaryColor: #fff; --dangerColor: #ff7f7f; - --warningColor: #ff6600; - --highlightColor: rgba(168, 168, 0, 0.6); - --hoverOverlay: rgba(255, 255, 255, 0.08); + --warningColor: #f60; + --highlightColor: rgba(168, 168, 0, 60%); + --hoverOverlay: rgba(255, 255, 255, 8%); } } @@ -39,8 +39,8 @@ body, .plain { } .inverted { - color: var(--backgroundColor); background-color: var(--textColor); + color: var(--backgroundColor); } .bg-layer1 { background-color: var(--backgroundColorLayer1) }