From 1b1f88cf764dc9698aba4d99572ea5d01b5a6002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 16 Oct 2025 04:32:26 +0200 Subject: [PATCH] Add 98.css --- bun.lock | 16 + packages/webapp/package.json | 2 + packages/webapp/public/98.css/.editorconfig | 18 + .../98.css/.github/workflows/npm-publish.yml | 23 + packages/webapp/public/98.css/LICENSE | 7 + packages/webapp/public/98.css/README.md | 76 ++ packages/webapp/public/98.css/build.js | 81 ++ packages/webapp/public/98.css/docs/docs.css | 152 +++ packages/webapp/public/98.css/docs/icon.png | Bin 0 -> 209 bytes .../webapp/public/98.css/docs/index.html.ejs | 1129 +++++++++++++++++ packages/webapp/public/98.css/docs/vs.css | 67 + packages/webapp/public/98.css/docs/window.png | Bin 0 -> 3411 bytes packages/webapp/public/98.css/docs/zoom.png | Bin 0 -> 4148 bytes .../98.css/fonts/converted/ms_sans_serif.woff | Bin 0 -> 8540 bytes .../fonts/converted/ms_sans_serif.woff2 | Bin 0 -> 6508 bytes .../fonts/converted/ms_sans_serif_bold.woff | Bin 0 -> 8304 bytes .../fonts/converted/ms_sans_serif_bold.woff2 | Bin 0 -> 6264 bytes .../ms-sans-serif-bold/MS Sans Serif Bold.ttf | Bin 0 -> 12256 bytes .../fonts/src/ms-sans-serif-bold/license.txt | 4 + .../fonts/src/ms-sans-serif-bold/readme.txt | 26 + .../fonts/src/ms-sans-serif/MS Sans Serif.ttf | Bin 0 -> 14280 bytes .../fonts/src/ms-sans-serif/license.txt | 4 + .../98.css/fonts/src/ms-sans-serif/readme.txt | 26 + .../public/98.css/icon/button-down-active.svg | 5 + .../webapp/public/98.css/icon/button-down.svg | 8 + .../webapp/public/98.css/icon/button-left.svg | 8 + .../public/98.css/icon/button-right.svg | 8 + .../webapp/public/98.css/icon/button-up.svg | 8 + .../public/98.css/icon/checkmark-disabled.svg | 3 + .../webapp/public/98.css/icon/checkmark.svg | 3 + packages/webapp/public/98.css/icon/close.svg | 3 + .../public/98.css/icon/groupbox-border.svg | 4 + packages/webapp/public/98.css/icon/help.svg | 8 + .../98.css/icon/indicator-horizontal.svg | 6 + .../icon/indicator-rectangle-horizontal.svg | 6 + .../public/98.css/icon/maximize-disabled.svg | 4 + .../webapp/public/98.css/icon/maximize.svg | 3 + .../webapp/public/98.css/icon/minimize.svg | 3 + .../98.css/icon/radio-border-disabled.svg | 7 + .../public/98.css/icon/radio-border.svg | 8 + .../public/98.css/icon/radio-dot-disabled.svg | 3 + .../webapp/public/98.css/icon/radio-dot.svg | 3 + .../webapp/public/98.css/icon/restore.svg | 10 + .../98.css/icon/scrollbar-background.svg | 4 + .../98.css/icon/sunken-panel-border.svg | 10 + packages/webapp/public/98.css/now.json | 4 + packages/webapp/public/98.css/package.json | 45 + packages/webapp/public/98.css/server.js | 16 + packages/webapp/public/98.css/style.css | 994 +++++++++++++++ packages/webapp/src/routes/__root.tsx | 19 + 50 files changed, 2834 insertions(+) create mode 100644 packages/webapp/public/98.css/.editorconfig create mode 100644 packages/webapp/public/98.css/.github/workflows/npm-publish.yml create mode 100644 packages/webapp/public/98.css/LICENSE create mode 100644 packages/webapp/public/98.css/README.md create mode 100644 packages/webapp/public/98.css/build.js create mode 100644 packages/webapp/public/98.css/docs/docs.css create mode 100644 packages/webapp/public/98.css/docs/icon.png create mode 100644 packages/webapp/public/98.css/docs/index.html.ejs create mode 100644 packages/webapp/public/98.css/docs/vs.css create mode 100644 packages/webapp/public/98.css/docs/window.png create mode 100644 packages/webapp/public/98.css/docs/zoom.png create mode 100644 packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff create mode 100644 packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff2 create mode 100644 packages/webapp/public/98.css/fonts/converted/ms_sans_serif_bold.woff create mode 100644 packages/webapp/public/98.css/fonts/converted/ms_sans_serif_bold.woff2 create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif-bold/MS Sans Serif Bold.ttf create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif-bold/license.txt create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif-bold/readme.txt create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif/MS Sans Serif.ttf create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif/license.txt create mode 100644 packages/webapp/public/98.css/fonts/src/ms-sans-serif/readme.txt create mode 100644 packages/webapp/public/98.css/icon/button-down-active.svg create mode 100644 packages/webapp/public/98.css/icon/button-down.svg create mode 100644 packages/webapp/public/98.css/icon/button-left.svg create mode 100644 packages/webapp/public/98.css/icon/button-right.svg create mode 100644 packages/webapp/public/98.css/icon/button-up.svg create mode 100644 packages/webapp/public/98.css/icon/checkmark-disabled.svg create mode 100644 packages/webapp/public/98.css/icon/checkmark.svg create mode 100644 packages/webapp/public/98.css/icon/close.svg create mode 100644 packages/webapp/public/98.css/icon/groupbox-border.svg create mode 100644 packages/webapp/public/98.css/icon/help.svg create mode 100644 packages/webapp/public/98.css/icon/indicator-horizontal.svg create mode 100644 packages/webapp/public/98.css/icon/indicator-rectangle-horizontal.svg create mode 100644 packages/webapp/public/98.css/icon/maximize-disabled.svg create mode 100644 packages/webapp/public/98.css/icon/maximize.svg create mode 100644 packages/webapp/public/98.css/icon/minimize.svg create mode 100644 packages/webapp/public/98.css/icon/radio-border-disabled.svg create mode 100644 packages/webapp/public/98.css/icon/radio-border.svg create mode 100644 packages/webapp/public/98.css/icon/radio-dot-disabled.svg create mode 100644 packages/webapp/public/98.css/icon/radio-dot.svg create mode 100644 packages/webapp/public/98.css/icon/restore.svg create mode 100644 packages/webapp/public/98.css/icon/scrollbar-background.svg create mode 100644 packages/webapp/public/98.css/icon/sunken-panel-border.svg create mode 100644 packages/webapp/public/98.css/now.json create mode 100644 packages/webapp/public/98.css/package.json create mode 100644 packages/webapp/public/98.css/server.js create mode 100644 packages/webapp/public/98.css/style.css diff --git a/bun.lock b/bun.lock index e127305..2968c36 100644 --- a/bun.lock +++ b/bun.lock @@ -47,6 +47,7 @@ "packages/webapp": { "name": "@website/webapp", "dependencies": { + "98.css": "^0.1.21", "@effect/platform": "^0.92.0", "@effect/platform-browser": "^0.72.0", "@effect/rpc": "^0.71.0", @@ -66,6 +67,7 @@ "react-dom": "^19.1.1", "react-i18next": "^16.0.1", "react-icons": "^5.5.0", + "react-shadow": "^20.6.0", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.13", }, @@ -84,6 +86,8 @@ }, }, "packages": { + "98.css": ["98.css@0.1.21", "", {}, "sha512-ddk5qtUWyapM0Bzd5jwGExoE5fdSEGrP+F5VbYjyZLf2c9UVmn6w2NPTvCsoD4BWdGsjdLjlkQGhWwWTJcYQJQ=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/compat-data": ["@babel/compat-data@7.28.4", "", {}, "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw=="], @@ -738,6 +742,8 @@ "html-parse-stringify": ["html-parse-stringify@3.0.1", "", { "dependencies": { "void-elements": "3.1.0" } }, "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg=="], + "humps": ["humps@2.0.1", "", {}, "sha512-E0eIbrFWUhwfXJmsbdjRQFQPrl5pTEoKlz163j1mTqqUnU9PgR4AgB8AIITzuB3vLBdxZXyZ9TDIrwB2OASz4g=="], + "i18next": ["i18next@25.6.0", "", { "dependencies": { "@babel/runtime": "^7.27.6" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw=="], "i18next-browser-languagedetector": ["i18next-browser-languagedetector@8.2.0", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g=="], @@ -812,6 +818,8 @@ "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "lucide-react": ["lucide-react@0.545.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw=="], @@ -854,6 +862,8 @@ "npm-sort": ["npm-sort@0.0.4", "", { "bin": { "npm-sort": "./index.js" } }, "sha512-S5Id/3Jvr7Cf/QnWjRteprngERCBhhEFOM+wMhUrAYP060/HUBC1aL5GoXS3xITlgacJCWaSmP4HQaAt91nNYQ=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -880,6 +890,8 @@ "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], @@ -896,8 +908,12 @@ "react-icons": ["react-icons@5.5.0", "", { "peerDependencies": { "react": "*" } }, "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw=="], + "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], + "react-shadow": ["react-shadow@20.6.0", "", { "dependencies": { "humps": "^2.0.1" }, "peerDependencies": { "prop-types": "^15.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-kY+w4OMNZ8Nj9YI9eiTgvvJ/wYO7XyX1D/LYhvwQZv5vw69iCiDtGB0BX/2U8gLUuZAMN+x/7rHJKqHh8wXFHQ=="], + "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="], diff --git a/packages/webapp/package.json b/packages/webapp/package.json index e8d8170..8958607 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -14,6 +14,7 @@ "clean:modules": "rm -rf node_modules" }, "dependencies": { + "98.css": "^0.1.21", "@effect/platform": "^0.92.0", "@effect/platform-browser": "^0.72.0", "@effect/rpc": "^0.71.0", @@ -33,6 +34,7 @@ "react-dom": "^19.1.1", "react-i18next": "^16.0.1", "react-icons": "^5.5.0", + "react-shadow": "^20.6.0", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.13" }, diff --git a/packages/webapp/public/98.css/.editorconfig b/packages/webapp/public/98.css/.editorconfig new file mode 100644 index 0000000..07552cf --- /dev/null +++ b/packages/webapp/public/98.css/.editorconfig @@ -0,0 +1,18 @@ +# https://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 80 +trim_trailing_whitespace = true + +[*.md] +max_line_length = 0 +trim_trailing_whitespace = false + +[COMMIT_EDITMSG] +max_line_length = 0 diff --git a/packages/webapp/public/98.css/.github/workflows/npm-publish.yml b/packages/webapp/public/98.css/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..17a83f5 --- /dev/null +++ b/packages/webapp/public/98.css/.github/workflows/npm-publish.yml @@ -0,0 +1,23 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages + +name: Publish to NPM + +on: + workflow_dispatch: + release: + types: [published] + +jobs: + publish-npm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + - run: npm ci + - run: npm run release + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/packages/webapp/public/98.css/LICENSE b/packages/webapp/public/98.css/LICENSE new file mode 100644 index 0000000..55b4959 --- /dev/null +++ b/packages/webapp/public/98.css/LICENSE @@ -0,0 +1,7 @@ +Copyright 2020 Jordan Scales + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/webapp/public/98.css/README.md b/packages/webapp/public/98.css/README.md new file mode 100644 index 0000000..3fa4de2 --- /dev/null +++ b/packages/webapp/public/98.css/README.md @@ -0,0 +1,76 @@ +## 98.css + +[![npm](https://98badges.now.sh/api/version)](http://npm.im/98.css) +[![gzip size](https://98badges.now.sh/api/size)](https://unpkg.com/98.css) + +A design system for building faithful recreations of old UIs. + +a screenshot of a window with the title 'My First VB4 Program' and two buttons OK and Cancel, styled like a Windows 98 dialog a magnified view showing pixel-perfect borders on a scrollbar and button element + +98.css is a CSS file that takes semantic HTML and makes it look pretty. It does not ship with any JavaScript, so it is compatible with your frontend framework of choice. + +Be sure to check out [XP.css](https://botoxparty.github.io/XP.css/) and [7.css](https://khang-nd.github.io/7.css/) as well. + +### Installation / Usage + +The easiest way to use 98.css is to import it from [unpkg](https://unpkg.com/). + +```html + + + + 98.css example + + + + + +
+
+
+ My First VB4 Program +
+
+
+

Hello, world!

+
+
+ + +``` + +Alternatively, you can grab 98.css for [the releases page](https://github.com/jdan/98.css/releases) or [npm](https://www.npmjs.com/package/98.css). + +``` +npm install 98.css +``` + +Here is an example of [98.css being used with React](https://codesandbox.io/s/objective-chandrasekhar-t5t6h?file=/src/index.js), and [an example with vanilla JavaScript](https://codesandbox.io/s/late-sound-miqho?file=/index.html). + +Refer to the [documentation page](https://jdan.github.io/98.css/) for specific instructions on this library's components. + +### Developing + +First, run `npm install`. + +[`style.css`](https://github.com/jdan/98.css/blob/main/style.css) is where everything happens. + +You can use `npm start` to start a development environment that will watch for file changes and rebuild 98.css, reloading your browser in the process. + +You can run a build manually with `npm run build`. This will write to the `dist/` directory. + +### Issues, Contributing, etc. + +Refer to [the GitHub issues page](https://github.com/jdan/98.css/issues) to see bugs in my CSS or report new ones. I'd really like to see your pull requests (especially those new to open-source!) and will happily provide code review. 98.css is a fun, silly project and I'd like to make it a fun place to build your open-source muscle. + +Thank you for checking my little project out, I hope it brought you some joy today. Consider [starring/following along on GitHub](https://github.com/jdan/98.css/stargazers) and maybe subscribing to more fun things on [my twitter](https://twitter.com/jdan). 👋 + +### Publishing + +Building the docs site: `npm run deploy:docs` + +Publishing to npm: `npm run release` + +### License + +[MIT](https://github.com/jdan/98.css/blob/main/LICENSE) diff --git a/packages/webapp/public/98.css/build.js b/packages/webapp/public/98.css/build.js new file mode 100644 index 0000000..3e4bbf0 --- /dev/null +++ b/packages/webapp/public/98.css/build.js @@ -0,0 +1,81 @@ +#!/usr/bin/env node +const dedent = require("dedent"); +const ejs = require("ejs"); +const fs = require("fs"); +const glob = require("glob"); +const hljs = require("highlight.js"); +const mkdirp = require("mkdirp"); +const path = require("path"); +const postcss = require("postcss"); + +const { homepage, version } = require("./package.json"); + +function buildCSS() { + const input = + `/*! 98.css v${version} - ${homepage} */\n` + fs.readFileSync("style.css"); + + return postcss() + .use(require("postcss-inline-svg")) + .use(require("postcss-css-variables")) + .use(require("postcss-calc")) + .use(require("postcss-copy")({ dest: "dist", template: "[name].[ext]" })) + .use(require("cssnano")) + .process(input, { + from: "style.css", + to: "dist/98.css", + map: { inline: false }, + }) + .then((result) => { + mkdirp.sync("dist"); + fs.writeFileSync("dist/98.css", result.css); + fs.writeFileSync("dist/98.css.map", result.map.toString()); + }); +} + +function buildDocs() { + let id = 0; + function getNewId() { + return ++id; + } + function getCurrentId() { + return id; + } + + const template = fs.readFileSync("docs/index.html.ejs", "utf-8"); + function example(code) { + const magicBrackets = /\[\[(.*)\]\]/g; + const dedented = dedent(code); + const inline = dedented.replace(magicBrackets, "$1"); + const escaped = hljs.highlight("html", dedented.replace(magicBrackets, "")) + .value; + + return `
+ ${inline} +
+ Show code +
${escaped}
+
+
`; + } + + glob("docs/*", (err, files) => { + if (!err) { + files.forEach((srcFile) => + fs.copyFileSync(srcFile, path.join("dist", path.basename(srcFile))) + ); + } else throw "error globbing dist directory."; + }); + fs.writeFileSync( + path.join(__dirname, "/dist/index.html"), + ejs.render(template, { getNewId, getCurrentId, example }) + ); +} + +function build() { + buildCSS() + .then(buildDocs) + .catch((err) => console.log(err)); +} +module.exports = build; + +build(); diff --git a/packages/webapp/public/98.css/docs/docs.css b/packages/webapp/public/98.css/docs/docs.css new file mode 100644 index 0000000..a38ce5b --- /dev/null +++ b/packages/webapp/public/98.css/docs/docs.css @@ -0,0 +1,152 @@ +body { + margin: 0; + padding: 0; + background: #c0c0c0; +} + +main { + width: 65rem; + margin-left: 240px; + margin-bottom: 60px; +} + +aside { + width: 200px; + position: fixed; + top: 0; + bottom: 0; + padding: 8px; + display: flex; + align-items: stretch; +} + +aside .tree-view { + width: 100%; + /* TODO: Move scrollbar into the recessed region? */ + overflow-y: scroll; +} + +h1 { + margin: 12px 0; +} + +hr { + margin: 0; + border: none; + width: 400px; + height: 1px; + opacity: 0.5; + background: linear-gradient( + to right, + red 20%, + yellow 20%, + yellow 36%, + green 36%, + green 60%, + blue 60%, + blue 100% + ); +} + +h2 { + margin-bottom: 12px; +} + +h3 { + font-size: 1.6rem; +} + +h3, +h4 { + /* Swap the margin for a top-padding so linking to this section + results in a better scroll position */ + padding-top: 20px; + margin-top: 0; + display: block; + flex: 0 0 180px; +} + +p { + max-width: 50rem; + line-height: 1.5; +} + +.component { + display: flex; + margin-top: 24px; +} + +blockquote { + margin: 0 0 20px; + padding: 20px; + background: #dfdfdf; +} + +blockquote footer { + margin: 12px 0 0 12px; +} + +.example { + margin: 16px 0; + padding: 12px 24px; + border-left: 1px solid #808080; +} + +details { + margin-top: 12px; +} + +summary { + user-select: none; + cursor: pointer; + display: inline; +} + +details[open] summary { + margin-bottom: 8px; +} + +button.focused { + outline: 1px dotted #000000; + outline-offset: -4px; +} + +button.active { + box-shadow: inset -1px -1px #ffffff, inset 1px 1px #0a0a0a, + inset -2px -2px #dfdfdf, inset 2px 2px #808080; +} + +@media (max-width: 480px) { + aside { + display: none; + } + + main { + box-sizing: border-box; + width: 100%; + margin: 0; + padding: 16px; + } + + hr { + width: 100%; + } + + p { + width: 100%; + } + + h3, + h4 { + flex: 0; + } + + .component { + display: block; + margin-top: 24px; + } + + pre { + overflow-x: scroll; + } +} diff --git a/packages/webapp/public/98.css/docs/icon.png b/packages/webapp/public/98.css/docs/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a14abdaa58c0b41ae5a6e014d4a8fed7674e30 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBewwF?V@L(#-N^@e4=8ZB?my;OA{?G zR@R}VoMxB2FHe_v$o{Xu+2>9h;E$=0mgX4C4)lJ0`3Xw|jn&^JScnUsA#qaiEP1p00i_>zopr00s_3 A*Z=?k literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/docs/index.html.ejs b/packages/webapp/public/98.css/docs/index.html.ejs new file mode 100644 index 0000000..442af08 --- /dev/null +++ b/packages/webapp/public/98.css/docs/index.html.ejs @@ -0,0 +1,1129 @@ + + + + 98.css - A design system for building faithful recreations of old UIs + + + + + + + + + + + + + + + + +
+

98.css

+
+

A design system for building faithful recreations of old UIs.

+ +

+ + npm + + + gzip size + +

+ +

Intro

+

+ 98.css is a CSS library for building interfaces that look like Windows 98. + See more on GitHub. +

+ +
+
+
+ My First VB4 Program +
+ +
+ + + +
+
+
+

Hello, world!

+
+ + +
+
+
+ +

+ This library relies on the usage of semantic HTML. To make a button, you'll need + to use a <button>. Input elements require labels. Icon buttons rely on + aria-label. This page will guide you through that process, but accessibility is a primary + goal of this project. +

+ +

+ You can override many of the styles of your elements while maintaining the appearance provided by + this library. Need more padding on your buttons? Go for it. Need to add some color to your input labels? + Be our guest. +

+ +

+ This library does not contain any JavaScript, it merely styles your HTML with some CSS. + This means 98.css is compatible with your frontend framework of choice. +

+ +

+ Here is an example of 98.css used with React, and + an example with vanilla JavaScript. The fastest way to use 98.css is to import it from unpkg. +

+ +
<link
+  rel="stylesheet"
+  href="https://unpkg.com/98.css"
+>
+ +

+ You can install 98.css from the GitHub releases page, or from npm. +

+
npm install 98.css
+ +

Components

+ +
+

Button

+
+
+ A command button, also referred to as a push button, is a control + that causes the application to perform some action when the user clicks it. + +
— Microsoft Windows User Experience p. 160
+
+ +

+ A standard button measures 75px wide and 23px tall, with a raised outer and inner border. + They are given 12px of horizontal padding by default. +

+ + <%- example(` + + `)%> + +

+ You can add the class default to any button to apply additional styling, + useful when communicating to the user what default action would happen in the active window if + the Enter key was pressed on Windows 98. +

+ + <%- example(``)%> + +

+ When buttons are clicked, the raised borders become sunken. + The following button is simulated to be in the pressed (active) state. +

+ + <% /* [[ ... ]] is used to render contents that + will not appear in the "Show code" section */ + %> + <%- example(`I am being pressed`) %> + +

+ Disabled buttons maintain the same raised border, but have a "washed out" + appearance in their label. +

+ + <%- example(``) %> + +

+ Button focus is communicated with a dotted border, set 4px within the contents of the button. + The following example is simulated to be focused. +

+ + <%- example(`I am focused`) %> +
+
+ +
+

Checkbox

+
+
+ A check box represents an independent or non-exclusive choice. +
— Microsoft Windows User Experience p. 167
+
+ +

+ Checkboxes are represented with a sunken panel, populated with a "check" icon when + selected, next to a label indicating the choice. +

+ +

+ Note: You must include a corresponding label after + your checkbox, using the <label> element with a for attribute + pointed at the id of your input. This ensures the checkbox is easy to use with + assistive technologies, on top of ensuring a good user experience for all (navigating with the tab key, + being able to click the entire label to select the box). +

+ + <%- example(` + + + `) %> + +

+ Checkboxes can be selected and disabled with the standard checked and disabled + attributes. +

+ +

+ When grouping inputs, wrap each input in a container with the field-row class. This ensures + a consistent spacing between inputs. +

+ + <%- example(` +
+ + +
+
+ + +
+
+ + +
+ `) %> +
+
+ +
+

OptionButton

+
+
+ An option button, also referred to as a radio button, represents a single + choice within a limited set of mutually exclusive choices. That is, the user can choose only + one set of options. + +
— Microsoft Windows User Experience p. 164
+
+ +

+ Option buttons can be used via the radio type on an input element. +

+ +

+ Option buttons can be grouped by specifying a shared name attribute on each + input. Just as before: when grouping inputs, wrap each input in a container with the + field-row class to ensure a consistent spacing between inputs. +

+ + <%- example(` +
+ + +
+
+ + +
+ `) %> + +

+ Option buttons can also be checked and disabled with their corresponding + HTML attributes. +

+ + <%- example(` +
+ + +
+
+ + +
+
+ + +
+ `) %> +
+
+ +
+

GroupBox

+
+
+ A group box is a special control you can use to organize a set of + controls. A group box is a rectangular frame with an optional label that surrounds + a set of controls. + +
— Microsoft Windows User Experience p. 189
+
+ +

+ A group box can be used by wrapping your elements with the fieldset tag. + It contains a sunken outer border and a raised inner border, resembling an engraved box + around your controls. +

+ + <%- example(` +
+
Select one:
+
+ + +
+
+ + +
+
+ + +
+
+ `) %> + +

+ You can provide your group with a label by placing a legend element + within the fieldset. +

+ + <%- example(` +
+ Today's mood +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ `) %> +
+
+ +
+

TextBox

+
+
+ A text box (also referred to as an edit control) is a + rectangular control where the user enters or edits text. It can + be defined to support a single line or multiple lines of text. + +
— Microsoft Windows User Experience p. 181
+
+ +

+ Text boxes can rendered by specifying a text type on an + input element. As with checkboxes and radio buttons, you + should provide a corresponding label with a properly set for + attribute, and wrap both in a container with the field-row class. +

+ + <%- example(` +
+ + +
+ `) %> + +

+ Additionally, you can make use of the field-row-stacked class + to position your label above the input instead of beside it. +

+ + <%- example(` +
+ + +
+
+ + +
+ `) %> + +

+ To support multiple lines in the user's input, use the textarea + element instead. +

+ + <%- example(` +
+ + +
+ `) %> + +

+ Text boxes can also be disabled and have value with their corresponding HTML attributes. +

+ + <%- example(` +
+ + +
+ `) %> +
+ + +
+ +
+

Slider

+
+
+ A slider, sometimes called a trackbar control, consists of a bar that + defines the extent or range of the adjustment and an indicator that + shows the current value for the control... + +
— Microsoft Windows User Experience p. 146
+
+ +

+ Sliders can rendered by specifying a range type on an + input element. +

+ + <%- example(` +
+ + + + +
+ `) %> + +

+ You can make use of the has-box-indicator class replace the + default indicator with a box indicator, furthermore the slider can be wrapped + with a div using is-vertical to display the input vertically. +

+ +

+ Note: To change the length of a vertical slider, the input width + and div height. +

+ + <%- example(` +
+ +
+ +
+
+ `) %> +
+
+ +
+ +
+
+ A drop-down list box allows the selection of only a + single item from a list. In its closed state, the control displays + the current value for the control. The user opens the list to change + the value. + +
+ — Microsoft Windows User Experience p. 175 +
+
+ +

+ Dropdowns can be rendered by using the select and option + elements. +

+ + <%- example(` + + `) %> + +

+ By default, the first option will be selected. You can change this by + giving one of your option elements the selected + attribute. +

+ + <%- example(` + + `) %> +
+
+ +

Window

+

+ The following components illustrate how to build complete windows using + 98.css. +

+ +
+

Title Bar

+
+
+ At the top edge of the window, inside its border, is the title bar + (also reffered to as the caption or caption bar), which extends across + the width of the window. The title bar identifies the contents of the + window. + +
+ — Microsoft Windows User Experience p. 118 +
+
+ +
+ Include command buttons associated with the common commands of the + primary window in the title bar. These buttons act as shortcuts to specific + window commands. + +
+ — Microsoft Windows User Experience p. 122 +
+
+ +

+ You can build a complete title bar by making use of three classes, + title-bar, title-bar-text, and title-bar-controls. +

+ + <%- example(` +
+
A Title Bar
+
+ +
+
+ `) %> + +

+ We make use of aria-label to render the Close button, to let + assistive technologies know the intent of this button. You may also use + "Minimize", "Maximize", "Restore" and "Help" like so: +

+ + <%- example(` +
+
A Title Bar
+
+ + + +
+
+ +
+ +
+
A Maximized Title Bar
+
+ + + +
+
+ +
+ +
+
A Helpful Bar
+
+ + +
+
+ `) %> + +

+ Each aria-label also has a corresponding styling class to render the title bar buttons, + to let the aria-label text be in other languages without causing rendering, accessibility, or localization issues. +

+ + <%- example(` +
+
A Title Bar using Button Styling Classes
+
+ + + +
+
+ +
+ +
+
A Maximized Title Bar using Button Styling Classes
+
+ + + +
+
+ +
+ +
+
A Helpful Bar using Button Styling Classes
+
+ + +
+
+ `) %> + +

+ Maximize buttons can be disabled, useful when making a window appear as if it cannot be maximized. +

+ + <%- example(` +
+
A Title Bar with Maximize disabled
+
+ + + +
+
+ `) %> + +

+ You can make a title bar "inactive" by adding inactive class, + useful when making more than one window. +

+ <%- example(` +
+
An inactive title bar
+
+ +
+
+ `) %> +
+
+ +
+

Window contents

+
+
+ Every window has a boundary that defines its shape. + +
+ — Microsoft Windows User Experience p. 118 +
+
+ +

+ To give our title bar a home, we make use of the window + class. This provides a raised outer and inner border, as well as some + padding. We can freely resize the window by specifying a width in the + container style. +

+ + <%- example(` +
+
+
A Complete Window
+
+ + + +
+
+
+ `) %> + +

+ To draw the contents of the window, we use the window-body + class under the title bar. +

+ + <%- example(` +
+
+
A Window With Stuff In It
+
+ + + +
+
+
+

There's so much room for activities!

+
+
+ `) %> +
+
+ +
+

Status Bar

+
+
+ A status bar is a special area within a window, typically the bottom, that displays information + about the current state of what is being viewed in the window or any other contextual information, such as keyboard + state. + +
+ — Microsoft Windows User Experience p. 146 +
+
+ +

+ You can render a status bar with the status-bar class, + and status-bar-field for every child text element. +

+ + <%- example(` +
+
+
A Window With A Status Bar
+
+
+

There are just so many possibilities:

+
    +
  • A Task Manager
  • +
  • A Notepad
  • +
  • Or even a File Explorer!
  • +
+
+
+

Press F1 for help

+

Slide 1

+

CPU Usage: 14%

+
+
+ `) %> + + +
+ +
+

TreeView

+
+
+ A tree view control is a special list box control + that displays a set of objects as an indented outline based + on their logical hierarchical relationship. + +
+ — Microsoft Windows User Experience p. 178 +
+
+ +

+ To render a tree view, use an ul element with the + tree-view class. The children of this list (li + elements), can contain whatever you'd like. +

+ + <%- example(` +
    +
  • We can put
  • +
  • ✨ Whatever ✨
  • +
  • We want in here
  • +
+ `) %> + +

+ To make this a tree, we can nest further ul elements + (no class needed on these). This will provide them with a nice dotted + border and indentation to illustrate the structure of the tree. +

+

+ To create expandable sections, wrap child lists inside of + details elements. +

+ + <%- example(` +
    +
  • Table of Contents
  • +
  • What is web development?
  • +
  • + CSS +
      +
    • Selectors
    • +
    • Specificity
    • +
    • Properties
    • +
    +
  • +
  • +
    + JavaScript +
      +
    • Avoid at all costs
    • +
    • +
      + Unless +
        +
      • Avoid
      • +
      • +
        + At +
          +
        • Avoid
        • +
        • At
        • +
        • All
        • +
        • Cost
        • +
        +
        +
      • +
      • All
      • +
      • Cost
      • +
      +
      +
    • +
    +
    +
  • +
  • HTML
  • +
  • Special Thanks
  • +
+ `) %> +
+
+ +
+

Tabs

+
+
+ A tab control is analogous to a divider in a file cabinet or notebook. + You can use this control to define multiple logical pages or sections of information within the same window. + +
+ — Microsoft Windows User Experience p. 193 +
+
+ +

+ To render a tab list, use a menu element with the + [role=tablist] attribute. The children of this menu (li + elements), should get a [role=tab] attribute. +

+ +

+ Tabs should be managed by adding custom javascript code. + All you need is to add the [aria-selected=true] attribute to the active tab. +

+ + <%- example(` +
+

Hello, world!

+ + +
  • Desktop
  • +
  • My computer
  • +
  • Control panel
  • +
  • Devices manager
  • +
  • Hardware profiles
  • +
  • Performance
  • +
    +
    +
    +

    the tab content

    +
    +
    +
    + `) %> + +

    + To create multirows tabs, add a multirows + class to the menu tag. +

    + + <%- example(` +
    +

    Hello, world!

    + + +
  • Desktop
  • +
  • My computer
  • +
  • Control panel
  • +
  • Devices manager
  • +
  • Hardware profiles
  • +
  • Performance
  • +
    + +
  • Users
  • +
  • Network
  • +
  • Programs
  • +
  • Services
  • +
  • Resources
  • +
  • Advanced
  • +
    +
    +
    +

    the tab content

    +
    +
    +
    + `) %> +
    +
    +
    +

    TableView

    +
    +

    + To render a table view, use a table element. Wrap it with a div element with sunken-panel class to provide proper border and overflow container. +

    +

    + With a bit of extra scripting you can make table view interactive. Give interactive class to + table element to show pointer cursor when hovering over body rows. Table rows can be given + highlighted class to appear selected. +

    + + <%- example(` +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameVersionCompany
    MySQL ODBC 3.51 Driver3.51.11.00MySQL AB
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    SQL Server3.70.06.23Microsoft Corporation
    +
    + + `) %> +
    +
    + +
    +

    Progress Indicator

    +
    +
    + You can use a progress indicator, also known as a progress bar control, to show the percentage of completion of a lengthy operation. + +
    + — Microsoft Windows User Experience p. 189 +
    +
    + +

    + There are two types of progress bars: solid and segmented. The solid version is the default. To declare a segmented bar, you should use the segmented class. +

    + + <%- example(` +
    + +
    + `) %> + + <%- example(` +
    + +
    + `) %> +
    +
    + +
    +

    Field borders

    +
    +
    + Text boxes, check boxes, drop-down list boxes, spin boxes and list + boxes use the field border style. You can also use the style + for define the work area within a window. It uses the sunken outer and + sunken inner basic border styles. + + For most controls, the interior of the field uses the button highlight + color. For text fields, such as text boxes and combo boxes, the + interior uses the button face color when the field is read-only or + disabled. + +
    + — Microsoft Windows User Experience p. 421 +
    +
    + +
    + Status fields use the status field border style. This style + uses only the sunken outer basic border style. You use the status + field style in status bars and other read-only fields where the + content of the file can change dynamically. + +
    + — Microsoft Windows User Experience p. 422 +
    +
    + + As mentioned in these guidelines, these styles are used in other + contexts than just form elements and status fields such as to indicate + work areas and dynamic content. For that reason, we provide three + classes for these generic usages, field-border, + field-border-disabled, and + status-field-border. These classes only define the border + and background color and minimal padding, so you will typically need to + at least provide some extra padding yourself. + + <%- example(` +
    + Work area +
    + `) %> + + + <%- example(` +
    + Disabled work area +
    + `) %> + + <%- example(` +
    + Dynamic content +
    + `) %> +
    +
    + +

    Issues, Contributing, etc.

    + +

    + 98.css is MIT licensed. +

    + +

    + Refer to the GitHub issues page to see bugs + in my CSS or report new ones. I'd really like to see your pull requests (especially those new to + open-source!) and will happily provide code review. 98.css is a fun, silly project and I'd like + to make it a fun place to build your open-source muscle. +

    + +

    + Thank you for checking my little project out, I hope it brought you some joy today. Consider + starring/following along on GitHub and maybe + subscribing to more fun things on my twitter. 👋 +

    +
    + + diff --git a/packages/webapp/public/98.css/docs/vs.css b/packages/webapp/public/98.css/docs/vs.css new file mode 100644 index 0000000..6703b64 --- /dev/null +++ b/packages/webapp/public/98.css/docs/vs.css @@ -0,0 +1,67 @@ +/* + +Visual Studio-like style based on original C# coloring by Jason Diamond + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, +.hljs-quote, +.hljs-variable { + color: #008000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-built_in, +.hljs-name, +.hljs-tag { + color: #00f; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-attribute, +.hljs-literal, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-addition { + color: #a31515; +} + +.hljs-deletion, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-meta { + color: #2b91af; +} + +.hljs-doctag { + color: #808080; +} + +.hljs-attr { + color: #f00; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #00b0e8; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/packages/webapp/public/98.css/docs/window.png b/packages/webapp/public/98.css/docs/window.png new file mode 100644 index 0000000000000000000000000000000000000000..58627353ffcfbcdbc20b04d433ab16f6fc3531ab GIT binary patch literal 3411 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 QKSBsA^Ydp4&8~<42O12DM*si- literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/docs/zoom.png b/packages/webapp/public/98.css/docs/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..a3bd3fac3bb8829e2fc8f06c3e60a382a1125f8d GIT binary patch literal 4148 zcmd^CX;4#F6b|Cj;wV(ZG!eBIjq7@Y(`l8J!ON5{-5@OqNAQcHD z#5~cM=@!~SK~x|tCRAC3jL;edF=%uM#0Y^BqL7t7ARtzxP|8e~A8+1$@0@$?{m%K$ zx%W`F`FhVXTV#enAZB4Ud-@{~CS~xm;+-k*pSun_GvSvB$=`b;BD-dZ9R8R}@bK|K zAaZFlbqA)w-|rsXyoZE9%)Zt4m{byfJcvM;S7AIocE$uN8i8=fdgiI8mM2y%I@R)x z=dz<<>B=Xbg@kW6ctqRzmEu#c&7Qi6ee7BG^S$IF9d7H6@U_*U!OykUrYG1022Xcx zflgIRYiHpS)U8`1+mo|66oadb_A%~Y0hy8zhk0C@0j;fILbGE{L#!OQ>Wm^qxSn_gUsd9Q<*>xbh zEb8`1N_pnx}#9@=kZYD(0iB2rQQ?cHA=&w%kp_0e}w|1b}YRS(m7X z@%yOq)De{?8Kqhn5fsk2P&^`3bWwd6aHmj6kX1Er8uF`l8$kZ`Wm8&Cp0IFrc0Sai zd$0L)TYiV1vY~l&ETaH^nE3T!J~v$3dArbPwXscYLGPELUCl+^IA0rJ>^bygK>q_xdTNf*|jQHb5 z_B|mnB)x`iPB6W;h9OMkTI~41j=RDb$+5j(cH%WOimpk}BZ%*%qjgWsVYUoegQZ1G zYeJntM@JhvX+}}NW2(Km#g5}u1mpmru5LxS570V2NZDXqzl~n&J3#tFtoY*tJhLyB zUbE;+2}QwTQM_r7)dWoVU>j^X?EXvytDV$s1L-uOUHw~3;%w)|viRzj^ST_}lpz=L zw>T)BsB*m0^;ubZB2}LCy>$m2LfLV?^2NqN&;-TR^Di|7;K{dByhiH2@DomguFms$Ig zi_ldY?r(8mH66OyO10k#n&lw-1&=dvs8s1S?bAdnWuEe!L6wQN#6cn@MvK`=ELr3BcJwvuF&AiQCd;(@Tr?4Fu1AP@+Ipk zoqss3khmr|2T2=Ye9VX!B@;mPx)VeWTo_ajDmb*art@;iZTMD|yu9goY$X^sS2VM! znzt%DB^SC_rn(7_lC$tDxJcl}%6^>%r{x%|Gpt?BbE|l(dgf{|p zK#trGj8`F_0bSe$JWA+VB1m`2r^tG4L`@2kaLJ`6ZA`A-y|O@Q4fjZW?2#=U6J^H2 zuw8)ug`jxNU{^F=FTB}TjbI@Z39P>i7U^4D6YPWf^5cYjQjk32@2TwW1hvsA#AdG= zc7Ls^bss~4dOeljR?jYjnpR45$Rt-SFm5m0?c5>h{EPbXqxhHW T*tU&ur;osR`Fdt=-2dh8h5b(g literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff b/packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff new file mode 100644 index 0000000000000000000000000000000000000000..a8df7f1a4721d554665198639aa4d49fef81792b GIT binary patch literal 8540 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 OKd@+*0SrE`ul^6uF~lYS literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff2 b/packages/webapp/public/98.css/fonts/converted/ms_sans_serif.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..83ea806020dcccda6b9f8c9c6c3c6b573f550df9 GIT binary patch literal 6508 zcmV-y8I$IBPew8T0RR9102yom5C8xG08RJ+02vGb0RR9100000000000000000000 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 QAW^@EieQu^1J~<+0C&)-d;kCd literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/fonts/converted/ms_sans_serif_bold.woff2 b/packages/webapp/public/98.css/fonts/converted/ms_sans_serif_bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..610c0911782e150841b2857e5a79d62d8f12cfbf GIT binary patch literal 6264 zcmV-;7>DO~Pew8T0RR9102p`x5C8xG073Ks02mek0RR9100000000000000000000 z0000#Mn+Uk92y=5U;u+U2qX!FWf2Gp;w;u;3xQMs0X7081A`<4AO(su2ZJ39f(RQt zIu&eOWrmFd7-a22qNoXLlO_58TLLFz9BW*)%95C#ieP9`*HmieZXNBEr&6GqTE_-a za4kHb2b0S(oL7(O`z$}TVm3b9h5ccE_>P%XoGO7J- zr9bw0NNFDALclMWXo6ZT-ZSZ{1^*_kYE}Ldw146^yb&5>xnzYT{>un;n^q!>F&4s> zIQF^UcljPAqVi0drrs(=W9VO3>{o)@a-Q*fs3r(2W?olmj6*m&eFZk6|NqM@(VlZ( zRrlyuPtJy9A5X*RWbgCwU3 zku6*^dzsmW6qu=zGc`6r8G!}N7#JYn*IwTvxRZ?wm1nzu+iPt7kC*zQuQ8AomJl$0 znp(}>1q?mTaD~W?W=#`fB@e8b;KP2-ud&F0(|sb;TZ(v0_A`~h}8%O z7{EB`G9J$1fQ-Wd4p!PjMM}5ZVT__RpcZ$61%mv z#VFjcI*vN7{C1m?;4n0yC2ijb@dI6P0cN>ZS5VMUEMvs zefQF3uYGeAzVkIckwy%%7LQ83cUU{QAh?Ck{C_ zhU!WTBBt}6-tb%b&Jk=*pC-86elTkN3crNTR@X|Uob)%`ap^UV8Jv!m(VUNma+p5z z^wx5jN)QyyTcRG_y|PP|)>pgXx+af!O*hGpz=t}{eX~A|?jglsn>tz2sM*-p=4?K( z$8Gwatdykhe%!cSkM|LnV$Ukn=>pb*1_eu+?7+nK7?86*)!aV)lJCPY)~syg$RD-c z6b=Oyn<6f#_zM*q|1;Ej%d#-MUnpVnw>c%dQ~TGo4?w2VC|`D8w3M%D4O-jVgMo)a zL5mY^kj=2g<4m=Bm4I%S8d`9K!TjT0L886ZekBUv2a&9yY9ozYr;O3*Xb?StA%O^G z8J&;H8q{07yM5sO1pfa3PzbeuS*tbvF7dqHR-KYLXfdCOy*;ETn=eH$_dVI7`VXYF z;d}UDL`14hM6Xlcg-=hU5WYaJesufr#NkB?S0G)~O+TkmR+ec?e=+t3KgFj;>UyN6 z?^3?neqOh<-3WbOhkAu<+OXgDDzuFJURpj;9+S=5!Y&T4EoL7-Yfqr)@2nvRbAO{0 zkCN+tPBFjk{~e;l;SvZG1qCGs1v@z<96)@2bCE}n(CHKfny)Y9<5m|Ig54C(MegL# zITVeYCcgC}C_ynD?Ma4HenTfrOzv1)Gbai);zWi(4qH;HLF*q`C(FN3mMDglUV})i zW>K4c^A)e&a|-2py9Nz*L%&an)Vg4h6}R_~Sxu9B6tIAsRuWfHm$!|h%_QGi(SsT{ zlg+&diG>tSR~-6?BJ29y^c{^nu+IoOxwP+pNG^d;o2c1m4^C zC-1~exqb%=aUjynC`?5wpTRS!5zGMZMxPB%oIa^*x5f|+c3;6KSLTt>GlJn#gORl{l6MPgG zOhz#GZ+P~x5qe}FZDMc_A!(l4lqx!!k&$akJKfihI|@Zy=Ww|vV9ju2k_-d& z!37`lg*tAmId9$kx-uQMvyxn~*OvD#&l-n7qWKuehGCk;K6|BHgZ&h$qXYw%aMp{) zMsf}9l;P{`oqX9gf|!6&tr{eChFrZW)>`f93_`qxnnncPo4e~H!5^L-X!dI(sZX7 zn?dxvfA-G&olzn9?3s*Jf<9v-$iRIDgViga3j+Z>E9rZh-*K%Pb{wvKESuq7+-`gb zg2e?F#7?&_GFJCitGPM9J3?~ecRl}K7}0HQ$t_ei6X<=TjGw#3r+oE7d$@nz1Er^O z5oN4`Ufol_9aYnlu?k!*{c*sYzcsf(KwBE{U8T)Lcr6<5^pZkp07V2iUilrMG#b>G z0hDsstIen`4Wl=RGq2U;Gn%+vJ18FRVci=Ud()#izOF)vIp;t<+XSMTp7Wk?n=XLzx;ZyVZ^z_T0Jj(tR!^%g{q!yfDmIT%f6%hb$2!C?4- z88m7H&)!ga03Srg&!@L`Uv}{mUPrSt($XqW<}xog;*Dh?FBXsf+UPAPRU3C-yI|eY zp@s4FT8e!7x{Q&IEbUv>y7_92%pyjYDPwN|7-aU`LxF2-h6t-UeO8m1k2`KN*SPi| zd<#&F4zDkBPl-w991^Zec&c7xluwy65k0;t3`_S{x0*EQ>AJ!|Qgt++^=Avl$|7;A z?QRV9Ab9L+;G}M61e(~yccehZ%tXf&+w!4+;HNpk(Zj&-{eEP3LKGih4YX_i2pm~n zYKpw>(B!OcKP4m$=Kxxfkg83eadCA#dR!=Y>K}KDTnU*(tvCr*ZS=M+NUSCX>PpDC zN_dOwX34!msS3(drpeydl?kpVrgpO8H0!geL&$}>d?(W|n8>v=IbL%f4Tq;GJ%|S) zV{dw+MQ1vSnX4cm-=98!^Ty zT!rzH#AA=8HItAec`}`lnD8findQ(T^qZ>$OuEV;L<=3|#;id(Tq#kVX|3Ayhd^oI zR+q|O@HF67p1P-)5qQ@&ieb}3Lcw1Tm- zOC=yY@5xw*R<34L@rkfegY>o(8$N13j$?=(rR>VU|KsJvmGq;eO&MI@XoWnNSMyRi z{fPwr+vV~9>7n;q4mz|HiSn;q^*a}EqDTb?r0q$88^%ODU{mnW!H<$aI%Z$D%E?s` zs{`t|9ES=H+ta>d)bdg#@?3enqJ-YQDW{t{+U^l)<*z%Z`^)CP6I_Hbj_d~MpU2c9 zFLGs_y)_oHdGF4ybt^#G$rb@9Jb3z%t`<0ukOwX4LP%#X*2?+GJMUp-Dwjuf0p`@) zb4h*mqz`&% z6vv(x*|)NOHi72%yp z+o{c{%0WlD0tJJhXfRH{zQY5w#|^28HI?MO6i(F)Y`@E-@6?7*oY*~QLur?-*9y8h zYd~#n9k5e{wO_`mV!*~o(IKA&8jlwmj-hH2hFvnB#S-Q7KCmDVj6o=}P5_cGlLr}g z2}Pb&A5#%b04V-84dPD-kXQ~0ew4Z#PqAB6>(#=Zd67el z2t?PDEe0`9b89{T%xqcd2ZKCv!{uhVHR?rLzbG1+0_P0hW=Q=yopMFmX9ctXypX*q3o8sf#9)hljkmn2?lMHqHB zPk57KLa6X?Mf}XK=b`JF7>w8=S2;H4ALdx0#UsQJyDY52p8`A&Jcv4}V9b&Uii7qs zZhY8T74X2&#KH9bpH;_x*j8FH8I+FjxK0+qGHUGwstsh>!a{RoVxdSu*qe;G!jei9 zsEk2zr=;W4VOd|?Tp`gXNy70q-MnK+;*R~Dy^_?OONl7lnFdTJZ0qSRz?9!9G& zEN!?HPyv*;7a!m@3Sn^LBdu`()QW-a09QkV;W92!OH_6pt&8N8??TL8L>Pw-Y;v9} zF?~7Ih}=b-GbGPp>MetuYqE zy}k^Yie@*LPJ)RYRjBhzA=CCm76!5br%k1DHvr{(Ftq>{L1av!mK1%0TIjKb!^uQ? zgC{Ap^T9(@Fr5L3HanEF1HyH137JM2xSPFYx@#$i**1BdvXgX5hdCK32lEZ8ag`CRy5&@2_Tr#psnXIT3N6SNnnZ*6 z*_JqSQFhJTgY9?fF~TZbC#vU5+LK!;AtR9=Db4`GiM@m%dz8@X97FDJ;!2}b;n2r~ zl0`SCIPz?a{qVRlwgj(5&1KyjB&>CDl_Z_ZGhxEEKZ<(xv?C79=^Y<tI=+%Vw83C- zZlY+4osX%nC@7qjWTw+C9tqnQxuFvsOGk2%JCG&b&#_(%$y!k|?`ftN_kybzPv~eg z6g_p*o?l@MwEf9>iH8cu{MN2XQiA&~G87(hRWF9@v1vCvS5yfYh}bE`%Y^R{502LU zb5=wzk&VU!Z=YusikI{VQ$57hoAHpjUm$R(NjKR&CB-X!4f)c05^qdxp3h>#C+vQC zdRg&Ea(a2Y=-yY(rUA%#sscPyK3!|827-w~c)l1|&OotS9F#3rD57g~Q5FJdl-yF6 zn9mnPl(4kLvEFD9b$ z*bPpJUge=M&_O}T@&2qEcJic$ZPAg9)7U}4loHZ7i*x`37SMSp8Oo(8o%#X?T2$B99Xlp>f)cEO;8I`p^olH&rB=Ps`c|eH7JDCPI_^N1=6>ijkr6yl z5|{9L)=3N!WqA}yI}r#q#$?n*+D02o61oA6OJz&?qmXb0R{7roS_GI~25w~Q#0Xy* zA_!su#YSSa!v(X7%{Td9>3ryD_?0~hhl(*PopJCA)6;n^%-4MfqBJ39_sX0{*%in#&XDU%`BErBv`gusSv`h8I)tVoJx9WNxk z=5lMB*G?hHM4PaJL)p#uo!ng%rJoc@~uB%ZRDD~gW5d97YC7#R?HN_15G(i#l7GlY?)l0u;fDO)HIRRm{1 zsFz%;L%5>KzL%V*hgOsk$jYeX*bVY5LkU(BS0S7dOS6Uq>hC{sjZNU%{nX)_^tTk; z`2VSniwgSx7T$#XOTkNK{y!hy3q}GV26nr`ptH0b(RP8#GOiB3_tuzS7(S=w2`Y8; zyf;zN^3NT%%n$Q|eT;jY9D)b1h#Y>H3hzm=w3Z*J3I9B|KwD;AhV}|CkG8M$N}~qY z!_k74wyaNO9@-;#L9ZZkor}swvL`ZYJK~kHk8>RQP?`0q-lS5`lplb$$E$kuqP*=C zK{B&OhQjL8ACHYfIpvq^-__foOb{3?q0L&0Tm&>{>O?9}s2cLwQnmEuP}R|$yH$^J zey#d6m#qfuR;y}Adp%r@@bz*vW})7!=5pF}s^&4-+^*&`-v-qZrrKrI7bv$kkG@D} zD_ebueEU!MGVF5EiVy8QI_3ViAoDBo|D#TRsriTVSwjdd8;-6xa6@=x0LwB+o6Zoj zh^MD{y9x;%0WIfaXse!x->oVOh) z+T9%5R+LwRBurv8f{sN;(BY^xAbW-cjSh(ctE%;7K*x!Cb9Q*BMXcav0fsfv^V5Rl zfXT~~DL|i!GVnTbCceJ}hvQ^6+aM8^L^{TJAeTMmPC9KvUnI0lafu!4kY9{CgrTN? zMscL!3~e*A!P;Ito)4FlR*<39IVm_bh)Fw=v38k?+K{l$MP3mB%gTwW(FaY=ixn;E z7Yh*>Qb2f-vP0g;+IF5(9cOqrftH44jm=R){1698*g;$m(^BKJ3{0+QHBBbc zs!_BR24Td+z??)6Wlj~w8=UM_+CxAT@;85IU>th~+e|*pXU&HCIfhauRsKNh3SWXaC2M!%McH-2Ta~CdM zxpwQ$y$6q;JbUr#4GM!xNJ>e|$jZqpC@LwdsH$mbYU}9g=^Gdt8Jn1znOj&|S=-p! z*?afl)0b~QegRv|5;=MD6)04sSUJj7p7K?oLKUf4C0ygWN>!$Ef7SXun^$-FdH1ft zj*V+NcW!pxJHz=ues3rz%c*j@oGE9^xpKZ-C>Kl3-N{5N8UN?X!^@X!TYbHi>J_D| zk8f<)9hIF(gA0sH?c~{wN*Cue{{J_x>9lYTrgLhxaM;zQ;myvUO{!!>itUD{IvH^f z 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 literal 0 HcmV?d00001 diff --git a/packages/webapp/public/98.css/fonts/src/ms-sans-serif/license.txt b/packages/webapp/public/98.css/fonts/src/ms-sans-serif/license.txt new file mode 100644 index 0000000..fa4925d --- /dev/null +++ b/packages/webapp/public/98.css/fonts/src/ms-sans-serif/license.txt @@ -0,0 +1,4 @@ +The FontStruction “MS Sans Serif” +(https://fontstruct.com/fontstructions/show/1384746) by “lou” is licensed +under a Creative Commons Attribution Share Alike license +(http://creativecommons.org/licenses/by-sa/3.0/). diff --git a/packages/webapp/public/98.css/fonts/src/ms-sans-serif/readme.txt b/packages/webapp/public/98.css/fonts/src/ms-sans-serif/readme.txt new file mode 100644 index 0000000..63472f4 --- /dev/null +++ b/packages/webapp/public/98.css/fonts/src/ms-sans-serif/readme.txt @@ -0,0 +1,26 @@ +The font file in this archive was created using Fontstruct the free, online +font-building tool. +This font was created by “lou”. +This font has a homepage where this archive and other versions may be found: +https://fontstruct.com/fontstructions/show/1384746 + +Try Fontstruct at http://fontstruct.com +It’s easy and it’s fun. + +NOTE FOR FLASH USERS: Fontstruct fonts (fontstructions) are optimized for Flash. +If the font in this archive is a pixel font, it is best displayed at a font-size +of 11. + +Fontstruct is sponsored by FontShop. +Visit them at https://fontshop.com +FontShop is the original independent font retailer. We’ve been around since +the dawn of digital type. Whether you need the right font or need to create the +right font from scratch, let our 26 years of experience work for you. + +Fontstruct is copyright ©2017 Rob Meek + +LEGAL NOTICE: +In using this font you must comply with the licensing terms described in the +file “license.txt” included with this archive. +If you redistribute the font file in this archive, it must be accompanied by all +the other files from this archive, including this one. diff --git a/packages/webapp/public/98.css/icon/button-down-active.svg b/packages/webapp/public/98.css/icon/button-down-active.svg new file mode 100644 index 0000000..0ef5732 --- /dev/null +++ b/packages/webapp/public/98.css/icon/button-down-active.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/webapp/public/98.css/icon/button-down.svg b/packages/webapp/public/98.css/icon/button-down.svg new file mode 100644 index 0000000..2d0b52b --- /dev/null +++ b/packages/webapp/public/98.css/icon/button-down.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/button-left.svg b/packages/webapp/public/98.css/icon/button-left.svg new file mode 100644 index 0000000..f31b886 --- /dev/null +++ b/packages/webapp/public/98.css/icon/button-left.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/button-right.svg b/packages/webapp/public/98.css/icon/button-right.svg new file mode 100644 index 0000000..ddab662 --- /dev/null +++ b/packages/webapp/public/98.css/icon/button-right.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/button-up.svg b/packages/webapp/public/98.css/icon/button-up.svg new file mode 100644 index 0000000..91f8d4f --- /dev/null +++ b/packages/webapp/public/98.css/icon/button-up.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/checkmark-disabled.svg b/packages/webapp/public/98.css/icon/checkmark-disabled.svg new file mode 100644 index 0000000..ac065de --- /dev/null +++ b/packages/webapp/public/98.css/icon/checkmark-disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/checkmark.svg b/packages/webapp/public/98.css/icon/checkmark.svg new file mode 100644 index 0000000..6a3bbb4 --- /dev/null +++ b/packages/webapp/public/98.css/icon/checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/close.svg b/packages/webapp/public/98.css/icon/close.svg new file mode 100644 index 0000000..419a57a --- /dev/null +++ b/packages/webapp/public/98.css/icon/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/groupbox-border.svg b/packages/webapp/public/98.css/icon/groupbox-border.svg new file mode 100644 index 0000000..38a6221 --- /dev/null +++ b/packages/webapp/public/98.css/icon/groupbox-border.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/webapp/public/98.css/icon/help.svg b/packages/webapp/public/98.css/icon/help.svg new file mode 100644 index 0000000..20a3fda --- /dev/null +++ b/packages/webapp/public/98.css/icon/help.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/indicator-horizontal.svg b/packages/webapp/public/98.css/icon/indicator-horizontal.svg new file mode 100644 index 0000000..f6db8b0 --- /dev/null +++ b/packages/webapp/public/98.css/icon/indicator-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/webapp/public/98.css/icon/indicator-rectangle-horizontal.svg b/packages/webapp/public/98.css/icon/indicator-rectangle-horizontal.svg new file mode 100644 index 0000000..7d0d9b1 --- /dev/null +++ b/packages/webapp/public/98.css/icon/indicator-rectangle-horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/webapp/public/98.css/icon/maximize-disabled.svg b/packages/webapp/public/98.css/icon/maximize-disabled.svg new file mode 100644 index 0000000..8a65ef5 --- /dev/null +++ b/packages/webapp/public/98.css/icon/maximize-disabled.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/webapp/public/98.css/icon/maximize.svg b/packages/webapp/public/98.css/icon/maximize.svg new file mode 100644 index 0000000..e9d4982 --- /dev/null +++ b/packages/webapp/public/98.css/icon/maximize.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/minimize.svg b/packages/webapp/public/98.css/icon/minimize.svg new file mode 100644 index 0000000..a676778 --- /dev/null +++ b/packages/webapp/public/98.css/icon/minimize.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/radio-border-disabled.svg b/packages/webapp/public/98.css/icon/radio-border-disabled.svg new file mode 100644 index 0000000..fd003cd --- /dev/null +++ b/packages/webapp/public/98.css/icon/radio-border-disabled.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/webapp/public/98.css/icon/radio-border.svg b/packages/webapp/public/98.css/icon/radio-border.svg new file mode 100644 index 0000000..633be90 --- /dev/null +++ b/packages/webapp/public/98.css/icon/radio-border.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/radio-dot-disabled.svg b/packages/webapp/public/98.css/icon/radio-dot-disabled.svg new file mode 100644 index 0000000..7d59f52 --- /dev/null +++ b/packages/webapp/public/98.css/icon/radio-dot-disabled.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/radio-dot.svg b/packages/webapp/public/98.css/icon/radio-dot.svg new file mode 100644 index 0000000..61b884d --- /dev/null +++ b/packages/webapp/public/98.css/icon/radio-dot.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/public/98.css/icon/restore.svg b/packages/webapp/public/98.css/icon/restore.svg new file mode 100644 index 0000000..9d17f27 --- /dev/null +++ b/packages/webapp/public/98.css/icon/restore.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/webapp/public/98.css/icon/scrollbar-background.svg b/packages/webapp/public/98.css/icon/scrollbar-background.svg new file mode 100644 index 0000000..3770071 --- /dev/null +++ b/packages/webapp/public/98.css/icon/scrollbar-background.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/webapp/public/98.css/icon/sunken-panel-border.svg b/packages/webapp/public/98.css/icon/sunken-panel-border.svg new file mode 100644 index 0000000..1f09c91 --- /dev/null +++ b/packages/webapp/public/98.css/icon/sunken-panel-border.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/webapp/public/98.css/now.json b/packages/webapp/public/98.css/now.json new file mode 100644 index 0000000..ad0e88c --- /dev/null +++ b/packages/webapp/public/98.css/now.json @@ -0,0 +1,4 @@ +{ + "version": 2, + "public": true +} diff --git a/packages/webapp/public/98.css/package.json b/packages/webapp/public/98.css/package.json new file mode 100644 index 0000000..1a4a01b --- /dev/null +++ b/packages/webapp/public/98.css/package.json @@ -0,0 +1,45 @@ +{ + "name": "98.css", + "version": "0.1.21", + "description": "A design system for building faithful recreations of old UIs", + "main": "dist/98.css", + "directories": { + "doc": "docs" + }, + "scripts": { + "build": "node build.js", + "deploy:docs": "npm run build && gh-pages -d dist", + "release": "npm run build && npm publish" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jdan/98.css.git" + }, + "keywords": [ + "css", + "windows98" + ], + "author": "Jordan Scales ", + "license": "MIT", + "bugs": { + "url": "https://github.com/jdan/98.css/issues" + }, + "homepage": "https://github.com/jdan/98.css", + "devDependencies": { + "chokidar": "^3.3.1", + "cssnano": "^5.0.1", + "dedent": "^0.7.0", + "ejs": "^3.0.2", + "gh-pages": "^2.2.0", + "glob": "^7.1.6", + "highlight.js": "^10.4.1", + "live-server": "^1.2.1", + "mkdirp": "^1.0.4", + "postcss": "^8.2.12", + "postcss-calc": "^7.0.2", + "postcss-copy": "^7.1.0", + "postcss-css-variables": "^0.14.0", + "postcss-inline": "^1.2.0", + "postcss-inline-svg": "^4.1.0" + } +} diff --git a/packages/webapp/public/98.css/server.js b/packages/webapp/public/98.css/server.js new file mode 100644 index 0000000..13edc80 --- /dev/null +++ b/packages/webapp/public/98.css/server.js @@ -0,0 +1,16 @@ +const chokidar = require("chokidar"); +const build = require("./build"); + +chokidar + .watch(["style.css", "build.js", "docs", "fonts", "icon"], { + usePolling: true, + }) + .on("change", (file) => { + console.log( + `[${new Date().toLocaleTimeString()}] ${file} changed -- rebuilding...` + ); + build(); + }); + +var liveServer = require("live-server"); +liveServer.start({ port: 3000, root: "dist" }); diff --git a/packages/webapp/public/98.css/style.css b/packages/webapp/public/98.css/style.css new file mode 100644 index 0000000..8c74873 --- /dev/null +++ b/packages/webapp/public/98.css/style.css @@ -0,0 +1,994 @@ +/** + * 98.css + * Copyright (c) 2020 Jordan Scales + * https://github.com/jdan/98.css/blob/main/LICENSE + */ + +:root { + /* Color */ + --text-color: #222222; + --surface: #c0c0c0; + --button-highlight: #ffffff; + --button-face: #dfdfdf; + --button-shadow: #808080; + --window-frame: #0a0a0a; + --dialog-blue: #000080; + --dialog-blue-light: #1084d0; + --dialog-gray: #808080; + --dialog-gray-light: #b5b5b5; + --link-blue: #0000ff; + + /* Spacing */ + --element-spacing: 8px; + --grouped-button-spacing: 4px; + --grouped-element-spacing: 6px; + --radio-width: 12px; + --checkbox-width: 13px; + --radio-label-spacing: 6px; + --range-track-height: 4px; + --range-spacing: 10px; + + /* Some detailed computations for radio buttons and checkboxes */ + --radio-total-width-precalc: var(--radio-width) + var(--radio-label-spacing); + --radio-total-width: calc(var(--radio-total-width-precalc)); + --radio-left: calc(-1 * var(--radio-total-width-precalc)); + --radio-dot-width: 4px; + --radio-dot-top: calc(var(--radio-width) / 2 - var(--radio-dot-width) / 2); + --radio-dot-left: calc( + -1 * (var(--radio-total-width-precalc)) + var(--radio-width) / 2 - var( + --radio-dot-width + ) / 2 + ); + + --checkbox-total-width-precalc: var(--checkbox-width) + + var(--radio-label-spacing); + --checkbox-total-width: calc(var(--checkbox-total-width-precalc)); + --checkbox-left: calc(-1 * var(--checkbox-total-width-precalc)); + --checkmark-width: 7px; + --checkmark-left: 3px; + + /* Borders */ + --border-width: 1px; + --border-raised-outer: inset -1px -1px var(--window-frame), + inset 1px 1px var(--button-highlight); + --border-raised-inner: inset -2px -2px var(--button-shadow), + inset 2px 2px var(--button-face); + --border-sunken-outer: inset -1px -1px var(--button-highlight), + inset 1px 1px var(--window-frame); + --border-sunken-inner: inset -2px -2px var(--button-face), + inset 2px 2px var(--button-shadow); + --default-button-border-raised-outer: inset -2px -2px var(--window-frame), inset 1px 1px var(--window-frame); + --default-button-border-raised-inner: inset 2px 2px var(--button-highlight), inset -3px -3px var(--button-shadow), inset 3px 3px var(--button-face); + --default-button-border-sunken-outer: inset 2px 2px var(--window-frame), inset -1px -1px var(--window-frame); + --default-button-border-sunken-inner: inset -2px -2px var(--button-highlight), inset 3px 3px var(--button-shadow), inset -3px -3px var(--button-face); + + + /* Window borders flip button-face and button-highlight */ + --border-window-outer: inset -1px -1px var(--window-frame), + inset 1px 1px var(--button-face); + --border-window-inner: inset -2px -2px var(--button-shadow), + inset 2px 2px var(--button-highlight); + + /* Field borders (checkbox, input, etc) flip window-frame and button-shadow */ + --border-field: inset -1px -1px var(--button-highlight), + inset 1px 1px var(--button-shadow), inset -2px -2px var(--button-face), + inset 2px 2px var(--window-frame); + --border-status-field: inset -1px -1px var(--button-face), inset 1px 1px var(--button-shadow); + + /* Tabs */ + --border-tab: inset -1px 0 var(--window-frame), + inset 1px 1px var(--button-face), + inset -2px 0 var(--button-shadow), + inset 2px 2px var(--button-highlight) +} + +@font-face { + font-family: "Pixelated MS Sans Serif"; + src: url("fonts/converted/ms_sans_serif.woff") format("woff"); + src: url("fonts/converted/ms_sans_serif.woff2") format("woff2"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: "Pixelated MS Sans Serif"; + src: url("fonts/converted/ms_sans_serif_bold.woff") format("woff"); + src: url("fonts/converted/ms_sans_serif_bold.woff2") format("woff2"); + font-weight: bold; + font-style: normal; +} + +body { + font-family: Arial; + font-size: 12px; + color: var(--text-color); +} + +button, +label, +input, +legend, +textarea, +select, +option, +table, +ul.tree-view, +.window, +.title-bar, +li[role=tab] { + font-family: "Pixelated MS Sans Serif", Arial; + -webkit-font-smoothing: none; + font-size: 11px; +} + +h1 { + font-size: 5rem; +} + +h2 { + font-size: 2.5rem; +} + +h3 { + font-size: 2rem; +} + +h4 { + font-size: 1.5rem; +} + +u { + text-decoration: none; + border-bottom: 0.5px solid #222222; +} + +button, +input[type="submit"], +input[type="reset"] { + box-sizing: border-box; + border: none; + color: transparent; + text-shadow: 0 0 var(--text-color); + background: var(--surface); + box-shadow: var(--border-raised-outer), var(--border-raised-inner); + border-radius: 0; + + min-width: 75px; + min-height: 23px; + padding: 0 12px; +} + +button.default, +input[type="submit"].default, +input[type="reset"].default { + box-shadow: var(--default-button-border-raised-outer), var(--default-button-border-raised-inner); +} + +.vertical-bar { + width: 4px; + height: 20px; + background: #c0c0c0; + box-shadow: var(--border-raised-outer), var(--border-raised-inner); +} + +button:not(:disabled):active, +input[type="submit"]:not(:disabled):active, +input[type="reset"]:not(:disabled):active { + box-shadow: var(--border-sunken-outer), var(--border-sunken-inner); + text-shadow: 1px 1px var(--text-color); +} + +button.default:not(:disabled):active, +input[type="submit"].default:not(:disabled):active, +input[type="reset"].default:not(:disabled):active { + box-shadow: var(--default-button-border-sunken-outer), var(--default-button-border-sunken-inner); +} + +@media (not(hover)) { + button:not(:disabled):hover, + input[type="submit"]:not(:disabled):hover, + input[type="reset"]:not(:disabled):hover { + box-shadow: var(--border-sunken-outer), var(--border-sunken-inner); + } +} + +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus { + outline: 1px dotted #000000; + outline-offset: -4px; +} + +button::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner { + border: 0; +} + +:disabled, +:disabled + label, +input[readonly], +input[readonly] + label { + color: var(--button-shadow); +} + +button:disabled, +input[type="submit"]:disabled, +input[type="reset"]:disabled, +:disabled + label { + text-shadow: 1px 1px 0 var(--button-highlight); +} + +.window { + box-shadow: var(--border-window-outer), var(--border-window-inner); + background: var(--surface); + padding: 3px; +} + +.title-bar { + background: linear-gradient( + 90deg, + var(--dialog-blue), + var(--dialog-blue-light) + ); + padding: 3px 2px 3px 3px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.title-bar.inactive { + background: linear-gradient( + 90deg, + var(--dialog-gray), + var(--dialog-gray-light) + ); +} + +.title-bar-text { + font-weight: bold; + color: white; + letter-spacing: 0; + margin-right: 24px; +} + +.title-bar-controls { + display: flex; +} + +.title-bar-controls button { + padding: 0; + display: block; + min-width: 16px; + min-height: 14px; +} + +.title-bar-controls button:active { + padding: 0; +} + +.title-bar-controls button:focus { + outline: none; +} + +.title-bar-controls button[aria-label="Minimize"], +.title-bar-controls button[aria-label].minimize { + background-image: svg-load("./icon/minimize.svg"); + background-repeat: no-repeat; + background-position: bottom 3px left 4px; +} + +.title-bar-controls button[aria-label="Maximize"], +.title-bar-controls button[aria-label].maximize { + background-image: svg-load("./icon/maximize.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Maximize"]:disabled, +.title-bar-controls button[aria-label].maximize:disabled { + background-image: svg-load("./icon/maximize-disabled.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Restore"], +.title-bar-controls button[aria-label].restore { + background-image: svg-load("./icon/restore.svg"); + background-repeat: no-repeat; + background-position: top 2px left 3px; +} + +.title-bar-controls button[aria-label="Help"], +.title-bar-controls button[aria-label].help { + background-image: svg-load("./icon/help.svg"); + background-repeat: no-repeat; + background-position: top 2px left 5px; +} + +.title-bar-controls button[aria-label="Close"], +.title-bar-controls button[aria-label].close { + margin-left: 2px; + background-image: svg-load("./icon/close.svg"); + background-repeat: no-repeat; + background-position: top 3px left 4px; +} + +.status-bar { + margin: 0px 1px; + display: flex; + gap: 1px; +} + +.status-bar-field { + box-shadow: var(--border-status-field); + flex-grow: 1; + padding: 2px 3px; + margin: 0; +} + +.window-body { + margin: var(--element-spacing); +} + +fieldset { + border-image: svg-load("./icon/groupbox-border.svg") 2; + padding: calc(2 * var(--border-width) + var(--element-spacing)); + padding-block-start: var(--element-spacing); + margin: 0; +} + +legend { + background: var(--surface); +} + +.field-row { + display: flex; + align-items: center; +} + +[class^="field-row"] + [class^="field-row"] { + margin-top: var(--grouped-element-spacing); +} + +.field-row > * + * { + margin-left: var(--grouped-element-spacing); +} + +.field-row-stacked { + display: flex; + flex-direction: column; +} + +.field-row-stacked * + * { + margin-top: var(--grouped-element-spacing); +} + +label { + display: inline-flex; + align-items: center; + user-select: none; +} + +input[type="radio"], +input[type="checkbox"] { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + margin: 0; + background: 0; + position: fixed; + opacity: 0; + border: none; +} + +input[type="radio"] + label, +input[type="checkbox"] + label { + line-height: 13px; +} + +input[type="radio"] + label { + position: relative; + margin-left: var(--radio-total-width); +} + +input[type="radio"] + label::before { + content: ""; + position: absolute; + top: 0; + left: calc(-1 * (var(--radio-total-width-precalc))); + display: inline-block; + width: var(--radio-width); + height: var(--radio-width); + margin-right: var(--radio-label-spacing); + background: svg-load("./icon/radio-border.svg"); +} + +input[type="radio"]:active + label::before { + background: svg-load("./icon/radio-border-disabled.svg"); +} + +input[type="radio"]:checked + label::after { + content: ""; + display: block; + width: var(--radio-dot-width); + height: var(--radio-dot-width); + top: var(--radio-dot-top); + left: var(--radio-dot-left); + position: absolute; + background: svg-load("./icon/radio-dot.svg"); +} + +input[type="radio"]:focus + label, +input[type="checkbox"]:focus + label { + outline: 1px dotted #000000; +} + +input[type="radio"][disabled] + label::before { + background: svg-load("./icon/radio-border-disabled.svg"); +} + +input[type="radio"][disabled]:checked + label::after { + background: svg-load("./icon/radio-dot-disabled.svg"); +} + +input[type="checkbox"] + label { + position: relative; + margin-left: var(--checkbox-total-width); +} + +input[type="checkbox"] + label::before { + content: ""; + position: absolute; + left: calc(-1 * (var(--checkbox-total-width-precalc))); + display: inline-block; + width: var(--checkbox-width); + height: var(--checkbox-width); + background: var(--button-highlight); + box-shadow: var(--border-field); + margin-right: var(--radio-label-spacing); +} + +input[type="checkbox"]:active + label::before { + background: var(--surface); +} + +input[type="checkbox"]:checked + label::after { + content: ""; + display: block; + width: var(--checkmark-width); + height: var(--checkmark-width); + position: absolute; + left: calc( + -1 * (var(--checkbox-total-width-precalc)) + var(--checkmark-left) + ); + background: svg-load("./icon/checkmark.svg"); +} + +input[type="checkbox"][disabled] + label::before { + background: var(--surface); +} + +input[type="checkbox"][disabled]:checked + label::after { + background: svg-load("./icon/checkmark-disabled.svg"); +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="number"], +input[type="search"], +select, +textarea { + padding: 3px 4px; + border: none; + box-shadow: var(--border-field); + background-color: var(--button-highlight); + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0; +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="search"], +select { + height: 21px; +} +input[type="number"] { + /* need this 1 pixel to fit the spinner controls in box */ + height: 22px; +} +/* clears the ‘X’ from Internet Explorer */ +input[type=search]::-ms-clear { display: none; width : 0; height: 0; } +input[type=search]::-ms-reveal { display: none; width : 0; height: 0; } +/* clears the ‘X’ from Chrome */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { display: none; } + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="tel"], +input[type="number"], +input[type="search"] { + /* For some reason descenders are getting cut off without this */ + line-height: 2; +} + +input[type="email"]:disabled, +input[type="url"]:disabled, +input[type="tel"]:disabled, +input[type="password"]:disabled, +input[type="text"]:disabled, +input[type="number"]:disabled, +input[type="search"]:disabled, +input[type="email"]:read-only, +input[type="url"]:read-only, +input[type="tel"]:read-only, +input[type="password"]:read-only, +input[type="text"]:read-only, +input[type="number"]:read-only, +input[type="search"]:read-only, +textarea:disabled { + background-color: var(--surface); +} + +select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + position: relative; + padding-right: 32px; + background-image: svg-load("./icon/button-down.svg"); + background-position: top 2px right 2px; + background-repeat: no-repeat; + border-radius: 0; +} + +select:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="tel"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +textarea:focus { + outline: none; +} + +input[type="range"] { + -webkit-appearance: none; + width: 100%; + background: transparent; +} + +input[type="range"]:focus { + outline: none; +} + +input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 21px; + width: 11px; + background: svg-load("./icon/indicator-horizontal.svg"); + transform: translateY(-8px); + box-shadow: none; + border: none; +} + +input[type="range"].has-box-indicator::-webkit-slider-thumb { + background: svg-load("./icon/indicator-rectangle-horizontal.svg"); + transform: translateY(-10px); +} + +input[type="range"]::-moz-range-thumb { + height: 21px; + width: 11px; + border: 0; + border-radius: 0; + background: svg-load("./icon/indicator-horizontal.svg"); + transform: translateY(2px); +} + +input[type="range"].has-box-indicator::-moz-range-thumb { + background: svg-load("./icon/indicator-rectangle-horizontal.svg"); + transform: translateY(0px); +} + +input[type="range"]::-webkit-slider-runnable-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: 1px 0 0 white, 1px 1px 0 white, 0 1px 0 white, -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, 0 -1px 0 darkgrey, -1px 1px 0 white, 1px -1px darkgrey; +} + +input[type="range"]::-moz-range-track { + width: 100%; + height: 2px; + box-sizing: border-box; + background: black; + border-right: 1px solid grey; + border-bottom: 1px solid grey; + box-shadow: 1px 0 0 white, 1px 1px 0 white, 0 1px 0 white, -1px 0 0 darkgrey, + -1px -1px 0 darkgrey, 0 -1px 0 darkgrey, -1px 1px 0 white, 1px -1px darkgrey; +} + +.is-vertical { + display: inline-block; + width: 4px; + height: 150px; + transform: translateY(50%); +} + +.is-vertical > input[type="range"] { + width: 150px; + height: 4px; + margin: 0 calc(var(--grouped-element-spacing) + var(--range-spacing)) 0 + var(--range-spacing); + transform-origin: left; + transform: rotate(270deg) translateX(calc(-50% + var(--element-spacing))); +} + +.is-vertical > input[type="range"]::-webkit-slider-runnable-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: -1px 0 0 white, -1px 1px 0 white, 0 1px 0 white, 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, 0 -1px 0 darkgrey, 1px 1px 0 white, -1px -1px darkgrey; +} + +.is-vertical > input[type="range"]::-moz-range-track { + border-left: 1px solid grey; + border-right: 0; + border-bottom: 1px solid grey; + box-shadow: -1px 0 0 white, -1px 1px 0 white, 0 1px 0 white, 1px 0 0 darkgrey, + 1px -1px 0 darkgrey, 0 -1px 0 darkgrey, 1px 1px 0 white, -1px -1px darkgrey; +} + +.is-vertical > input[type="range"]::-webkit-slider-thumb { + transform: translateY(-8px) scaleX(-1); +} + +.is-vertical > input[type="range"].has-box-indicator::-webkit-slider-thumb { + transform: translateY(-10px) scaleX(-1); +} + +.is-vertical > input[type="range"]::-moz-range-thumb { + transform: translateY(2px) scaleX(-1); +} + +.is-vertical > input[type="range"].has-box-indicator::-moz-range-thumb { + transform: translateY(0px) scaleX(-1); +} + +select:focus { + color: var(--button-highlight); + background-color: var(--dialog-blue); +} +select:focus option { + color: #000; + background-color: #fff; +} + +select:active { + background-image: svg-load("./icon/button-down-active.svg"); +} + +a { + color: var(--link-blue); +} + +a:focus { + outline: 1px dotted var(--link-blue); +} + +ul.tree-view { + display: block; + background: var(--button-highlight); + box-shadow: var(--border-field); + padding: 6px; + margin: 0; +} + +ul.tree-view li { + list-style-type: none; +} + +ul.tree-view a { + text-decoration: none; + color: #000; +} + +ul.tree-view a:focus { + background-color: var(--dialog-blue); + color: var(--button-highlight); +} + +ul.tree-view ul, +ul.tree-view li { + margin-top: 3px; +} + +ul.tree-view ul { + margin-left: 16px; + padding-left: 16px; + /* Goes down too far */ + border-left: 1px dotted #808080; +} + +ul.tree-view ul > li { + position: relative; +} +ul.tree-view ul > li::before { + content: ""; + display: block; + position: absolute; + left: -16px; + top: 6px; + width: 12px; + border-bottom: 1px dotted #808080; +} + +/* Cover the bottom of the left dotted border */ +ul.tree-view ul > li:last-child::after { + content: ""; + display: block; + position: absolute; + left: -20px; + top: 7px; + bottom: 0px; + width: 8px; + background: var(--button-highlight); +} + +ul.tree-view details { + margin-top: 0; +} + +ul.tree-view details[open] summary { + margin-bottom: 0; +} + +ul.tree-view ul details > summary:before { + margin-left: -22px; + position: relative; + z-index: 1; +} + +ul.tree-view details > summary:before { + text-align: center; + display: block; + float: left; + content: "+"; + border: 1px solid #808080; + width: 8px; + height: 9px; + line-height: 8px; + margin-right: 5px; + padding-left: 1px; + background-color: #fff; +} + +ul.tree-view details[open] > summary:before { + content: "-"; +} + +ul.tree-view details > summary::marker, +ul.tree-view details > summary::-webkit-details-marker { + content: ""; +} + +pre { + display: block; + background: var(--button-highlight); + box-shadow: var(--border-field); + padding: 12px 8px; + margin: 0; +} + +code, +code * { + font-family: monospace; +} + +summary:focus { + outline: 1px dotted #000000; +} + +::-webkit-scrollbar { + width: 16px; +} +::-webkit-scrollbar:horizontal { + height: 17px; +} + +::-webkit-scrollbar-corner { + background: var(--button-face); +} + +::-webkit-scrollbar-track { + background-image: svg-load("./icon/scrollbar-background.svg"); +} + +::-webkit-scrollbar-thumb { + background-color: var(--button-face); + box-shadow: var(--border-raised-outer), var(--border-raised-inner); +} + +::-webkit-scrollbar-button:horizontal:start:decrement, +::-webkit-scrollbar-button:horizontal:end:increment, +::-webkit-scrollbar-button:vertical:start:decrement, +::-webkit-scrollbar-button:vertical:end:increment { + display: block; +} + +::-webkit-scrollbar-button:vertical:start { + height: 17px; + background-image: svg-load("./icon/button-up.svg"); +} +::-webkit-scrollbar-button:vertical:end { + height: 17px; + background-image: svg-load("./icon/button-down.svg"); +} +::-webkit-scrollbar-button:horizontal:start { + width: 16px; + background-image: svg-load("./icon/button-left.svg"); +} +::-webkit-scrollbar-button:horizontal:end { + width: 16px; + background-image: svg-load("./icon/button-right.svg"); +} + +.window[role=tabpanel] { + position: relative; + z-index: 2; +} + +menu[role=tablist] { + position: relative; + margin: 0 0 -2px 0; + text-indent: 0; + list-style-type: none; + display: flex; + padding-left: 3px; +} + +menu[role=tablist] > li { + border-top-left-radius: 3px; + border-top-right-radius: 3px; + box-shadow: var(--border-tab); + z-index: 1; +} + +menu[role=tablist] > li[aria-selected=true] { + padding-bottom: 2px; + margin-top: -2px; + background-color: var(--surface); + position: relative; + z-index: 8; + margin-left: -3px; +} + +menu[role=tablist] > li > a { + display: block; + color: #222; + margin: 6px; + text-decoration: none; +} +menu[role=tablist] > li[aria-selected=true] > a:focus { + outline: none; +} +menu[role=tablist] > li > a:focus { + outline: 1px dotted #222; +} + +menu[role=tablist].multirows > li { + flex-grow: 1; + text-align: center; +} +.sunken-panel { + box-sizing: border-box; + border: 2px groove transparent; + border-image: svg-load("./icon/sunken-panel-border.svg") 2; + overflow: auto; + background-color: #fff; +} + +table { + border-collapse: collapse; + position: relative; + text-align: left; + white-space: nowrap; + background-color: #fff; +} + +table > thead > tr > * { + position: sticky; + top: 0; + height: 17px; + box-shadow: var(--border-raised-outer), var(--border-raised-inner); + background: var(--surface); + box-sizing: border-box; + font-weight: normal; + padding: 0 var(--grouped-element-spacing); +} + +table.interactive > tbody > tr { + cursor: pointer; +} + +table > tbody > tr.highlighted { + color: #fff; + background-color: var(--dialog-blue); +} + +table > tbody > tr > * { + padding: 0 var(--grouped-element-spacing); + height: 14px; +} + +.progress-indicator { + height: 32px; + position: relative; + box-shadow: var(--border-sunken-inner); + padding: 4px 4px; + border: none; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0; +} + + +.progress-indicator > .progress-indicator-bar { + height: 100%; + display: block; + background-color: var(--dialog-blue); +} + +.progress-indicator.segmented > .progress-indicator-bar { + width: 100%; + background-color: transparent; /* resets the background color which is set to blue in the non-segmented selector */ + background-image: linear-gradient( + 90deg, + var(--dialog-blue) 0 16px, + transparent 0 2px + ); + background-repeat: repeat; + background-size: 18px 100%; +} + +.field-border { + background: var(--button-highlight); + box-shadow: var(--border-field); + padding: 2px; +} + +.field-border-disabled { + background: var(--surface); + box-shadow: var(--border-field); + padding: 2px; +} + +.status-field-border { + background: var(--surface); + box-shadow: var(--border-status-field); + padding: 1px; +} diff --git a/packages/webapp/src/routes/__root.tsx b/packages/webapp/src/routes/__root.tsx index b53751f..7b6ad40 100644 --- a/packages/webapp/src/routes/__root.tsx +++ b/packages/webapp/src/routes/__root.tsx @@ -3,6 +3,7 @@ import { TanStackRouterDevtools } from "@tanstack/react-router-devtools" import { useTranslation } from "react-i18next" import { DiGit } from "react-icons/di" import { FaCode } from "react-icons/fa" +import root from "react-shadow" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" @@ -16,6 +17,24 @@ function RootComponent() { const { t, i18n } = useTranslation() return <> + + + +
    +
    +
    A Window With Stuff In It
    +
    + + + +
    +
    +
    +

    There's so much room for activities!

    +
    +
    +
    +