feat(styles): add browser scss builder system
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
VITE_LAST_BUILD_DATE=20260623
|
VITE_LAST_BUILD_DATE=20260625
|
||||||
VITE_LAST_SUCCESSFUL_COMMIT=a89f454
|
VITE_LAST_SUCCESSFUL_COMMIT=41e5f31
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ __tests__/ # Jest tests
|
|||||||
- Change Log content is sourced from `src/data/toolkit/changelog.json`.
|
- Change Log content is sourced from `src/data/toolkit/changelog.json`.
|
||||||
- Credits Toolkit data is sourced from `src/data/toolkit/credits.json` and synced through the socket server.
|
- Credits Toolkit data is sourced from `src/data/toolkit/credits.json` and synced through the socket server.
|
||||||
- Toolkit Images and Audio records can upload files through the socket into `src/assets/images/uploads/` and `src/assets/music/uploads/`.
|
- Toolkit Images and Audio records can upload files through the socket into `src/assets/images/uploads/` and `src/assets/music/uploads/`.
|
||||||
|
- Local Toolkit authoring uses `http://127.0.0.1:5175` by default so it does not collide with deployed socket automation.
|
||||||
- Deployed Toolkit authoring uses `http://bone-kingdom.tabitha.tealthrone:5174` and intentionally runs from the shared repo workspace so edits update development JSON/assets while coding continues.
|
- Deployed Toolkit authoring uses `http://bone-kingdom.tabitha.tealthrone:5174` and intentionally runs from the shared repo workspace so edits update development JSON/assets while coding continues.
|
||||||
- Toolkit seed datasets live under `src/data/toolkit/` and are exported through `src/data/index.ts`.
|
- Toolkit seed datasets live under `src/data/toolkit/` and are exported through `src/data/index.ts`.
|
||||||
- Shared data interfaces live under `src/data/types/`.
|
- Shared data interfaces live under `src/data/types/`.
|
||||||
@@ -125,6 +126,17 @@ __tests__/ # Jest tests
|
|||||||
- Browser SCSS: `src/assets/scss/`
|
- Browser SCSS: `src/assets/scss/`
|
||||||
- Add or update asset type declarations in `src/types/assets.d.ts` when needed.
|
- Add or update asset type declarations in `src/types/assets.d.ts` when needed.
|
||||||
|
|
||||||
|
### Work with browser SCSS
|
||||||
|
|
||||||
|
1. Use `src/assets/scss/index.scss` as the only browser SCSS entrypoint.
|
||||||
|
2. Add design tokens and CSS custom properties in `__variables.scss`.
|
||||||
|
3. Add shared browser mixins in `__mixins.scss`.
|
||||||
|
4. Keep reset, root, and browser-wide element rules in `__globals.scss` and `__scrollbars.scss`.
|
||||||
|
5. Put reusable `.blb-*` class builders in the concern-specific partials: `__typography.scss`, `__layout.scss`, `__surfaces.scss`, `__buttons.scss`, `__forms.scss`, and `__toolkit.scss`.
|
||||||
|
6. Do not add ad hoc browser CSS in screen files. Add or extend a builder class in `src/assets/scss/`, then reference that class from the browser-only surface that needs it.
|
||||||
|
7. Shared React Native screens and native-compatible components still use `StyleSheet.create()` unless a task explicitly asks for a web-only class-based migration.
|
||||||
|
8. Keep browser-only class usage, DOM APIs, and web-specific styling assumptions inside `.web.tsx` files, `src/web/`, or explicitly browser-only surfaces.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Starts the Vite browser app on `http://127.0.0.1:5173`.
|
|||||||
npm run dev:toolkit
|
npm run dev:toolkit
|
||||||
```
|
```
|
||||||
|
|
||||||
Starts the local Toolkit socket server on `http://127.0.0.1:5174`.
|
Starts the local Toolkit socket server on `http://127.0.0.1:5175`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev:all
|
npm run dev:all
|
||||||
@@ -121,7 +121,7 @@ The Toolkit contains socket-backed structured forms for volatile gameplay system
|
|||||||
Socket health check:
|
Socket health check:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://127.0.0.1:5174/health
|
curl http://127.0.0.1:5175/health
|
||||||
```
|
```
|
||||||
|
|
||||||
## Shared Deploy Toolkit Socket
|
## Shared Deploy Toolkit Socket
|
||||||
@@ -147,7 +147,9 @@ TOOLKIT_SOCKET_HOST=0.0.0.0 npm run deploy:toolkit
|
|||||||
|
|
||||||
## Assets
|
## Assets
|
||||||
|
|
||||||
Image assets live in `src/assets/images/`. Fonts live in `src/assets/fonts/`. Music lives in `src/assets/music/`. Browser SCSS entrypoints live in `src/assets/scss/`.
|
Image assets live in `src/assets/images/`. Fonts live in `src/assets/fonts/`. Music lives in `src/assets/music/`. Browser SCSS builders live in `src/assets/scss/`.
|
||||||
|
|
||||||
|
`src/assets/scss/index.scss` is the only browser SCSS entrypoint. Builder partials separate tokens, mixins, globals, scrollbars, typography, layout, surfaces, buttons, forms, and Toolkit-specific class systems. Browser-only UI should reference reusable `.blb-*` classes from those builders instead of adding ad hoc CSS in feature files.
|
||||||
|
|
||||||
The browser favicon is `src/assets/images/favicon.svg`.
|
The browser favicon is `src/assets/images/favicon.svg`.
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ describe('toolkit socket client configuration', () => {
|
|||||||
delete process.env.TOOLKIT_SOCKET_URL;
|
delete process.env.TOOLKIT_SOCKET_URL;
|
||||||
setTestLocation('localhost');
|
setTestLocation('localhost');
|
||||||
|
|
||||||
expect(getToolkitSocketUrl()).toBe('http://127.0.0.1:5174');
|
expect(getToolkitSocketUrl()).toBe('http://127.0.0.1:5175');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('derives the deployed socket URL from the current browser host', () => {
|
it('derives the deployed socket URL from the current browser host', () => {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Vite resolves `.web.ts` before `.ts` (see `vite.config.ts` `resolve.extensions`)
|
|||||||
Shared stores import `./persistStorage`; the correct implementation is picked per bundler.
|
Shared stores import `./persistStorage`; the correct implementation is picked per bundler.
|
||||||
|
|
||||||
### Web entry
|
### Web entry
|
||||||
`src/web/main.tsx` registers `App` via `AppRegistry.runApplication` against `#root` in `index.html`. Global styles: `src/assets/scss/index.scss`; image assets live under `src/assets/images/`.
|
`src/web/main.tsx` registers `App` via `AppRegistry.runApplication` against `#root` in `index.html`. Browser styles enter through `src/assets/scss/index.scss`, which composes builder partials for variables, mixins, globals, scrollbars, typography, layout, surfaces, buttons, forms, and Toolkit classes. Image assets live under `src/assets/images/`.
|
||||||
|
|
||||||
### Electron shell
|
### Electron shell
|
||||||
- `electron/main.ts` — `BrowserWindow`, context isolation, no node integration
|
- `electron/main.ts` — `BrowserWindow`, context isolation, no node integration
|
||||||
|
|||||||
+15
-3
@@ -116,7 +116,7 @@
|
|||||||
"runtime": "Node + Socket.IO",
|
"runtime": "Node + Socket.IO",
|
||||||
"entry": "socket/server.mjs",
|
"entry": "socket/server.mjs",
|
||||||
"devCommand": "npm run dev:toolkit",
|
"devCommand": "npm run dev:toolkit",
|
||||||
"healthUrl": "http://127.0.0.1:5174/health",
|
"healthUrl": "http://127.0.0.1:5175/health",
|
||||||
"deployCommand": "npm run deploy:toolkit",
|
"deployCommand": "npm run deploy:toolkit",
|
||||||
"deployHealthUrl": "http://bone-kingdom.tabitha.tealthrone:5174/health",
|
"deployHealthUrl": "http://bone-kingdom.tabitha.tealthrone:5174/health",
|
||||||
"primary": true
|
"primary": true
|
||||||
@@ -255,6 +255,18 @@
|
|||||||
"fonts": "src/assets/fonts/",
|
"fonts": "src/assets/fonts/",
|
||||||
"music": "src/assets/music/",
|
"music": "src/assets/music/",
|
||||||
"scss": "src/assets/scss/",
|
"scss": "src/assets/scss/",
|
||||||
|
"scssBuilders": [
|
||||||
|
"src/assets/scss/__variables.scss",
|
||||||
|
"src/assets/scss/__mixins.scss",
|
||||||
|
"src/assets/scss/__globals.scss",
|
||||||
|
"src/assets/scss/__scrollbars.scss",
|
||||||
|
"src/assets/scss/__typography.scss",
|
||||||
|
"src/assets/scss/__layout.scss",
|
||||||
|
"src/assets/scss/__surfaces.scss",
|
||||||
|
"src/assets/scss/__buttons.scss",
|
||||||
|
"src/assets/scss/__forms.scss",
|
||||||
|
"src/assets/scss/__toolkit.scss"
|
||||||
|
],
|
||||||
"favicon": "src/assets/images/favicon.svg"
|
"favicon": "src/assets/images/favicon.svg"
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
@@ -465,7 +477,7 @@
|
|||||||
],
|
],
|
||||||
"verify": [
|
"verify": [
|
||||||
"npm run test -- --runInBand",
|
"npm run test -- --runInBand",
|
||||||
"npm run dev:toolkit and check http://127.0.0.1:5174/health"
|
"npm run dev:toolkit and check http://127.0.0.1:5175/health"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mobile": {
|
"mobile": {
|
||||||
@@ -621,7 +633,7 @@
|
|||||||
"socketChanges": [
|
"socketChanges": [
|
||||||
"npm run test -- --runInBand",
|
"npm run test -- --runInBand",
|
||||||
"npm run dev:toolkit",
|
"npm run dev:toolkit",
|
||||||
"curl http://127.0.0.1:5174/health",
|
"curl http://127.0.0.1:5175/health",
|
||||||
"curl http://bone-kingdom.tabitha.tealthrone:5174/health"
|
"curl http://bone-kingdom.tabitha.tealthrone:5174/health"
|
||||||
],
|
],
|
||||||
"mobileChanges": ["npm run lint", "npm run test -- --runInBand"],
|
"mobileChanges": ["npm run lint", "npm run test -- --runInBand"],
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "BlbThroneOfTheBoneKing",
|
"name": "BlbThroneOfTheBoneKing",
|
||||||
"version": "0.0.5",
|
"version": "0.0.7",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "BlbThroneOfTheBoneKing",
|
"name": "BlbThroneOfTheBoneKing",
|
||||||
"version": "0.0.5",
|
"version": "0.0.7",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-async-storage/async-storage": "^3.1.1",
|
"@react-native-async-storage/async-storage": "^3.1.1",
|
||||||
"@react-native/new-app-screen": "0.85.3",
|
"@react-native/new-app-screen": "0.85.3",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "BlbThroneOfTheBoneKing",
|
"name": "BlbThroneOfTheBoneKing",
|
||||||
"version": "0.0.5",
|
"version": "0.0.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist/electron/main.js",
|
"main": "dist/electron/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+2
-2
@@ -6,13 +6,13 @@ The Toolkit socket is a local/shared Socket.IO authoring server for browser-only
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev:toolkit
|
npm run dev:toolkit
|
||||||
curl http://127.0.0.1:5174/health
|
curl http://127.0.0.1:5175/health
|
||||||
```
|
```
|
||||||
|
|
||||||
Default local settings:
|
Default local settings:
|
||||||
|
|
||||||
- host: `127.0.0.1`
|
- host: `127.0.0.1`
|
||||||
- port: `5174`
|
- port: `5175`
|
||||||
- CORS origin: `http://127.0.0.1:5173`
|
- CORS origin: `http://127.0.0.1:5173`
|
||||||
|
|
||||||
## Shared Deployment
|
## Shared Deployment
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { promisify } from 'node:util';
|
|||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
const ports = [
|
const ports = [
|
||||||
process.env.WEB_DEV_PORT ?? '5173',
|
process.env.WEB_DEV_PORT ?? '5173',
|
||||||
process.env.TOOLKIT_SOCKET_PORT ?? '5174',
|
process.env.TOOLKIT_SOCKET_PORT ?? '5175',
|
||||||
];
|
];
|
||||||
|
|
||||||
async function getPortProcessIds(port) {
|
async function getPortProcessIds(port) {
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ const require = createRequire(import.meta.url);
|
|||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
const defaultWebOrigin = 'http://127.0.0.1:5173';
|
const defaultWebOrigin = 'http://127.0.0.1:5173';
|
||||||
const host = process.env.TOOLKIT_SOCKET_HOST ?? '127.0.0.1';
|
const host = process.env.TOOLKIT_SOCKET_HOST ?? '127.0.0.1';
|
||||||
const port = Number.parseInt(process.env.TOOLKIT_SOCKET_PORT ?? '5174', 10);
|
const port = Number.parseInt(process.env.TOOLKIT_SOCKET_PORT ?? '5175', 10);
|
||||||
const allowedOrigins = (
|
const allowedOrigins = (
|
||||||
process.env.TOOLKIT_SOCKET_CORS_ORIGIN ?? defaultWebOrigin
|
process.env.TOOLKIT_SOCKET_CORS_ORIGIN ?? defaultWebOrigin
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
@use './__mixins' as mixins;
|
||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
.blb-button {
|
||||||
|
@include mixins.control-reset;
|
||||||
|
@include mixins.gold-border;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
background: variables.$color-surface-strong;
|
||||||
|
border-radius: variables.$radius-control;
|
||||||
|
color: variables.$color-text;
|
||||||
|
display: inline-flex;
|
||||||
|
font-family: variables.$font-title;
|
||||||
|
gap: variables.$space-2;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: variables.$control-height-md;
|
||||||
|
padding: variables.$space-2 variables.$space-3;
|
||||||
|
text-align: center;
|
||||||
|
transition:
|
||||||
|
background-color 120ms ease,
|
||||||
|
border-color 120ms ease,
|
||||||
|
color 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button:hover {
|
||||||
|
background: #2c2c2c;
|
||||||
|
border-color: variables.$color-gold;
|
||||||
|
color: variables.$color-gold-strong;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button:focus-visible {
|
||||||
|
@include mixins.focus-ring;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button:disabled,
|
||||||
|
.blb-button[aria-disabled='true'] {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--toolkit {
|
||||||
|
background: variables.$color-surface-warm;
|
||||||
|
border-color: variables.$color-gold;
|
||||||
|
color: variables.$color-gold-strong;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--danger {
|
||||||
|
border-color: variables.$color-danger;
|
||||||
|
color: #ffd8d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--ghost {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--sharp {
|
||||||
|
@include mixins.sharp-control;
|
||||||
|
|
||||||
|
border-radius: variables.$radius-sharp;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--compact {
|
||||||
|
min-height: variables.$control-height-sm;
|
||||||
|
padding: variables.$space-1 variables.$space-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button--icon {
|
||||||
|
aspect-ratio: 1;
|
||||||
|
min-height: variables.$control-height-sm;
|
||||||
|
padding: 0;
|
||||||
|
width: variables.$control-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button-group {
|
||||||
|
align-items: stretch;
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button-group .blb-button {
|
||||||
|
border-radius: 0;
|
||||||
|
margin-left: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-button-group .blb-button:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
@use './__mixins' as mixins;
|
||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
.blb-field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: variables.$space-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-field-row {
|
||||||
|
align-items: center;
|
||||||
|
display: grid;
|
||||||
|
gap: variables.$space-2;
|
||||||
|
grid-template-columns: minmax(120px, 0.4fr) minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-control-label {
|
||||||
|
color: variables.$color-gold;
|
||||||
|
font-size: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-input,
|
||||||
|
.blb-select,
|
||||||
|
.blb-textarea {
|
||||||
|
@include mixins.gold-border;
|
||||||
|
|
||||||
|
background: #0d0f11;
|
||||||
|
border-radius: variables.$radius-control;
|
||||||
|
color: variables.$color-text;
|
||||||
|
min-height: variables.$control-height-md;
|
||||||
|
padding: variables.$space-2;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-input:focus,
|
||||||
|
.blb-select:focus,
|
||||||
|
.blb-textarea:focus {
|
||||||
|
@include mixins.focus-ring;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-textarea {
|
||||||
|
min-height: 84px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-range {
|
||||||
|
accent-color: variables.$color-gold;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-checkbox {
|
||||||
|
accent-color: variables.$color-gold;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-form-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: variables.$space-3;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-icon-action {
|
||||||
|
@include mixins.control-reset;
|
||||||
|
@include mixins.gold-border;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
background: variables.$color-surface-strong;
|
||||||
|
border-radius: variables.$radius-control;
|
||||||
|
color: variables.$color-gold-strong;
|
||||||
|
display: inline-flex;
|
||||||
|
height: variables.$control-height-sm;
|
||||||
|
justify-content: center;
|
||||||
|
width: variables.$control-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-icon-action:hover,
|
||||||
|
.blb-icon-action:focus-visible {
|
||||||
|
@include mixins.focus-ring;
|
||||||
|
}
|
||||||
@@ -1,19 +1,5 @@
|
|||||||
@use './__variables' as variables;
|
@use './__variables' as variables;
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'MiTicaRegular';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: url('../fonts/mitica/MiTicaRegular.otf') format('opentype');
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'SingleDayRegular';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: url('../fonts/single-day/SingleDayRegular.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body,
|
body,
|
||||||
#root {
|
#root {
|
||||||
@@ -24,35 +10,25 @@ body,
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
background: variables.$color-page-background;
|
background: variables.$color-page-background;
|
||||||
font-family: 'SingleDayRegular', sans-serif;
|
color: variables.$color-text;
|
||||||
|
font-family: variables.$font-body;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
*,
|
||||||
scrollbar-color: #d6b25e #111315;
|
*::before,
|
||||||
scrollbar-width: thin;
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
button,
|
||||||
height: 10px;
|
input,
|
||||||
width: 10px;
|
select,
|
||||||
}
|
textarea {
|
||||||
|
font: inherit;
|
||||||
*::-webkit-scrollbar-track {
|
|
||||||
background: #111315;
|
|
||||||
border-left: 1px solid #2d2f32;
|
|
||||||
}
|
|
||||||
|
|
||||||
*::-webkit-scrollbar-thumb {
|
|
||||||
background: #3a3120;
|
|
||||||
border: 1px solid #d6b25e;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
*::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #4a3a22;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
.blb-fill {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-page {
|
||||||
|
background: variables.$color-page-background;
|
||||||
|
color: variables.$color-text;
|
||||||
|
min-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-landscape-stage {
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-stack {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: variables.$space-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-stack--tight {
|
||||||
|
gap: variables.$space-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-cluster {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: variables.$space-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-split {
|
||||||
|
align-items: stretch;
|
||||||
|
display: flex;
|
||||||
|
gap: variables.$space-4;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-grid-2 {
|
||||||
|
display: grid;
|
||||||
|
gap: variables.$space-4;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-grid-3 {
|
||||||
|
display: grid;
|
||||||
|
gap: variables.$space-3;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolbar {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 0;
|
||||||
|
min-height: variables.$control-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolbar-spacer {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-fixed-bottom-right {
|
||||||
|
bottom: variables.$space-3;
|
||||||
|
position: fixed;
|
||||||
|
right: variables.$space-3;
|
||||||
|
z-index: variables.$z-status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
@mixin focus-ring {
|
||||||
|
outline: 2px solid variables.$color-gold-strong;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin control-reset {
|
||||||
|
appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
color: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
font: inherit;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin gold-border($color: variables.$color-border) {
|
||||||
|
border: 1px solid $color;
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(214, 178, 94, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin panel-surface {
|
||||||
|
@include gold-border;
|
||||||
|
|
||||||
|
background: variables.$color-surface-raised;
|
||||||
|
border-radius: variables.$radius-panel;
|
||||||
|
box-shadow: 0 16px 40px variables.$color-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sharp-control {
|
||||||
|
border-radius: variables.$radius-sharp;
|
||||||
|
min-height: variables.$control-height-sm;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
* {
|
||||||
|
scrollbar-color: variables.$color-gold #111315;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background: #111315;
|
||||||
|
border-left: 1px solid #2d2f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background: #3a3120;
|
||||||
|
border: 1px solid variables.$color-gold;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #4a3a22;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
@use './__mixins' as mixins;
|
||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
.blb-panel {
|
||||||
|
@include mixins.panel-surface;
|
||||||
|
|
||||||
|
padding: variables.$space-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-panel--dense {
|
||||||
|
padding: variables.$space-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-panel--flat {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-card {
|
||||||
|
@include mixins.gold-border;
|
||||||
|
|
||||||
|
background: variables.$color-surface;
|
||||||
|
border-radius: variables.$radius-control;
|
||||||
|
padding: variables.$space-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-frame {
|
||||||
|
@include mixins.gold-border(variables.$color-border-strong);
|
||||||
|
|
||||||
|
background: rgba(5, 6, 7, 0.72);
|
||||||
|
border-radius: variables.$radius-panel;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-divider {
|
||||||
|
background: variables.$color-border;
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-socket-dot {
|
||||||
|
border-radius: 999px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-socket-dot--connected {
|
||||||
|
background: variables.$color-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-socket-dot--connecting {
|
||||||
|
background: variables.$color-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-socket-dot--disconnected {
|
||||||
|
background: variables.$color-danger;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
@use './__mixins' as mixins;
|
||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
.blb-toolkit {
|
||||||
|
background: variables.$color-page-background;
|
||||||
|
color: variables.$color-text;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-toolbar {
|
||||||
|
align-items: stretch;
|
||||||
|
background: #080a0b;
|
||||||
|
border-bottom: 1px solid variables.$color-border;
|
||||||
|
display: flex;
|
||||||
|
min-height: variables.$control-height-sm;
|
||||||
|
z-index: variables.$z-toolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-window {
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
padding: variables.$space-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-record-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: variables.$space-1;
|
||||||
|
min-width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-record {
|
||||||
|
@include mixins.gold-border;
|
||||||
|
|
||||||
|
background: variables.$color-surface;
|
||||||
|
border-radius: variables.$radius-control;
|
||||||
|
color: variables.$color-text;
|
||||||
|
padding: variables.$space-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-record--active {
|
||||||
|
background: variables.$color-surface-warm;
|
||||||
|
border-color: variables.$color-gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-editor {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-toolkit-status {
|
||||||
|
align-items: center;
|
||||||
|
bottom: variables.$space-2;
|
||||||
|
display: inline-flex;
|
||||||
|
gap: variables.$space-1;
|
||||||
|
position: fixed;
|
||||||
|
right: variables.$space-2;
|
||||||
|
z-index: variables.$z-status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
@use './__variables' as variables;
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'MiTicaRegular';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
src: url('../fonts/mitica/MiTicaRegular.otf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'SingleDayRegular';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
src: url('../fonts/single-day/SingleDayRegular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-font-title {
|
||||||
|
font-family: variables.$font-title;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-font-body {
|
||||||
|
font-family: variables.$font-body;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-heading-xl,
|
||||||
|
.blb-heading-lg,
|
||||||
|
.blb-heading-md,
|
||||||
|
.blb-control-label {
|
||||||
|
color: variables.$color-text;
|
||||||
|
font-family: variables.$font-title;
|
||||||
|
letter-spacing: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-heading-xl {
|
||||||
|
font-size: 42px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-heading-lg {
|
||||||
|
font-size: 30px;
|
||||||
|
line-height: 1.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-heading-md {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-body-copy {
|
||||||
|
color: variables.$color-text;
|
||||||
|
font-family: variables.$font-body;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.35;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-small-copy,
|
||||||
|
.blb-kicker {
|
||||||
|
color: variables.$color-text-muted;
|
||||||
|
font-family: variables.$font-body;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-kicker {
|
||||||
|
color: variables.$color-gold;
|
||||||
|
font-family: variables.$font-title;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-text-gold {
|
||||||
|
color: variables.$color-gold-strong;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-text-muted {
|
||||||
|
color: variables.$color-text-muted;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blb-text-dim {
|
||||||
|
color: variables.$color-text-dim;
|
||||||
|
}
|
||||||
@@ -1 +1,62 @@
|
|||||||
|
$font-title: 'MiTicaRegular', serif;
|
||||||
|
$font-body: 'SingleDayRegular', sans-serif;
|
||||||
|
|
||||||
$color-page-background: #050607;
|
$color-page-background: #050607;
|
||||||
|
$color-surface: #111518;
|
||||||
|
$color-surface-raised: #171b1f;
|
||||||
|
$color-surface-strong: #232323;
|
||||||
|
$color-surface-warm: #3a2a12;
|
||||||
|
$color-text: #f8f1dd;
|
||||||
|
$color-text-muted: #b9ad96;
|
||||||
|
$color-text-dim: #7d745f;
|
||||||
|
$color-gold: #d6b25e;
|
||||||
|
$color-gold-strong: #f5d67b;
|
||||||
|
$color-gold-dim: #80642f;
|
||||||
|
$color-border: #3b3326;
|
||||||
|
$color-border-strong: #72582b;
|
||||||
|
$color-danger: #b44747;
|
||||||
|
$color-success: #61d47a;
|
||||||
|
$color-warning: #d7bb52;
|
||||||
|
$color-shadow: rgba(0, 0, 0, 0.42);
|
||||||
|
|
||||||
|
$space-1: 4px;
|
||||||
|
$space-2: 8px;
|
||||||
|
$space-3: 12px;
|
||||||
|
$space-4: 16px;
|
||||||
|
$space-5: 20px;
|
||||||
|
$space-6: 24px;
|
||||||
|
$space-8: 32px;
|
||||||
|
|
||||||
|
$radius-sharp: 0;
|
||||||
|
$radius-control: 4px;
|
||||||
|
$radius-panel: 6px;
|
||||||
|
|
||||||
|
$control-height-sm: 28px;
|
||||||
|
$control-height-md: 38px;
|
||||||
|
$control-height-lg: 46px;
|
||||||
|
|
||||||
|
$z-overlay: 20;
|
||||||
|
$z-toolbar: 30;
|
||||||
|
$z-status: 40;
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--blb-font-title: #{$font-title};
|
||||||
|
--blb-font-body: #{$font-body};
|
||||||
|
--blb-color-page-background: #{$color-page-background};
|
||||||
|
--blb-color-surface: #{$color-surface};
|
||||||
|
--blb-color-surface-raised: #{$color-surface-raised};
|
||||||
|
--blb-color-surface-strong: #{$color-surface-strong};
|
||||||
|
--blb-color-surface-warm: #{$color-surface-warm};
|
||||||
|
--blb-color-text: #{$color-text};
|
||||||
|
--blb-color-text-muted: #{$color-text-muted};
|
||||||
|
--blb-color-text-dim: #{$color-text-dim};
|
||||||
|
--blb-color-gold: #{$color-gold};
|
||||||
|
--blb-color-gold-strong: #{$color-gold-strong};
|
||||||
|
--blb-color-gold-dim: #{$color-gold-dim};
|
||||||
|
--blb-color-border: #{$color-border};
|
||||||
|
--blb-color-border-strong: #{$color-border-strong};
|
||||||
|
--blb-color-danger: #{$color-danger};
|
||||||
|
--blb-color-success: #{$color-success};
|
||||||
|
--blb-color-warning: #{$color-warning};
|
||||||
|
--blb-shadow: #{$color-shadow};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,13 @@
|
|||||||
|
// Browser style builder entrypoint.
|
||||||
|
// Add new web class systems as partials here; keep component code referencing
|
||||||
|
// the generated .blb-* classes instead of defining ad hoc browser CSS.
|
||||||
|
@use './__variables';
|
||||||
|
@use './__mixins';
|
||||||
|
@use './__typography';
|
||||||
@use './__globals';
|
@use './__globals';
|
||||||
|
@use './__scrollbars';
|
||||||
|
@use './__layout';
|
||||||
|
@use './__surfaces';
|
||||||
|
@use './__buttons';
|
||||||
|
@use './__forms';
|
||||||
|
@use './__toolkit';
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"id": "browser-scss-builder-system",
|
||||||
|
"version": "0.0.5-20260625-local",
|
||||||
|
"createdAt": "2026-06-25",
|
||||||
|
"title": "Browser SCSS Builder System",
|
||||||
|
"summary": "Added a separated browser styling builder layer and moved local Toolkit socket defaults away from the deployed socket port.",
|
||||||
|
"changes": [
|
||||||
|
"Added SCSS builder partials for variables, mixins, typography, layout, surfaces, buttons, forms, scrollbars, and Toolkit-specific classes.",
|
||||||
|
"Documented the styling boundary between browser class builders and native-compatible React Native StyleSheet usage.",
|
||||||
|
"Changed the local Toolkit socket default port to 5175 while keeping deployed Toolkit automation on 5174."
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "woodpecker-gitea-endpoint-fix",
|
"id": "woodpecker-gitea-endpoint-fix",
|
||||||
"version": "0.0.5-20260624-local",
|
"version": "0.0.5-20260624-local",
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ type ToolkitAssetUploadResponse =
|
|||||||
| ToolkitAssetUploadSuccessResponse
|
| ToolkitAssetUploadSuccessResponse
|
||||||
| ToolkitAssetUploadErrorResponse;
|
| ToolkitAssetUploadErrorResponse;
|
||||||
|
|
||||||
const defaultToolkitSocketUrl = 'http://127.0.0.1:5174';
|
const defaultToolkitSocketUrl = 'http://127.0.0.1:5175';
|
||||||
|
const deployedToolkitSocketPort = '5174';
|
||||||
const toolkitSocketTimeoutMs = 5000;
|
const toolkitSocketTimeoutMs = 5000;
|
||||||
|
|
||||||
let toolkitSocket: Socket | null = null;
|
let toolkitSocket: Socket | null = null;
|
||||||
@@ -112,7 +113,7 @@ function getBrowserToolkitSocketUrl() {
|
|||||||
return defaultToolkitSocketUrl;
|
return defaultToolkitSocketUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${location.protocol}//${location.hostname}:5174`;
|
return `${location.protocol}//${location.hostname}:${deployedToolkitSocketPort}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getToolkitSocketUrl() {
|
export function getToolkitSocketUrl() {
|
||||||
|
|||||||
Reference in New Issue
Block a user