@polisplatform/theme-bootstrap 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -2
- package/package.json +89 -4
- package/src/index.ts +2 -0
- package/src/styles/elements.scss +149 -0
- package/src/styles/fonts.scss +0 -0
- package/src/styles/main.scss +11 -0
- package/src/styles/responsive.scss +35 -0
- package/src/styles/variables.scss +277 -0
- package/src/theme.ts +127 -0
- package/tsconfig.json +20 -0
package/README.md
CHANGED
|
@@ -1,3 +1,128 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @polisplatform/theme-bootstrap
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Video Game Rankings theme for Polis-family apps. Provides the SCSS design
|
|
4
|
+
tokens (variables, fonts, base element styles, responsive helpers) and the
|
|
5
|
+
Mantine theme overrides extracted from the VGR web app.
|
|
6
|
+
|
|
7
|
+
## What's in here
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
theme.ts Mantine theme override (createTheme(...))
|
|
12
|
+
styles/
|
|
13
|
+
main.scss Imports bootstrap + the partials below
|
|
14
|
+
variables.scss CSS custom properties (colors, typography, layout)
|
|
15
|
+
fonts.scss Font-face declarations (currently empty placeholder)
|
|
16
|
+
elements.scss Base element styles (h3/h4/h6, .button, .alert, ...)
|
|
17
|
+
responsive.scss Breakpoint helpers (.hide-in-mobile, .desktop-only, ...)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The contents are extracted verbatim from
|
|
21
|
+
`Video-Game-Rankings/apps/web/src/theme/` and the inline `mantimeTheme`
|
|
22
|
+
object that lived in `apps/web/src/App.tsx`.
|
|
23
|
+
|
|
24
|
+
## Consuming
|
|
25
|
+
|
|
26
|
+
This package follows the same distribution pattern as `polis-laravel` and
|
|
27
|
+
`polis-react`: it lives in a public GitHub repo and is pulled in via a
|
|
28
|
+
`github:` dependency pinned to a tag.
|
|
29
|
+
|
|
30
|
+
Add to the consuming app's `package.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@polisplatform/theme-bootstrap": "github:PomeloProductions/polis-theme-bootstrap#v0.1.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then `npm install`.
|
|
41
|
+
|
|
42
|
+
## Importing
|
|
43
|
+
|
|
44
|
+
### Polis theme (recommended)
|
|
45
|
+
|
|
46
|
+
`@polisplatform/theme-bootstrap` exports a `theme: PolisTheme` object that
|
|
47
|
+
satisfies the canonical interface in `@polisplatform/react/theme/PolisTheme`.
|
|
48
|
+
Pass it to `<PolisProvider>` from `@polisplatform/react`:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { PolisProvider } from '@polisplatform/react';
|
|
52
|
+
import { theme } from '@polisplatform/theme-bootstrap';
|
|
53
|
+
|
|
54
|
+
export function App() {
|
|
55
|
+
return <PolisProvider theme={theme}>{/* ... */}</PolisProvider>;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`PolisProvider` injects every token as a `--polis-*` CSS custom
|
|
60
|
+
property and wraps children in `<MantineProvider>` using the theme's
|
|
61
|
+
embedded `mantineTheme` override. Swap themes by changing only the
|
|
62
|
+
import on the second line — components in `@polisplatform/react` that read
|
|
63
|
+
`var(--polis-*)` will pick up the new palette automatically.
|
|
64
|
+
|
|
65
|
+
### Dark mode
|
|
66
|
+
|
|
67
|
+
This theme ships a full dark colour set (in `theme.dark`) whose surfaces track
|
|
68
|
+
Bootstrap 5.3's dark theme (`--bs-body-bg` #212529 body, `--bs-tertiary-bg`
|
|
69
|
+
#2b3035 elevated). `<PolisProvider>` (from `@polisplatform/react` ≥ the dark-mode
|
|
70
|
+
release) resolves the active scheme (`'light' | 'dark' | 'system'`), injects the
|
|
71
|
+
matching token set, and sets `data-bs-theme="dark"` on `<html>` so Bootstrap's
|
|
72
|
+
own dark mode engages in lockstep:
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<PolisProvider theme={theme} defaultAppliedColorScheme="system">
|
|
76
|
+
{/* ... */}
|
|
77
|
+
</PolisProvider>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
SCSS-only consumers (no `<PolisProvider>`) get dark by setting
|
|
81
|
+
`data-bs-theme="dark"` or `data-polis-color-scheme="dark"` on the root element —
|
|
82
|
+
`styles/variables.scss` overrides the `--polis-color-*` tokens under those
|
|
83
|
+
selectors.
|
|
84
|
+
|
|
85
|
+
### Mantine theme (standalone)
|
|
86
|
+
|
|
87
|
+
If you only need the Mantine theme overrides (no token interface, no
|
|
88
|
+
PolisProvider), the `mantineTheme` export is the same object that's
|
|
89
|
+
embedded in `theme.mantineTheme`:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { MantineProvider } from '@mantine/core';
|
|
93
|
+
import { mantineTheme } from '@polisplatform/theme-bootstrap';
|
|
94
|
+
|
|
95
|
+
export function App() {
|
|
96
|
+
return (
|
|
97
|
+
<MantineProvider theme={mantineTheme}>
|
|
98
|
+
{/* ... */}
|
|
99
|
+
</MantineProvider>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### SCSS
|
|
105
|
+
|
|
106
|
+
Import the bundle entry point:
|
|
107
|
+
|
|
108
|
+
```scss
|
|
109
|
+
@import '@polisplatform/theme-bootstrap/styles/main.scss';
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or pull in individual partials:
|
|
113
|
+
|
|
114
|
+
```scss
|
|
115
|
+
@import '@polisplatform/theme-bootstrap/styles/variables';
|
|
116
|
+
@import '@polisplatform/theme-bootstrap/styles/elements';
|
|
117
|
+
@import '@polisplatform/theme-bootstrap/styles/responsive';
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`main.scss` currently imports `~bootstrap/scss/bootstrap`, so the consuming
|
|
121
|
+
app must have `bootstrap` available to its SCSS resolver (most bundlers
|
|
122
|
+
honour the `~` tilde-prefix to mean "resolve from `node_modules`").
|
|
123
|
+
|
|
124
|
+
## Versioning
|
|
125
|
+
|
|
126
|
+
Tagged releases follow SemVer. Breaking changes bump the major; new
|
|
127
|
+
features the minor; bug fixes the patch. Pin consumers to a tag
|
|
128
|
+
(`#v0.1.0`) so theme updates roll out deliberately.
|
package/package.json
CHANGED
|
@@ -1,6 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polisplatform/theme-bootstrap",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Video Game Rankings theme for Polis-family apps (SCSS variables, fonts, base elements, responsive helpers, Mantine theme overrides)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Bryce Meyer <bryce13950@gmail.com> (Pomelo Productions)",
|
|
8
|
+
"homepage": "https://github.com/PomeloProductions/polis-theme-bootstrap",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/PomeloProductions/polis-theme-bootstrap.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/PomeloProductions/polis-theme-bootstrap/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"polis",
|
|
18
|
+
"pomelo",
|
|
19
|
+
"theme",
|
|
20
|
+
"bootstrap",
|
|
21
|
+
"ui"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public",
|
|
25
|
+
"registry": "https://registry.npmjs.org"
|
|
26
|
+
},
|
|
27
|
+
"main": "./src/index.ts",
|
|
28
|
+
"types": "./src/index.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./src/index.ts",
|
|
32
|
+
"import": "./src/index.ts",
|
|
33
|
+
"default": "./src/index.ts"
|
|
34
|
+
},
|
|
35
|
+
"./theme": "./src/theme.ts",
|
|
36
|
+
"./styles/*": "./src/styles/*",
|
|
37
|
+
"./styles/main.scss": "./src/styles/main.scss",
|
|
38
|
+
"./styles/variables.scss": "./src/styles/variables.scss",
|
|
39
|
+
"./styles/fonts.scss": "./src/styles/fonts.scss",
|
|
40
|
+
"./styles/elements.scss": "./src/styles/elements.scss",
|
|
41
|
+
"./styles/responsive.scss": "./src/styles/responsive.scss",
|
|
42
|
+
"./package.json": "./package.json"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"src",
|
|
46
|
+
"tsconfig.json",
|
|
47
|
+
"README.md"
|
|
48
|
+
],
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@mantine/core": "^9.0.0",
|
|
51
|
+
"@polisplatform/react": "github:PomeloProductions/polis-react",
|
|
52
|
+
"bootstrap": ">=5",
|
|
53
|
+
"react": ">=19.2.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@mantine/core": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@polisplatform/react": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"bootstrap": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"react": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"lint": "eslint . && prettier --check .",
|
|
71
|
+
"lint:fix": "eslint . --fix && prettier --write ."
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@eslint/js": "^10.0.0",
|
|
75
|
+
"@mantine/core": "^9.6.0",
|
|
76
|
+
"@mantine/dates": "^9.6.0",
|
|
77
|
+
"@mantine/hooks": "^9.6.0",
|
|
78
|
+
"@mantine/notifications": "^9.6.0",
|
|
79
|
+
"@mantine/tiptap": "^9.6.0",
|
|
80
|
+
"@polisplatform/react": "github:PomeloProductions/polis-react",
|
|
81
|
+
"eslint": "^10.0.0",
|
|
82
|
+
"eslint-config-prettier": "^10.0.0",
|
|
83
|
+
"eslint-plugin-import": "^2.31.0",
|
|
84
|
+
"eslint-plugin-react": "^7.37.4",
|
|
85
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
86
|
+
"globals": "^17.0.0",
|
|
87
|
+
"prettier": "^3.4.2",
|
|
88
|
+
"typescript": "^6.0.3",
|
|
89
|
+
"typescript-eslint": "^8.69.0"
|
|
90
|
+
}
|
|
91
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--primary-color: var(--polis-color-primary);
|
|
3
|
+
--primary-shade: #3171e0;
|
|
4
|
+
--primary-tint: #4c8dff;
|
|
5
|
+
--medium-color: #92949c;
|
|
6
|
+
--medium-tint: #a2a4ab;
|
|
7
|
+
--medium-shade: #808289;
|
|
8
|
+
--light-color: #f4f5f8;
|
|
9
|
+
--light-shade: #d7d8da;
|
|
10
|
+
--danger-color: #eb445a;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
h3 {
|
|
14
|
+
color: var(--primary-shade);
|
|
15
|
+
text-align: center;
|
|
16
|
+
font-weight: bold;
|
|
17
|
+
}
|
|
18
|
+
h4 {
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
margin: 0;
|
|
21
|
+
color: black;
|
|
22
|
+
}
|
|
23
|
+
h6 {
|
|
24
|
+
font-size: 5vw;
|
|
25
|
+
@media screen and (min-width: 400px) {
|
|
26
|
+
font-size: 20px;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
.content {
|
|
30
|
+
--background: var(--color-light);
|
|
31
|
+
--padding-top: 20px;
|
|
32
|
+
--padding-bottom: 20px;
|
|
33
|
+
--padding-start: 20px;
|
|
34
|
+
--padding-end: 20px;
|
|
35
|
+
}
|
|
36
|
+
.button {
|
|
37
|
+
--background: var(--polis-color-primary);
|
|
38
|
+
--background-hover: var(--color-primary-shade);
|
|
39
|
+
--background-activated: var(--color-primary-shade);
|
|
40
|
+
--background-focused: var(--color-primary-shade);
|
|
41
|
+
--color: var(--color-primary-contrast);
|
|
42
|
+
--border-radius: 4px;
|
|
43
|
+
--box-shadow: none;
|
|
44
|
+
--padding-top: 10px;
|
|
45
|
+
--padding-bottom: 10px;
|
|
46
|
+
--padding-start: 20px;
|
|
47
|
+
--padding-end: 20px;
|
|
48
|
+
font-weight: 500;
|
|
49
|
+
text-transform: none;
|
|
50
|
+
}
|
|
51
|
+
.button.outlined {
|
|
52
|
+
--background: transparent;
|
|
53
|
+
--background-hover: rgba(var(--color-primary-rgb), 0.1);
|
|
54
|
+
--background-activated: rgba(var(--color-primary-rgb), 0.2);
|
|
55
|
+
--background-focused: rgba(var(--color-primary-rgb), 0.1);
|
|
56
|
+
--color: var(--polis-color-primary);
|
|
57
|
+
--border-color: var(--polis-color-primary);
|
|
58
|
+
--border-width: 1px;
|
|
59
|
+
--border-style: solid;
|
|
60
|
+
}
|
|
61
|
+
.error {
|
|
62
|
+
color: var(--danger-color);
|
|
63
|
+
}
|
|
64
|
+
.select {
|
|
65
|
+
--background: transparent;
|
|
66
|
+
--color: var(--color-dark);
|
|
67
|
+
--placeholder-color: var(--color-medium);
|
|
68
|
+
--padding-start: 0;
|
|
69
|
+
--padding-end: 0;
|
|
70
|
+
}
|
|
71
|
+
.item {
|
|
72
|
+
--background: transparent;
|
|
73
|
+
--color: var(--color-dark);
|
|
74
|
+
--padding-start: 0;
|
|
75
|
+
--padding-end: 0;
|
|
76
|
+
--inner-padding-end: 0;
|
|
77
|
+
--min-height: 40px;
|
|
78
|
+
}
|
|
79
|
+
.item,
|
|
80
|
+
.list {
|
|
81
|
+
--background: transparent;
|
|
82
|
+
}
|
|
83
|
+
.alert {
|
|
84
|
+
--background: var(--color-light);
|
|
85
|
+
--backdrop-opacity: 0.4;
|
|
86
|
+
--max-width: 90%;
|
|
87
|
+
--width: 90%;
|
|
88
|
+
--border-radius: 8px;
|
|
89
|
+
--box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
90
|
+
--header-color: var(--color-dark);
|
|
91
|
+
--message-color: var(--color-medium);
|
|
92
|
+
--button-color: var(--polis-color-primary);
|
|
93
|
+
--button-background: transparent;
|
|
94
|
+
--button-background-hover: rgba(var(--color-primary-rgb), 0.1);
|
|
95
|
+
--button-background-activated: rgba(var(--color-primary-rgb), 0.2);
|
|
96
|
+
--button-background-focused: rgba(var(--color-primary-rgb), 0.1);
|
|
97
|
+
}
|
|
98
|
+
.toolbar .back-button {
|
|
99
|
+
--color: var(--color-dark);
|
|
100
|
+
--padding-start: 0;
|
|
101
|
+
--padding-end: 0;
|
|
102
|
+
margin: 0;
|
|
103
|
+
}
|
|
104
|
+
.app {
|
|
105
|
+
--background: var(--color-light);
|
|
106
|
+
}
|
|
107
|
+
a {
|
|
108
|
+
color: var(--primary-shade);
|
|
109
|
+
text-decoration: none;
|
|
110
|
+
|
|
111
|
+
&:hover {
|
|
112
|
+
text-decoration: underline;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
.plt-android {
|
|
116
|
+
.back-button {
|
|
117
|
+
display: none;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
input,
|
|
122
|
+
textarea {
|
|
123
|
+
border: 1px solid var(--light-shade);
|
|
124
|
+
padding: 8px;
|
|
125
|
+
border-radius: 4px;
|
|
126
|
+
|
|
127
|
+
&:focus {
|
|
128
|
+
outline: none;
|
|
129
|
+
border-color: var(--primary-color);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.back-button {
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
color: var(--medium-color);
|
|
137
|
+
text-decoration: none;
|
|
138
|
+
padding: 8px;
|
|
139
|
+
|
|
140
|
+
&:hover {
|
|
141
|
+
color: var(--medium-shade);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.app-container {
|
|
146
|
+
min-height: 100vh;
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: column;
|
|
149
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.plt-mobileweb,
|
|
2
|
+
.plt-desktop {
|
|
3
|
+
input::-webkit-outer-spin-button,
|
|
4
|
+
input::-webkit-inner-spin-button {
|
|
5
|
+
-webkit-appearance: none;
|
|
6
|
+
margin: 0;
|
|
7
|
+
}
|
|
8
|
+
input[type='number'] {
|
|
9
|
+
-moz-appearance: textfield;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// These are the organization breakpoints
|
|
14
|
+
@media screen and (max-width: 800px) {
|
|
15
|
+
.desktop-only {
|
|
16
|
+
display: none !important;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
@media screen and (min-width: 801px) {
|
|
20
|
+
.mobile-only {
|
|
21
|
+
display: none !important;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Public breakpoints
|
|
26
|
+
.hide-in-desktop {
|
|
27
|
+
@media screen and (min-width: 992px) {
|
|
28
|
+
display: none !important;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
.hide-in-mobile {
|
|
32
|
+
@media screen and (max-width: 991px) {
|
|
33
|
+
display: none !important;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Theme Variables
|
|
3
|
+
* ----------------------------------------------------------------------------
|
|
4
|
+
* Custom variables for the application theme
|
|
5
|
+
*
|
|
6
|
+
* The `--polis-*` block mirrors the token values exported from `theme.ts`
|
|
7
|
+
* (`@polisplatform/theme-bootstrap`) as CSS custom-property defaults. Consumers
|
|
8
|
+
* that import just the SCSS — without going through `<PolisProvider>`
|
|
9
|
+
* from `@polisplatform/react` — still get a styled surface. When `<PolisProvider>`
|
|
10
|
+
* is mounted it will overwrite these on `document.documentElement`, so
|
|
11
|
+
* runtime theme swaps still take precedence.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
/* ── Polis canonical tokens (mirrors src/theme.ts) ── */
|
|
16
|
+
--polis-color-primary: #228be6;
|
|
17
|
+
--polis-color-primary-hover: #1c7ed6;
|
|
18
|
+
--polis-color-primary-active: #1971c2;
|
|
19
|
+
--polis-color-surface: #ffffff;
|
|
20
|
+
--polis-color-surface-alt: #f8f9fa;
|
|
21
|
+
--polis-color-text-primary: #212529;
|
|
22
|
+
--polis-color-text-muted: #6c757d;
|
|
23
|
+
--polis-color-border: #dee2e6;
|
|
24
|
+
--polis-color-success: #52ab58;
|
|
25
|
+
--polis-color-warning: #ffc409;
|
|
26
|
+
--polis-color-danger: #eb445a;
|
|
27
|
+
--polis-color-info: #3298b3;
|
|
28
|
+
|
|
29
|
+
--polis-font-body: Inter, sans-serif;
|
|
30
|
+
--polis-font-heading: Inter, sans-serif;
|
|
31
|
+
--polis-font-mono:
|
|
32
|
+
'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
33
|
+
|
|
34
|
+
--polis-radius-sm: 2px;
|
|
35
|
+
--polis-radius-md: 4px;
|
|
36
|
+
--polis-radius-lg: 8px;
|
|
37
|
+
--polis-radius-full: 9999px;
|
|
38
|
+
|
|
39
|
+
--polis-spacing-xs: 4px;
|
|
40
|
+
--polis-spacing-sm: 8px;
|
|
41
|
+
--polis-spacing-md: 16px;
|
|
42
|
+
--polis-spacing-lg: 24px;
|
|
43
|
+
--polis-spacing-xl: 32px;
|
|
44
|
+
|
|
45
|
+
/* ── Legacy VGR / Bootstrap-styled palette (kept for backward-compat) ── */
|
|
46
|
+
/* Primary Colors */
|
|
47
|
+
--color-primary-rgb: 56, 128, 255;
|
|
48
|
+
--color-primary-contrast: #ffffff;
|
|
49
|
+
--color-primary-contrast-rgb: 255, 255, 255;
|
|
50
|
+
--color-primary-shade: #e87819;
|
|
51
|
+
--color-primary-tint: #f58d34;
|
|
52
|
+
--color-primary-light: #ffeed4;
|
|
53
|
+
|
|
54
|
+
/* Secondary Colors */
|
|
55
|
+
--color-secondary: #3298b3;
|
|
56
|
+
--color-secondary-rgb: 61, 194, 255;
|
|
57
|
+
--color-secondary-contrast: #ffffff;
|
|
58
|
+
--color-secondary-contrast-rgb: 255, 255, 255;
|
|
59
|
+
--color-secondary-shade: #3eacc9;
|
|
60
|
+
--color-secondary-tint: #3298b3;
|
|
61
|
+
|
|
62
|
+
/* Tertiary Colors */
|
|
63
|
+
--color-tertiary: #5260ff;
|
|
64
|
+
--color-tertiary-rgb: 82, 96, 255;
|
|
65
|
+
--color-tertiary-contrast: #ffffff;
|
|
66
|
+
--color-tertiary-contrast-rgb: 255, 255, 255;
|
|
67
|
+
--color-tertiary-shade: #4854e0;
|
|
68
|
+
--color-tertiary-tint: #6370ff;
|
|
69
|
+
|
|
70
|
+
/* Quaternary Colors */
|
|
71
|
+
--color-quaternary: #481514;
|
|
72
|
+
|
|
73
|
+
/* Success Colors */
|
|
74
|
+
--color-success: #52ab58;
|
|
75
|
+
--color-success-rgb: 45, 211, 111;
|
|
76
|
+
--color-success-contrast: #ffffff;
|
|
77
|
+
--color-success-contrast-rgb: 255, 255, 255;
|
|
78
|
+
--color-success-shade: rgba(0, 128, 55, 0.95);
|
|
79
|
+
--color-success-tint: #3fa46a;
|
|
80
|
+
|
|
81
|
+
/* Warning Colors */
|
|
82
|
+
--color-warning: #ffc409;
|
|
83
|
+
--color-warning-rgb: 255, 196, 9;
|
|
84
|
+
--color-warning-contrast: #000000;
|
|
85
|
+
--color-warning-contrast-rgb: 0, 0, 0;
|
|
86
|
+
--color-warning-shade: #e0ac08;
|
|
87
|
+
--color-warning-tint: #ffca22;
|
|
88
|
+
|
|
89
|
+
/* Danger Colors */
|
|
90
|
+
--color-danger: #eb445a;
|
|
91
|
+
--color-danger-rgb: 235, 68, 90;
|
|
92
|
+
--color-danger-contrast: #ffffff;
|
|
93
|
+
--color-danger-contrast-rgb: 255, 255, 255;
|
|
94
|
+
--color-danger-shade: #cf3c4f;
|
|
95
|
+
--color-danger-tint: #ed576b;
|
|
96
|
+
|
|
97
|
+
/* Dark Colors */
|
|
98
|
+
--color-dark: #222428;
|
|
99
|
+
--color-dark-rgb: 34, 36, 40;
|
|
100
|
+
--color-dark-contrast: #ffffff;
|
|
101
|
+
--color-dark-contrast-rgb: 255, 255, 255;
|
|
102
|
+
--color-dark-shade: #1e2023;
|
|
103
|
+
--color-dark-tint: #383a3e;
|
|
104
|
+
|
|
105
|
+
/* Medium Colors */
|
|
106
|
+
--color-medium: #545454;
|
|
107
|
+
--color-medium-rgb: 146, 148, 156;
|
|
108
|
+
--color-medium-contrast: #ffffff;
|
|
109
|
+
--color-medium-contrast-rgb: 255, 255, 255;
|
|
110
|
+
--color-medium-shade: #888b8e;
|
|
111
|
+
--color-medium-tint: #9d9fa6;
|
|
112
|
+
|
|
113
|
+
/* Light Colors */
|
|
114
|
+
--color-light: #f5f7f4;
|
|
115
|
+
--color-light-rgb: 244, 245, 248;
|
|
116
|
+
--color-light-contrast: var(--polis-color-primary);
|
|
117
|
+
--color-light-contrast-rgb: 0, 0, 0;
|
|
118
|
+
--color-light-shade: #d7d8da;
|
|
119
|
+
--color-light-tint: #f5f6f9;
|
|
120
|
+
|
|
121
|
+
/* Social Colors */
|
|
122
|
+
--color-favorite: #69bb7b;
|
|
123
|
+
--color-favorite-rgb: 105, 187, 123;
|
|
124
|
+
--color-favorite-contrast: #ffffff;
|
|
125
|
+
--color-favorite-contrast-rgb: 255, 255, 255;
|
|
126
|
+
--color-favorite-shade: #5ca56c;
|
|
127
|
+
--color-favorite-tint: #78c288;
|
|
128
|
+
|
|
129
|
+
--color-twitter: #1da1f4;
|
|
130
|
+
--color-twitter-rgb: 29, 161, 244;
|
|
131
|
+
--color-twitter-contrast: #ffffff;
|
|
132
|
+
--color-twitter-contrast-rgb: 255, 255, 255;
|
|
133
|
+
--color-twitter-shade: #1a8ed7;
|
|
134
|
+
--color-twitter-tint: #34aaf5;
|
|
135
|
+
|
|
136
|
+
--color-instagram: #5956d8;
|
|
137
|
+
--color-instagram-rgb: 89, 86, 216;
|
|
138
|
+
--color-instagram-contrast: #ffffff;
|
|
139
|
+
--color-instagram-contrast-rgb: 255, 255, 255;
|
|
140
|
+
--color-instagram-shade: #4e4cbe;
|
|
141
|
+
--color-instagram-tint: #6a67dc;
|
|
142
|
+
|
|
143
|
+
--color-vimeo: #23b6ea;
|
|
144
|
+
--color-vimeo-rgb: 35, 182, 234;
|
|
145
|
+
--color-vimeo-contrast: #ffffff;
|
|
146
|
+
--color-vimeo-contrast-rgb: 255, 255, 255;
|
|
147
|
+
--color-vimeo-shade: #1fa0ce;
|
|
148
|
+
--color-vimeo-tint: #39bdec;
|
|
149
|
+
|
|
150
|
+
--color-facebook: #3b5998;
|
|
151
|
+
--color-facebook-rgb: 59, 89, 152;
|
|
152
|
+
--color-facebook-contrast: #ffffff;
|
|
153
|
+
--color-facebook-contrast-rgb: 255, 255, 255;
|
|
154
|
+
--color-facebook-shade: #344e86;
|
|
155
|
+
--color-facebook-tint: #4f6aa2;
|
|
156
|
+
|
|
157
|
+
--color-github: #211f1f;
|
|
158
|
+
--color-github-rgb: 33, 31, 31;
|
|
159
|
+
--color-github-contrast: #ffffff;
|
|
160
|
+
--color-github-contrast-rgb: 255, 255, 255;
|
|
161
|
+
--color-github-shade: #1d1b1b;
|
|
162
|
+
--color-github-tint: #373535;
|
|
163
|
+
|
|
164
|
+
/* Other Colors */
|
|
165
|
+
--welcome-background: #f6ead7;
|
|
166
|
+
--color-violet: #5e17eb;
|
|
167
|
+
|
|
168
|
+
/* Typography */
|
|
169
|
+
--font-family: 'Omnes', 'Helvetica Neue', 'Arial', sans-serif;
|
|
170
|
+
--headings-font-weight: 300;
|
|
171
|
+
|
|
172
|
+
/* Layout */
|
|
173
|
+
--toolbar-background: white;
|
|
174
|
+
--tab-bar-background: white;
|
|
175
|
+
--color-angular: #ac282b;
|
|
176
|
+
--color-communication: #8e8d93;
|
|
177
|
+
--color-tooling: #fe4c52;
|
|
178
|
+
--color-services: #fd8b2d;
|
|
179
|
+
--color-design: #fed035;
|
|
180
|
+
--color-workshop: #69bb7b;
|
|
181
|
+
--color-food: #3bc7c4;
|
|
182
|
+
--color-documentation: #b16be3;
|
|
183
|
+
--color-navigation: #6600cc;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/*
|
|
187
|
+
* ── Polis dark tokens ──
|
|
188
|
+
* SCSS-only consumers (no <PolisProvider>) get dark mode by setting
|
|
189
|
+
* `data-bs-theme="dark"` (Bootstrap 5.3 native) or `data-polis-color-scheme="dark"`
|
|
190
|
+
* on the root element. When <PolisProvider> is mounted it overwrites these
|
|
191
|
+
* inline on document.documentElement, so this block is the standalone default.
|
|
192
|
+
* Mirrors the `dark` set in src/theme.ts.
|
|
193
|
+
*/
|
|
194
|
+
:root[data-bs-theme='dark'],
|
|
195
|
+
:root[data-polis-color-scheme='dark'] {
|
|
196
|
+
--polis-color-primary: #4dabf7;
|
|
197
|
+
--polis-color-primary-hover: #74c0fc;
|
|
198
|
+
--polis-color-primary-active: #a5d8ff;
|
|
199
|
+
--polis-color-primary-tint: #1b3a5b;
|
|
200
|
+
--polis-color-primary-subtle: #132840;
|
|
201
|
+
--polis-color-primary-contrast: #0b0d10;
|
|
202
|
+
--polis-color-surface: #212529;
|
|
203
|
+
--polis-color-surface-alt: #2b3035;
|
|
204
|
+
--polis-color-text-primary: #dee2e6;
|
|
205
|
+
--polis-color-text-muted: #adb5bd;
|
|
206
|
+
--polis-color-border: #495057;
|
|
207
|
+
--polis-color-success: #69db7c;
|
|
208
|
+
--polis-color-warning: #ffd43b;
|
|
209
|
+
--polis-color-danger: #ff8787;
|
|
210
|
+
--polis-color-info: #66d9e8;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Dark Theme */
|
|
214
|
+
body.dark {
|
|
215
|
+
--color-primary: #428cff;
|
|
216
|
+
--color-primary-rgb: 66, 140, 255;
|
|
217
|
+
--color-primary-contrast: #ffffff;
|
|
218
|
+
--color-primary-contrast-rgb: 255, 255, 255;
|
|
219
|
+
--color-primary-shade: #3a7be0;
|
|
220
|
+
--color-primary-tint: #5598ff;
|
|
221
|
+
|
|
222
|
+
--color-secondary: #50c8ff;
|
|
223
|
+
--color-secondary-rgb: 80, 200, 255;
|
|
224
|
+
--color-secondary-contrast: #ffffff;
|
|
225
|
+
--color-secondary-contrast-rgb: 255, 255, 255;
|
|
226
|
+
--color-secondary-shade: #46b0e0;
|
|
227
|
+
--color-secondary-tint: #62ceff;
|
|
228
|
+
|
|
229
|
+
--color-tertiary: #6a64ff;
|
|
230
|
+
--color-tertiary-rgb: 106, 100, 255;
|
|
231
|
+
--color-tertiary-contrast: #ffffff;
|
|
232
|
+
--color-tertiary-contrast-rgb: 255, 255, 255;
|
|
233
|
+
--color-tertiary-shade: #5d58e0;
|
|
234
|
+
--color-tertiary-tint: #7974ff;
|
|
235
|
+
|
|
236
|
+
--color-success: #2fdf75;
|
|
237
|
+
--color-success-rgb: 47, 223, 117;
|
|
238
|
+
--color-success-contrast: #000000;
|
|
239
|
+
--color-success-contrast-rgb: 0, 0, 0;
|
|
240
|
+
--color-success-shade: #29c467;
|
|
241
|
+
--color-success-tint: #44e283;
|
|
242
|
+
|
|
243
|
+
--color-warning: #ffd534;
|
|
244
|
+
--color-warning-rgb: 255, 213, 52;
|
|
245
|
+
--color-warning-contrast: #000000;
|
|
246
|
+
--color-warning-contrast-rgb: 0, 0, 0;
|
|
247
|
+
--color-warning-shade: #e0bb2e;
|
|
248
|
+
--color-warning-tint: #ffd948;
|
|
249
|
+
|
|
250
|
+
--color-danger: #ff4961;
|
|
251
|
+
--color-danger-rgb: 255, 73, 97;
|
|
252
|
+
--color-danger-contrast: #ffffff;
|
|
253
|
+
--color-danger-contrast-rgb: 255, 255, 255;
|
|
254
|
+
--color-danger-shade: #e04055;
|
|
255
|
+
--color-danger-tint: #ff5b71;
|
|
256
|
+
|
|
257
|
+
--color-dark: #f4f5f8;
|
|
258
|
+
--color-dark-rgb: 244, 245, 248;
|
|
259
|
+
--color-dark-contrast: #000000;
|
|
260
|
+
--color-dark-contrast-rgb: 0, 0, 0;
|
|
261
|
+
--color-dark-shade: #d7d8da;
|
|
262
|
+
--color-dark-tint: #f5f6f9;
|
|
263
|
+
|
|
264
|
+
--color-medium: #989aa2;
|
|
265
|
+
--color-medium-rgb: 152, 154, 162;
|
|
266
|
+
--color-medium-contrast: #000000;
|
|
267
|
+
--color-medium-contrast-rgb: 0, 0, 0;
|
|
268
|
+
--color-medium-shade: #86888f;
|
|
269
|
+
--color-medium-tint: #a2a4ab;
|
|
270
|
+
|
|
271
|
+
--color-light: #222428;
|
|
272
|
+
--color-light-rgb: 34, 36, 40;
|
|
273
|
+
--color-light-contrast: #ffffff;
|
|
274
|
+
--color-light-contrast-rgb: 255, 255, 255;
|
|
275
|
+
--color-light-shade: #1e2023;
|
|
276
|
+
--color-light-tint: #383a3e;
|
|
277
|
+
}
|
package/src/theme.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createTheme } from '@mantine/core';
|
|
2
|
+
import type { PolisTheme } from '@polisplatform/react/theme/PolisTheme';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Mantine theme overrides for the Video Game Rankings application.
|
|
6
|
+
*
|
|
7
|
+
* Extracted verbatim from `apps/web/src/App.tsx` of the VGR repo. This is
|
|
8
|
+
* the same `mantineTheme` object that was passed to `<MantineProvider>`.
|
|
9
|
+
*
|
|
10
|
+
* Exported standalone for callers that consume the Mantine theme directly,
|
|
11
|
+
* and re-exported below at `theme.mantineTheme` so `<PolisProvider>` can
|
|
12
|
+
* forward it into Mantine.
|
|
13
|
+
*/
|
|
14
|
+
export const mantineTheme = createTheme({
|
|
15
|
+
primaryColor: 'blue',
|
|
16
|
+
fontFamily: 'Inter, sans-serif',
|
|
17
|
+
other: {
|
|
18
|
+
primaryShade: { light: 6, dark: 8 },
|
|
19
|
+
},
|
|
20
|
+
components: {
|
|
21
|
+
Table: {
|
|
22
|
+
styles: {
|
|
23
|
+
th: {
|
|
24
|
+
backgroundColor: 'var(--polis-color-surface-alt, #f8f9fa)',
|
|
25
|
+
borderBottom: '2px solid var(--polis-color-border, #dee2e6)',
|
|
26
|
+
padding: '1rem',
|
|
27
|
+
},
|
|
28
|
+
td: {
|
|
29
|
+
padding: '1rem',
|
|
30
|
+
},
|
|
31
|
+
tr: {
|
|
32
|
+
'&:hover': {
|
|
33
|
+
backgroundColor: 'var(--polis-color-surface-alt, #f8f9fa)',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `@polisplatform/theme-bootstrap` — the Polis token bundle that drives the
|
|
43
|
+
* VGR-flavored visual identity (Bootstrap-rooted SCSS palette + Mantine
|
|
44
|
+
* theme override).
|
|
45
|
+
*
|
|
46
|
+
* Pass this to `<PolisProvider theme={theme}>` from `@polisplatform/react`.
|
|
47
|
+
*
|
|
48
|
+
* The primary palette tracks the Mantine theme's `primaryColor: 'blue'`,
|
|
49
|
+
* which is what the actual Mantine surface renders in the VGR app. The
|
|
50
|
+
* other colour tokens align with Bootstrap 5 defaults.
|
|
51
|
+
*/
|
|
52
|
+
export const theme: PolisTheme = {
|
|
53
|
+
name: 'bootstrap',
|
|
54
|
+
|
|
55
|
+
colors: {
|
|
56
|
+
primary: '#228be6',
|
|
57
|
+
primaryHover: '#1c7ed6',
|
|
58
|
+
primaryActive: '#1971c2',
|
|
59
|
+
// Mantine blue[1] / blue[2] — light tints of the primary, used for
|
|
60
|
+
// hover/selected backgrounds on neutral surfaces.
|
|
61
|
+
primaryTint: '#d0ebff',
|
|
62
|
+
primarySubtle: '#a5d8ff',
|
|
63
|
+
// White reads cleanly on the blue[6] primary used by buttons / badges.
|
|
64
|
+
primaryContrast: '#ffffff',
|
|
65
|
+
surface: '#ffffff',
|
|
66
|
+
surfaceAlt: '#f8f9fa',
|
|
67
|
+
textPrimary: '#212529',
|
|
68
|
+
textMuted: '#6c757d',
|
|
69
|
+
border: '#dee2e6',
|
|
70
|
+
success: '#52ab58',
|
|
71
|
+
warning: '#ffc409',
|
|
72
|
+
danger: '#eb445a',
|
|
73
|
+
info: '#3298b3',
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Dark colour tokens. Surfaces track Bootstrap 5.3's dark theme
|
|
78
|
+
* (`--bs-body-bg` #212529 body, `--bs-tertiary-bg` #2b3035 elevated) so the
|
|
79
|
+
* SCSS surface stays in step with `data-bs-theme="dark"`. The primary
|
|
80
|
+
* lightens to Mantine blue[4] (#4dabf7) to hold contrast against the dark
|
|
81
|
+
* body; `primaryContrast` stays dark ink for filled buttons.
|
|
82
|
+
*/
|
|
83
|
+
dark: {
|
|
84
|
+
primary: '#4dabf7',
|
|
85
|
+
primaryHover: '#74c0fc',
|
|
86
|
+
primaryActive: '#a5d8ff',
|
|
87
|
+
// Deep blue backgrounds for subtle/selected states on dark surfaces.
|
|
88
|
+
primaryTint: '#1b3a5b',
|
|
89
|
+
primarySubtle: '#132840',
|
|
90
|
+
// Dark ink reads on the light-blue primary used for filled buttons.
|
|
91
|
+
primaryContrast: '#0b0d10',
|
|
92
|
+
surface: '#212529',
|
|
93
|
+
surfaceAlt: '#2b3035',
|
|
94
|
+
textPrimary: '#dee2e6',
|
|
95
|
+
textMuted: '#adb5bd',
|
|
96
|
+
border: '#495057',
|
|
97
|
+
success: '#69db7c',
|
|
98
|
+
warning: '#ffd43b',
|
|
99
|
+
danger: '#ff8787',
|
|
100
|
+
info: '#66d9e8',
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
fonts: {
|
|
104
|
+
body: 'Inter, sans-serif',
|
|
105
|
+
heading: 'Inter, sans-serif',
|
|
106
|
+
mono: '"SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
radius: {
|
|
110
|
+
sm: '2px',
|
|
111
|
+
md: '4px',
|
|
112
|
+
lg: '8px',
|
|
113
|
+
full: '9999px',
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
spacing: {
|
|
117
|
+
xs: '4px',
|
|
118
|
+
sm: '8px',
|
|
119
|
+
md: '16px',
|
|
120
|
+
lg: '24px',
|
|
121
|
+
xl: '32px',
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
mantineTheme,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default theme;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"noEmit": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|