P11: Loch design system — rebrand, font swap, --ds- prefix #56
143
README.md
143
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Self-hosted infrastructure stack with GPU support, S3-compatible storage, Git server with container registry, CI/CD, data lakehouse, observability, documentation, and research tools. All services share a unified retro "throwback" theme injected via Traefik middleware.
|
Self-hosted infrastructure stack with GPU support, S3-compatible storage, Git server with container registry, CI/CD, data lakehouse, observability, documentation, and research tools. All services share a unified deep-navy design system ("loch") injected via Traefik middleware.
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
|
|
||||||
@@ -81,28 +81,28 @@ Routes are defined in `traefik/dynamic/services.yml` using Go templates with Spr
|
|||||||
"gitea" (dict "port" "3000" "theme" true "mw" "secure-headers")
|
"gitea" (dict "port" "3000" "theme" true "mw" "secure-headers")
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`theme: true`** applies the `inject-throwback` middleware (injects favicon + CSS via HTML rewrite)
|
- **`theme: true`** applies the `inject-loch` middleware (injects favicon + CSS via HTML rewrite)
|
||||||
- **`theme: false`** skips injection (API-only services like Nessie, Polaris, Loki)
|
- **`theme: false`** skips injection (API-only services like Nessie, Polaris, Loki)
|
||||||
- **`mw`** is a comma-separated list of additional middlewares (`secure-headers`, `local-only`, `infra-headers`)
|
- **`mw`** is a comma-separated list of additional middlewares (`secure-headers`, `local-only`, `infra-headers`)
|
||||||
- **`subdomain`** overrides the FQDN prefix (e.g. `woodpecker-server` → `ci.homelab.fhirworx.io`)
|
- **`subdomain`** overrides the FQDN prefix (e.g. `woodpecker-server` → `ci.homelab.fhirworx.io`)
|
||||||
|
|
||||||
To add a new service, add one line to the `$reef` dict and a service block to `compose.yml`.
|
To add a new service, add one line to the `$reef` dict and a service block to `compose.yml`.
|
||||||
|
|
||||||
### Throwback Theme
|
### Loch Design System
|
||||||
|
|
||||||
All HTML-serving services get a unified retro theme via the `inject-throwback` Traefik middleware, which uses the [rewrite-body](https://github.com/packruler/rewrite-body) plugin to inject `<link>` tags before `</head>`:
|
All HTML-serving services get a unified deep-navy design system via the `inject-loch` Traefik middleware, which uses the [rewrite-body](https://github.com/packruler/rewrite-body) plugin to inject `<link>` tags before `</head>`:
|
||||||
|
|
||||||
- **`fav32.png`** — 32x32 PNG favicon served from the dashboard container
|
- **`fav32.png`** — 32x32 PNG favicon served from the dashboard container
|
||||||
- **`throwback.css`** — Global CSS overrides (colors, fonts, borders)
|
- **`loch.css`** — Global CSS overrides (colors, fonts, borders)
|
||||||
- **`inject.css`** — Served as `throwback.css`, hides service-specific logos and applies the palette
|
- **`inject.css`** — Served as `loch.css`, hides service-specific logos and applies the palette
|
||||||
|
|
||||||
Per-service CSS files handle service-specific overrides:
|
Per-service CSS files handle service-specific overrides:
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `styles/inject.css` | Global throwback palette + logo hiding (served as `throwback.css`) |
|
| `styles/inject.css` | Global loch palette + logo hiding (served as `loch.css`) |
|
||||||
| `styles/dashboard.css` | Dashboard tile grid layout |
|
| `styles/dashboard.css` | Dashboard tile grid layout |
|
||||||
| `styles/gitea.css` | Gitea theme (registered as `throwback` in Gitea UI settings) |
|
| `styles/gitea.css` | Gitea theme (registered as `loch` in Gitea UI settings) |
|
||||||
| `styles/woodpecker.css` | Woodpecker custom CSS (via `WOODPECKER_CUSTOM_CSS_FILE`) |
|
| `styles/woodpecker.css` | Woodpecker custom CSS (via `WOODPECKER_CUSTOM_CSS_FILE`) |
|
||||||
| `styles/marimo.css` | Marimo notebook theme |
|
| `styles/marimo.css` | Marimo notebook theme |
|
||||||
| `styles/fav32.png` | 32x32 PNG favicon (canonical, injected by Traefik) |
|
| `styles/fav32.png` | 32x32 PNG favicon (canonical, injected by Traefik) |
|
||||||
@@ -173,114 +173,44 @@ EOF
|
|||||||
```bash
|
```bash
|
||||||
docker compose up -d postgres rustfs traefik
|
docker compose up -d postgres rustfs traefik
|
||||||
|
|
||||||
# Bootstrap: creates DB roles, databases, derives all credentials, writes .env
|
# Bootstrap: creates DB roles, databases, RustFS buckets/users/IAM,
|
||||||
|
# derives all 21 credentials, rotates Grafana password, writes .env
|
||||||
ROOT_KEY=$ROOT_KEY uv run python -m api.auth bootstrap $(git rev-parse HEAD)
|
ROOT_KEY=$ROOT_KEY uv run python -m api.auth bootstrap $(git rev-parse HEAD)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Configure RustFS
|
Bootstrap automatically handles:
|
||||||
|
- PostgreSQL roles and databases (gitea, woodpecker, nessie, polaris)
|
||||||
|
- RustFS buckets (`gitea`, `gitea-lfs`, `gitea-packages`, `lakehouse`)
|
||||||
|
- RustFS IAM users and per-user policies from `rustfs/policies/`
|
||||||
|
- Gitea admin password rotation and API token creation
|
||||||
|
- Grafana admin password rotation (non-fatal if unreachable)
|
||||||
|
- Woodpecker CI secret provisioning
|
||||||
|
|
||||||
1. Access console at `s3console.homelab.fhirworx.io`
|
### 3. Start All Services
|
||||||
2. Create user `git` with S3 credentials matching `.env`
|
|
||||||
3. Create buckets: `gitea`, `gitea-lfs`, `gitea-packages`
|
|
||||||
4. Create user `nessie` with S3 credentials matching `.env`
|
|
||||||
5. Create bucket: `lakehouse`
|
|
||||||
6. Apply IAM policies to users (see below)
|
|
||||||
|
|
||||||
**Gitea IAM Policy:**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": [
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:GetBucketLocation",
|
|
||||||
"s3:ListBucket",
|
|
||||||
"s3:ListBucketMultipartUploads"
|
|
||||||
],
|
|
||||||
"Resource": [
|
|
||||||
"arn:aws:s3:::gitea",
|
|
||||||
"arn:aws:s3:::gitea-lfs",
|
|
||||||
"arn:aws:s3:::gitea-packages"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:GetObject",
|
|
||||||
"s3:PutObject",
|
|
||||||
"s3:DeleteObject",
|
|
||||||
"s3:ListMultipartUploadParts",
|
|
||||||
"s3:AbortMultipartUpload"
|
|
||||||
],
|
|
||||||
"Resource": [
|
|
||||||
"arn:aws:s3:::gitea/*",
|
|
||||||
"arn:aws:s3:::gitea-lfs/*",
|
|
||||||
"arn:aws:s3:::gitea-packages/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Nessie IAM Policy:**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": [
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:GetBucketLocation",
|
|
||||||
"s3:ListBucket",
|
|
||||||
"s3:ListBucketMultipartUploads"
|
|
||||||
],
|
|
||||||
"Resource": ["arn:aws:s3:::lakehouse"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Effect": "Allow",
|
|
||||||
"Action": [
|
|
||||||
"s3:GetObject",
|
|
||||||
"s3:PutObject",
|
|
||||||
"s3:DeleteObject",
|
|
||||||
"s3:ListMultipartUploadParts",
|
|
||||||
"s3:AbortMultipartUpload"
|
|
||||||
],
|
|
||||||
"Resource": ["arn:aws:s3:::lakehouse/*"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Start All Services
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Configure Gitea
|
### 4. Configure Gitea
|
||||||
|
|
||||||
1. Complete initial setup at `gitea.homelab.fhirworx.io`
|
1. Complete initial setup at `gitea.homelab.fhirworx.io`
|
||||||
2. Create organization `homelab`
|
2. Create organization `homelab`
|
||||||
3. Create repository `stack`
|
3. Create repository `stack`
|
||||||
4. Generate API token for container registry access
|
4. Create OAuth2 application for Woodpecker:
|
||||||
5. Create OAuth2 application for Woodpecker:
|
|
||||||
- Name: `Woodpecker CI`
|
- Name: `Woodpecker CI`
|
||||||
- Redirect URI: `http://ci.homelab.fhirworx.io/authorize`
|
- Redirect URI: `http://ci.homelab.fhirworx.io/authorize`
|
||||||
- Copy Client ID and Secret to `.env`
|
- Copy Client ID and Secret to `.env`
|
||||||
|
|
||||||
### 6. Configure Woodpecker Secrets
|
### 5. Configure Woodpecker Root Key
|
||||||
|
|
||||||
Add secrets in Woodpecker UI (`ci.homelab.fhirworx.io`):
|
Add one secret in Woodpecker UI (`ci.homelab.fhirworx.io`):
|
||||||
- `root_key` — The hex-encoded root key (enables auto-rotation on every deploy)
|
- `root_key` — The hex-encoded root key (enables auto-rotation on every deploy)
|
||||||
- `registry_user` — Gitea username
|
- `registry_user` — Gitea username
|
||||||
- `registry_pass` — Gitea token
|
|
||||||
- `s3_access_key` — RustFS access key
|
|
||||||
- `s3_secret_key` — RustFS secret key
|
|
||||||
|
|
||||||
### 7. Verify Services
|
All other Woodpecker secrets (`registry_pass`, `s3_access_key`, `s3_secret_key`, `gitea_token`, `gitea_url`) are provisioned automatically by `bootstrap` and rotated on each deploy by `provision`.
|
||||||
|
|
||||||
|
### 6. Verify Services
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check Traefik routes
|
# Check Traefik routes
|
||||||
@@ -346,7 +276,7 @@ The derivation uses two tiers:
|
|||||||
| **Bootstrap** | `b"bootstrap"` | Only when root key changes | Superuser passwords, OAuth2 app |
|
| **Bootstrap** | `b"bootstrap"` | Only when root key changes | Superuser passwords, OAuth2 app |
|
||||||
| **Service** | `commit_sha` | Every deploy | DB passwords, S3 keys, API tokens |
|
| **Service** | `commit_sha` | Every deploy | DB passwords, S3 keys, API tokens |
|
||||||
|
|
||||||
### Managed Credentials (18 derived, 2 skipped)
|
### Managed Credentials (19 derived, 2 skipped)
|
||||||
|
|
||||||
| Variable | Tier | Format | Backend |
|
| Variable | Tier | Format | Backend |
|
||||||
|----------|------|--------|---------|
|
|----------|------|--------|---------|
|
||||||
@@ -359,8 +289,9 @@ The derivation uses two tiers:
|
|||||||
| `RUSTFS_SECRET_KEY` | Service | hex | env only |
|
| `RUSTFS_SECRET_KEY` | Service | hex | env only |
|
||||||
| `GITEA_S3_*`, `NESSIE_S3_*`, `POLARIS_S3_*` | Service | hex | env only (aliases of RUSTFS) |
|
| `GITEA_S3_*`, `NESSIE_S3_*`, `POLARIS_S3_*` | Service | hex | env only (aliases of RUSTFS) |
|
||||||
| `WOODPECKER_AGENT_SECRET` | Service | hex | env only |
|
| `WOODPECKER_AGENT_SECRET` | Service | hex | env only |
|
||||||
|
| `STACK_API_SECRET` | Service | hex | env only |
|
||||||
| `POLARIS_ROOT_SECRET` | Service | password | env only |
|
| `POLARIS_ROOT_SECRET` | Service | password | env only |
|
||||||
| `GF_ADMIN_PASSWORD` | Service | password | env only |
|
| `GF_ADMIN_PASSWORD` | Service | password | Grafana (admin API) |
|
||||||
| `GITEA_ADMIN_PASSWORD` | Service | password | Gitea (change-password) |
|
| `GITEA_ADMIN_PASSWORD` | Service | password | Gitea (change-password) |
|
||||||
| `GITEA_TOKEN` | Service | — | Gitea (API token) |
|
| `GITEA_TOKEN` | Service | — | Gitea (API token) |
|
||||||
|
|
||||||
@@ -381,7 +312,15 @@ ROOT_KEY=$KEY uv run python -m api.auth derive $COMMIT_SHA --redact
|
|||||||
|
|
||||||
### Auto-Rotation via CI
|
### Auto-Rotation via CI
|
||||||
|
|
||||||
The `provision` step in `.woodpecker/deploy.yml` runs after every deploy, deriving fresh service-tier credentials from the commit SHA and rotating PostgreSQL passwords and Gitea tokens automatically.
|
The `provision` step in `.woodpecker/deploy.yml` runs after every deploy, deriving fresh service-tier credentials from the commit SHA and rotating PostgreSQL passwords, Gitea tokens, Grafana admin password, and Woodpecker CI secrets automatically.
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
**CI provision step fails with `No module named 'api'`**: The provision step needs `UV_PROJECT_ENVIRONMENT: .venv` and `UV_LINK_MODE: copy` in its environment block (matching the CI pipeline pattern). Without these, `uv run` creates a fresh venv in the CI container and doesn't find the installed project.
|
||||||
|
|
||||||
|
**Grafana password rotation fails**: This is non-fatal — bootstrap/provision will log a warning but continue. Check that Grafana is running and reachable at its internal URL. On first bootstrap with default `admin`/`admin` credentials, rotation should succeed. On subsequent provisions, the old password is read from `.env` before overwrite.
|
||||||
|
|
||||||
|
**RustFS bucket creation fails**: Ensure RustFS is running and the `RUSTFS_ACCESS_KEY`/`RUSTFS_SECRET_KEY` in `.env` match the root credentials configured in the RustFS container environment.
|
||||||
|
|
||||||
## Documentation Site
|
## Documentation Site
|
||||||
|
|
||||||
@@ -468,9 +407,9 @@ stack/
|
|||||||
├── .env # Environment variables (not in git)
|
├── .env # Environment variables (not in git)
|
||||||
├── README.md
|
├── README.md
|
||||||
├── styles/ # Centralized theme assets
|
├── styles/ # Centralized theme assets
|
||||||
│ ├── inject.css # Global throwback CSS (served as throwback.css)
|
│ ├── inject.css # Global loch CSS (served as loch.css)
|
||||||
│ ├── dashboard.css # Dashboard tile grid
|
│ ├── dashboard.css # Dashboard tile grid
|
||||||
│ ├── gitea.css # Gitea throwback theme
|
│ ├── gitea.css # Gitea loch theme
|
||||||
│ ├── woodpecker.css # Woodpecker custom CSS
|
│ ├── woodpecker.css # Woodpecker custom CSS
|
||||||
│ ├── marimo.css # Marimo notebook theme
|
│ ├── marimo.css # Marimo notebook theme
|
||||||
│ ├── fav32.png # 32x32 PNG favicon (canonical, injected by Traefik)
|
│ ├── fav32.png # 32x32 PNG favicon (canonical, injected by Traefik)
|
||||||
@@ -551,8 +490,8 @@ Custom images use the `fhirworx/<svc>:<sha>` naming convention locally. The regi
|
|||||||
echo "<GITEA_TOKEN>" | docker login localhost:3000 -u <username> --password-stdin
|
echo "<GITEA_TOKEN>" | docker login localhost:3000 -u <username> --password-stdin
|
||||||
|
|
||||||
# Tag and push
|
# Tag and push
|
||||||
docker tag fhirworx/<svc>:latest localhost:3000/fhirworx/<svc>:latest
|
docker tag fhirworx/<svc>:latest localhost:3000/homelab/<svc>:latest
|
||||||
docker push localhost:3000/fhirworx/<svc>:latest
|
docker push localhost:3000/homelab/<svc>:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Custom images: `notebooks`, `zotero`, `docs`. Compose resolves `fhirworx/<svc>:${COMMIT_SHA:-latest}`.
|
Custom images: `notebooks`, `zotero`, `docs`. Compose resolves `fhirworx/<svc>:${COMMIT_SHA:-latest}`.
|
||||||
|
|||||||
42
compose.yml
42
compose.yml
@@ -110,13 +110,13 @@ services:
|
|||||||
- GITEA__server__ROOT_URL=http://gitea.${DOMAIN:-homelab.fhirworx.io}/
|
- GITEA__server__ROOT_URL=http://gitea.${DOMAIN:-homelab.fhirworx.io}/
|
||||||
- GITEA__server__SSH_DOMAIN=${DOMAIN:-homelab.fhirworx.io}
|
- GITEA__server__SSH_DOMAIN=${DOMAIN:-homelab.fhirworx.io}
|
||||||
- GITEA__webhook__ALLOWED_HOST_LIST=woodpecker-server,ci.${DOMAIN:-homelab.fhirworx.io},${HOST_IP:-192.168.1.192},172.19.0.0/16
|
- GITEA__webhook__ALLOWED_HOST_LIST=woodpecker-server,ci.${DOMAIN:-homelab.fhirworx.io},${HOST_IP:-192.168.1.192},172.19.0.0/16
|
||||||
- GITEA__ui__THEMES=gitea-auto,gitea-light,gitea-dark,throwback
|
- GITEA__ui__THEMES=gitea-auto,gitea-light,gitea-dark,loch
|
||||||
- GITEA__ui__DEFAULT_THEME=throwback
|
- GITEA__ui__DEFAULT_THEME=loch
|
||||||
volumes:
|
volumes:
|
||||||
- gitea_data:/var/lib/gitea
|
- gitea_data:/var/lib/gitea
|
||||||
- gitea_config:/etc/gitea
|
- gitea_config:/etc/gitea
|
||||||
- ./gitea/custom:/var/lib/gitea/custom
|
- ./gitea/custom:/var/lib/gitea/custom
|
||||||
- ./styles/gitea.css:/var/lib/gitea/custom/public/assets/css/theme-throwback.css:ro
|
- ./styles/gitea.css:/var/lib/gitea/custom/public/assets/css/theme-loch.css:ro
|
||||||
ports:
|
ports:
|
||||||
- "2222:2222"
|
- "2222:2222"
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
@@ -186,7 +186,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./notebooks:/home/kert/notebooks
|
- ./notebooks:/home/kert/notebooks
|
||||||
- ./notebooks/.marimo-config:/home/kert/.config/marimo
|
- ./notebooks/.marimo-config:/home/kert/.config/marimo
|
||||||
- ./styles/marimo.css:/home/kert/.config/marimo/retro-arcade.css:ro
|
- ./styles/marimo.css:/home/kert/.config/marimo/loch.css:ro
|
||||||
- ./notebooks/home-page-DUMF8ZY4.js:/home/kert/workspace/.venv/lib/python3.13/site-packages/marimo/_static/assets/home-page-DUMF8ZY4.js:ro
|
- ./notebooks/home-page-DUMF8ZY4.js:/home/kert/workspace/.venv/lib/python3.13/site-packages/marimo/_static/assets/home-page-DUMF8ZY4.js:ro
|
||||||
- ./data:/home/kert/data
|
- ./data:/home/kert/data
|
||||||
- ./zotero/data:/home/kert/zotero:ro
|
- ./zotero/data:/home/kert/zotero:ro
|
||||||
@@ -336,7 +336,7 @@ services:
|
|||||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
- ./nginx/index.html:/usr/share/nginx/html/index.html:ro
|
- ./nginx/index.html:/usr/share/nginx/html/index.html:ro
|
||||||
- ./styles/dashboard.css:/usr/share/nginx/html/dashboard.css:ro
|
- ./styles/dashboard.css:/usr/share/nginx/html/dashboard.css:ro
|
||||||
- ./styles/inject.css:/usr/share/nginx/html/throwback.css:ro
|
- ./styles/inject.css:/usr/share/nginx/html/loch.css:ro
|
||||||
- ./styles/fav32.png:/usr/share/nginx/html/fav32.png:ro
|
- ./styles/fav32.png:/usr/share/nginx/html/fav32.png:ro
|
||||||
security_opt:
|
security_opt:
|
||||||
- no-new-privileges:true
|
- no-new-privileges:true
|
||||||
@@ -349,6 +349,38 @@ services:
|
|||||||
- gateway
|
- gateway
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
api:
|
||||||
|
image: fhirworx/api:${COMMIT_SHA:-latest}
|
||||||
|
container_name: api
|
||||||
|
networks:
|
||||||
|
- gateway
|
||||||
|
- storage
|
||||||
|
- data
|
||||||
|
- observability
|
||||||
|
environment:
|
||||||
|
- STACK_API_SECRET=${STACK_API_SECRET}
|
||||||
|
- GITEA_TOKEN=${GITEA_TOKEN}
|
||||||
|
# Postgres
|
||||||
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-changeme}
|
||||||
|
# S3 / RustFS
|
||||||
|
- NESSIE_S3_ACCESS_KEY=${NESSIE_S3_ACCESS_KEY}
|
||||||
|
- NESSIE_S3_SECRET_KEY=${NESSIE_S3_SECRET_KEY}
|
||||||
|
- S3_ENDPOINT=${S3_ENDPOINT:-http://rustfs:9000}
|
||||||
|
- S3_REGION=${S3_REGION:-us-east-1}
|
||||||
|
- S3_WAREHOUSE=${S3_WAREHOUSE:-s3://lakehouse/}
|
||||||
|
# OpenTelemetry
|
||||||
|
- OTEL_SERVICE_NAME=api
|
||||||
|
- OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- rustfs
|
||||||
|
- nessie
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
# Observability Stack
|
# Observability Stack
|
||||||
jaeger:
|
jaeger:
|
||||||
image: jaegertracing/all-in-one:latest
|
image: jaegertracing/all-in-one:latest
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Throwback palette — matches styles/inject.css */
|
/* LOCH — deep-navy design system — matches styles/inject.css */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--ifm-color-primary: #3366cc;
|
--ifm-color-primary: #3366cc;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
border-bottom: 4px solid var(--color-red);
|
border-bottom: 4px solid var(--color-red);
|
||||||
}
|
}
|
||||||
.homelab-dashboard .hdr h1 {
|
.homelab-dashboard .hdr h1 {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 2rem !important;
|
font-size: 2rem !important;
|
||||||
color: var(--color-text) !important;
|
color: var(--color-text) !important;
|
||||||
letter-spacing: 6px !important;
|
letter-spacing: 6px !important;
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
.homelab-dashboard .subtitle {
|
.homelab-dashboard .subtitle {
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
font-size: 0.55rem;
|
font-size: 0.55rem;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 40px;
|
gap: 40px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
font-size: 0.5rem;
|
font-size: 0.5rem;
|
||||||
}
|
}
|
||||||
.homelab-dashboard .score-item {
|
.homelab-dashboard .score-item {
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
.homelab-dashboard .tile.logs .icon { color: var(--color-primary-light-1); }
|
.homelab-dashboard .tile.logs .icon { color: var(--color-primary-light-1); }
|
||||||
.homelab-dashboard .tile.proxy .icon { color: var(--color-text); }
|
.homelab-dashboard .tile.proxy .icon { color: var(--color-text); }
|
||||||
.homelab-dashboard .tile-title {
|
.homelab-dashboard .tile-title {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 0.7rem !important;
|
font-size: 0.7rem !important;
|
||||||
color: var(--color-text) !important;
|
color: var(--color-text) !important;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
font-size: 0.35rem;
|
font-size: 0.35rem;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* THROWBACK THEME - Tecmo Super Bowl */
|
/* LOCH — deep-navy design system */
|
||||||
/* Uses marimo's native CSS variable system for proper theming */
|
/* Uses marimo's native CSS variable system for proper theming */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
FONT CONFIGURATION
|
FONT CONFIGURATION
|
||||||
@@ -9,30 +9,30 @@
|
|||||||
:root {
|
:root {
|
||||||
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--marimo-heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
--marimo-heading-font: 'IBM Plex Mono', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
THROWBACK COLOR PALETTE
|
LOCH COLOR PALETTE
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #8a9fbb;
|
--ds-steel: #8a9fbb;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #4477dd;
|
--ds-blue: #4477dd;
|
||||||
--tb-blue-light: #6699ee;
|
--ds-blue-light: #6699ee;
|
||||||
--tb-blue-bright: #99bbff;
|
--ds-blue-bright: #99bbff;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #ee6688;
|
--ds-red-light: #ee6688;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
--tb-green-light: #77dd77;
|
--ds-green-light: #77dd77;
|
||||||
--tb-yellow: #eebb44;
|
--ds-yellow: #eebb44;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -40,39 +40,39 @@
|
|||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
/* Base colors */
|
/* Base colors */
|
||||||
--background: var(--tb-navy);
|
--background: var(--ds-navy);
|
||||||
--foreground: var(--tb-white);
|
--foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Muted/secondary text */
|
/* Muted/secondary text */
|
||||||
--muted: var(--tb-navy-light);
|
--muted: var(--ds-navy-light);
|
||||||
--muted-foreground: var(--tb-steel);
|
--muted-foreground: var(--ds-steel);
|
||||||
|
|
||||||
/* Popover/dropdown backgrounds */
|
/* Popover/dropdown backgrounds */
|
||||||
--popover: var(--tb-navy-light);
|
--popover: var(--ds-navy-light);
|
||||||
--popover-foreground: var(--tb-white);
|
--popover-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Cards (cells) */
|
/* Cards (cells) */
|
||||||
--card: var(--tb-navy);
|
--card: var(--ds-navy);
|
||||||
--card-foreground: var(--tb-white);
|
--card-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Borders and inputs */
|
/* Borders and inputs */
|
||||||
--border: var(--tb-slate);
|
--border: var(--ds-slate);
|
||||||
--input: var(--tb-navy-mid);
|
--input: var(--ds-navy-mid);
|
||||||
|
|
||||||
/* Primary action color */
|
/* Primary action color */
|
||||||
--primary: var(--tb-blue);
|
--primary: var(--ds-blue);
|
||||||
--primary-foreground: var(--tb-white);
|
--primary-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Secondary elements */
|
/* Secondary elements */
|
||||||
--secondary: var(--tb-slate);
|
--secondary: var(--ds-slate);
|
||||||
--secondary-foreground: var(--tb-white);
|
--secondary-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Accent/highlight */
|
/* Accent/highlight */
|
||||||
--accent: var(--tb-blue-light);
|
--accent: var(--ds-blue-light);
|
||||||
--accent-foreground: var(--tb-white);
|
--accent-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Focus ring */
|
/* Focus ring */
|
||||||
--ring: var(--tb-blue-light);
|
--ring: var(--ds-blue-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -80,23 +80,23 @@
|
|||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
/* Error states */
|
/* Error states */
|
||||||
--destructive: var(--tb-red);
|
--destructive: var(--ds-red);
|
||||||
--destructive-foreground: var(--tb-white);
|
--destructive-foreground: var(--ds-white);
|
||||||
--error: var(--tb-red);
|
--error: var(--ds-red);
|
||||||
--error-foreground: var(--tb-white);
|
--error-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Success states */
|
/* Success states */
|
||||||
--success: var(--tb-green);
|
--success: var(--ds-green);
|
||||||
--success-foreground: var(--tb-white);
|
--success-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Action buttons (run, etc) */
|
/* Action buttons (run, etc) */
|
||||||
--action: var(--tb-green);
|
--action: var(--ds-green);
|
||||||
--action-hover: var(--tb-green-light);
|
--action-hover: var(--ds-green-light);
|
||||||
--action-foreground: var(--tb-white);
|
--action-foreground: var(--ds-white);
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
--link: var(--tb-blue-bright);
|
--link: var(--ds-blue-bright);
|
||||||
--link-visited: var(--tb-blue-light);
|
--link-visited: var(--ds-blue-light);
|
||||||
|
|
||||||
/* Stale indicator */
|
/* Stale indicator */
|
||||||
--stale: rgba(221, 170, 51, 0.25);
|
--stale: rgba(221, 170, 51, 0.25);
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -131,7 +131,7 @@ body {
|
|||||||
.cm-editor {
|
.cm-editor {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-content {
|
.cm-content {
|
||||||
@@ -140,43 +140,43 @@ body {
|
|||||||
|
|
||||||
.cm-line {
|
.cm-line {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-gutters {
|
.cm-gutters {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-right: 2px solid var(--tb-slate) !important;
|
border-right: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-lineNumbers .cm-gutterElement {
|
.cm-lineNumbers .cm-gutterElement {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syntax highlighting */
|
/* Syntax highlighting */
|
||||||
.cm-keyword, .tok-keyword { color: var(--tb-blue-bright) !important; }
|
.cm-keyword, .tok-keyword { color: var(--ds-blue-bright) !important; }
|
||||||
.cm-string, .tok-string { color: var(--tb-green-light) !important; }
|
.cm-string, .tok-string { color: var(--ds-green-light) !important; }
|
||||||
.cm-number, .tok-number { color: var(--tb-yellow) !important; }
|
.cm-number, .tok-number { color: var(--ds-yellow) !important; }
|
||||||
.cm-comment, .tok-comment { color: var(--tb-steel) !important; font-style: italic !important; }
|
.cm-comment, .tok-comment { color: var(--ds-steel) !important; font-style: italic !important; }
|
||||||
.cm-function, .tok-function { color: var(--tb-white) !important; }
|
.cm-function, .tok-function { color: var(--ds-white) !important; }
|
||||||
.cm-variableName, .tok-variableName { color: var(--tb-white) !important; }
|
.cm-variableName, .tok-variableName { color: var(--ds-white) !important; }
|
||||||
.cm-operator, .tok-operator { color: var(--tb-blue-light) !important; }
|
.cm-operator, .tok-operator { color: var(--ds-blue-light) !important; }
|
||||||
.cm-propertyName, .tok-propertyName { color: var(--tb-blue-bright) !important; }
|
.cm-propertyName, .tok-propertyName { color: var(--ds-blue-bright) !important; }
|
||||||
.tok-standard, .cm-builtin { color: var(--tb-red-light) !important; }
|
.tok-standard, .cm-builtin { color: var(--ds-red-light) !important; }
|
||||||
.tok-definition, .cm-def { color: var(--tb-blue-bright) !important; }
|
.tok-definition, .cm-def { color: var(--ds-blue-bright) !important; }
|
||||||
.tok-typeName { color: var(--tb-yellow) !important; }
|
.tok-typeName { color: var(--ds-yellow) !important; }
|
||||||
.tok-bool { color: var(--tb-red-light) !important; }
|
.tok-bool { color: var(--ds-red-light) !important; }
|
||||||
|
|
||||||
/* Cursor */
|
/* Cursor */
|
||||||
.cm-cursor {
|
.cm-cursor {
|
||||||
border-left: 2px solid var(--tb-white) !important;
|
border-left: 2px solid var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selection */
|
/* Selection */
|
||||||
.cm-selectionBackground,
|
.cm-selectionBackground,
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Active line */
|
/* Active line */
|
||||||
@@ -189,29 +189,30 @@ body {
|
|||||||
============================================ */
|
============================================ */
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--marimo-heading-font) !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
line-height: 1.8 !important;
|
line-height: 1.8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 18px !important;
|
font-size: 18px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
h4, h5, h6 {
|
h4, h5, h6 {
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
TABLES (Scoreboard style)
|
TABLES (Table styling)
|
||||||
============================================ */
|
============================================ */
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse !important;
|
border-collapse: collapse !important;
|
||||||
@@ -219,26 +220,26 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--marimo-heading-font) !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
padding: 10px 12px !important;
|
padding: 10px 12px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 1px !important;
|
letter-spacing: 1px !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
border: 1px solid var(--tb-navy-light) !important;
|
border: 1px solid var(--ds-navy-light) !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(even) td {
|
tr:nth-child(even) td {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:hover td {
|
tr:hover td {
|
||||||
@@ -261,15 +262,15 @@ button,
|
|||||||
button[data-variant="primary"],
|
button[data-variant="primary"],
|
||||||
button.primary,
|
button.primary,
|
||||||
[data-action="run"] {
|
[data-action="run"] {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-green-light) !important;
|
border: 2px solid var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button[data-variant="primary"]:hover,
|
button[data-variant="primary"]:hover,
|
||||||
button.primary:hover,
|
button.primary:hover,
|
||||||
[data-action="run"]:hover {
|
[data-action="run"]:hover {
|
||||||
background: var(--tb-green-light) !important;
|
background: var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -279,9 +280,9 @@ input,
|
|||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
}
|
}
|
||||||
@@ -289,7 +290,7 @@ select {
|
|||||||
input:focus,
|
input:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
||||||
}
|
}
|
||||||
@@ -302,16 +303,16 @@ pre, code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border-radius: 3px !important;
|
border-radius: 3px !important;
|
||||||
font-size: 0.9em !important;
|
font-size: 0.9em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
@@ -325,18 +326,18 @@ pre code {
|
|||||||
LINKS
|
LINKS
|
||||||
============================================ */
|
============================================ */
|
||||||
a {
|
a {
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
transition: color 0.15s ease !important;
|
transition: color 0.15s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--tb-blue-light) !important;
|
color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -348,17 +349,17 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--tb-slate);
|
background: var(--ds-slate);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 2px solid var(--tb-navy-light);
|
border: 2px solid var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--tb-steel);
|
background: var(--ds-steel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -370,17 +371,17 @@ a:visited {
|
|||||||
[data-state="open"][data-side] {
|
[data-state="open"][data-side] {
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dropdown menus */
|
/* Dropdown menus */
|
||||||
[role="menu"],
|
[role="menu"],
|
||||||
[role="listbox"] {
|
[role="listbox"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +389,8 @@ a:visited {
|
|||||||
[role="option"]:hover,
|
[role="option"]:hover,
|
||||||
[role="menuitem"][data-highlighted],
|
[role="menuitem"][data-highlighted],
|
||||||
[role="option"][data-highlighted] {
|
[role="option"][data-highlighted] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Badges and pills */
|
/* Badges and pills */
|
||||||
@@ -403,7 +404,7 @@ a:visited {
|
|||||||
|
|
||||||
/* Focus visible for accessibility */
|
/* Focus visible for accessibility */
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid var(--tb-blue-light) !important;
|
outline: 2px solid var(--ds-blue-light) !important;
|
||||||
outline-offset: 2px !important;
|
outline-offset: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +414,7 @@ a:visited {
|
|||||||
[data-testid="outputs"],
|
[data-testid="outputs"],
|
||||||
.output-area {
|
.output-area {
|
||||||
background: rgba(22, 32, 64, 0.5) !important;
|
background: rgba(22, 32, 64, 0.5) !important;
|
||||||
border-top: 2px solid var(--tb-slate) !important;
|
border-top: 2px solid var(--ds-slate) !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,20 +434,20 @@ svg {
|
|||||||
HOME PAGE - "CREATE NEW NOTEBOOK" CARD
|
HOME PAGE - "CREATE NEW NOTEBOOK" CARD
|
||||||
============================================ */
|
============================================ */
|
||||||
a[rel="noreferrer"][target="_blank"] {
|
a[rel="noreferrer"][target="_blank"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a[rel="noreferrer"][target="_blank"]:hover {
|
a[rel="noreferrer"][target="_blank"]:hover {
|
||||||
border-color: var(--tb-blue) !important;
|
border-color: var(--ds-blue) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a[rel="noreferrer"][target="_blank"] h2 {
|
a[rel="noreferrer"][target="_blank"] h2 {
|
||||||
font-family: var(--marimo-heading-font) !important;
|
font-family: var(--marimo-heading-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
}
|
}
|
||||||
@@ -459,30 +460,30 @@ h2.text-xl {
|
|||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
border-bottom: 2px solid var(--tb-slate);
|
border-bottom: 2px solid var(--ds-slate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
HOME PAGE - FILE LISTS (notebook lists)
|
HOME PAGE - FILE LISTS (notebook lists)
|
||||||
============================================ */
|
============================================ */
|
||||||
.divide-y.border.rounded {
|
.divide-y.border.rounded {
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border > a,
|
.divide-y.border > a,
|
||||||
.divide-y.border > div > a {
|
.divide-y.border > div > a {
|
||||||
border-color: var(--tb-navy-light) !important;
|
border-color: var(--ds-navy-light) !important;
|
||||||
transition: all 0.1s ease !important;
|
transition: all 0.1s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border > a:hover,
|
.divide-y.border > a:hover,
|
||||||
.divide-y.border > div > a:hover {
|
.divide-y.border > div > a:hover {
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
border-left: 3px solid var(--tb-blue) !important;
|
border-left: 3px solid var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border a .flex-1 span {
|
.divide-y.border a .flex-1 span {
|
||||||
@@ -502,7 +503,7 @@ h2.text-xl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
PIXEL-PERFECT BORDERS
|
BORDERS
|
||||||
============================================ */
|
============================================ */
|
||||||
.rounded-lg,
|
.rounded-lg,
|
||||||
.rounded-md {
|
.rounded-md {
|
||||||
@@ -518,33 +519,33 @@ h2.text-xl {
|
|||||||
TOP BAR / ACTION BUTTONS
|
TOP BAR / ACTION BUTTONS
|
||||||
============================================ */
|
============================================ */
|
||||||
.absolute.top-3.right-5 button {
|
.absolute.top-3.right-5 button {
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.absolute.top-3.right-5 button:hover {
|
.absolute.top-3.right-5 button:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
SEARCH INPUT
|
SEARCH INPUT
|
||||||
============================================ */
|
============================================ */
|
||||||
input#search {
|
input#search {
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
font-family: var(--marimo-monospace-font) !important;
|
font-family: var(--marimo-monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
input#search:focus {
|
input#search:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
box-shadow: 0 0 8px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 8px rgba(85, 136, 221, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
BUTTON PRESS EFFECT
|
BUTTON STATES
|
||||||
============================================ */
|
============================================ */
|
||||||
button:active,
|
button:active,
|
||||||
[role="button"]:active {
|
[role="button"]:active {
|
||||||
@@ -55,7 +55,7 @@ theme = "dark"
|
|||||||
default_table_page_size = 10
|
default_table_page_size = 10
|
||||||
default_table_max_columns = 50
|
default_table_max_columns = 50
|
||||||
reference_highlighting = true
|
reference_highlighting = true
|
||||||
custom_css = ["/home/kert/.config/marimo/retro-arcade.css"]
|
custom_css = ["/home/kert/.config/marimo/loch.css"]
|
||||||
code_editor_font_size = 14
|
code_editor_font_size = 14
|
||||||
|
|
||||||
[keymap]
|
[keymap]
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
[display]
|
[display]
|
||||||
theme = "dark"
|
theme = "dark"
|
||||||
custom_css = ["/home/kert/.config/marimo/retro-arcade.css"]
|
custom_css = ["/home/kert/.config/marimo/loch.css"]
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ RUN uv python install ${PYTHON_VERSION} \
|
|||||||
# Create marimo config directory and config
|
# Create marimo config directory and config
|
||||||
RUN mkdir -p /home/${USERNAME}/.config/marimo
|
RUN mkdir -p /home/${USERNAME}/.config/marimo
|
||||||
COPY --chown=${USER_UID}:${USER_GID} .marimo.toml /home/${USERNAME}/.config/marimo/marimo.toml
|
COPY --chown=${USER_UID}:${USER_GID} .marimo.toml /home/${USERNAME}/.config/marimo/marimo.toml
|
||||||
COPY --chown=${USER_UID}:${USER_GID} .marimo-config/retro-arcade.css /home/${USERNAME}/.config/marimo/retro-arcade.css
|
COPY --chown=${USER_UID}:${USER_GID} .marimo-config/loch.css /home/${USERNAME}/.config/marimo/loch.css
|
||||||
|
|
||||||
EXPOSE 2718
|
EXPOSE 2718
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,23 @@ def _(mo):
|
|||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _():
|
def _():
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
_here = Path(__file__).resolve().parent if "__file__" in dir() else Path.cwd()
|
||||||
|
_styles = str((_here / "../styles").resolve())
|
||||||
|
if _styles not in sys.path:
|
||||||
|
sys.path.insert(0, _styles)
|
||||||
|
|
||||||
import altair as alt
|
import altair as alt
|
||||||
import duckdb
|
import duckdb
|
||||||
import polars as pl
|
import polars as pl
|
||||||
|
from nature import PALETTE, altair_theme
|
||||||
|
|
||||||
from conf import path as _conf_path
|
from conf import path as _conf_path
|
||||||
|
|
||||||
|
altair_theme()
|
||||||
|
|
||||||
DB_PATH = str(_conf_path("db.aco"))
|
DB_PATH = str(_conf_path("db.aco"))
|
||||||
con = duckdb.connect(DB_PATH, read_only=True)
|
con = duckdb.connect(DB_PATH, read_only=True)
|
||||||
|
|
||||||
@@ -40,7 +51,7 @@ def _():
|
|||||||
"""Run a query and return a Polars DataFrame."""
|
"""Run a query and return a Polars DataFrame."""
|
||||||
return con.execute(sql).pl()
|
return con.execute(sql).pl()
|
||||||
|
|
||||||
return alt, pl, q
|
return PALETTE, alt, pl, q
|
||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
@@ -93,7 +104,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
patients = q(
|
patients = q(
|
||||||
"SELECT sex, race, state, age, age_group FROM core.patient WHERE state IS NOT NULL"
|
"SELECT sex, race, state, age, age_group FROM core.patient WHERE state IS NOT NULL"
|
||||||
)
|
)
|
||||||
@@ -103,7 +114,7 @@ def _(alt, mo, q):
|
|||||||
.mark_arc(innerRadius=50)
|
.mark_arc(innerRadius=50)
|
||||||
.encode(
|
.encode(
|
||||||
theta=alt.Theta("count():Q"),
|
theta=alt.Theta("count():Q"),
|
||||||
color=alt.Color("sex:N", scale=alt.Scale(scheme="set2")),
|
color=alt.Color("sex:N", scale=alt.Scale(range=PALETTE)),
|
||||||
tooltip=["sex:N", "count():Q"],
|
tooltip=["sex:N", "count():Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Sex Distribution", width=250, height=250)
|
.properties(title="Sex Distribution", width=250, height=250)
|
||||||
@@ -115,7 +126,7 @@ def _(alt, mo, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("count():Q", title="Patients"),
|
x=alt.X("count():Q", title="Patients"),
|
||||||
y=alt.Y("race:N", sort="-x", title=None),
|
y=alt.Y("race:N", sort="-x", title=None),
|
||||||
color=alt.Color("race:N", scale=alt.Scale(scheme="set2"), legend=None),
|
color=alt.Color("race:N", scale=alt.Scale(range=PALETTE), legend=None),
|
||||||
tooltip=["race:N", "count():Q"],
|
tooltip=["race:N", "count():Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Race Distribution", width=350, height=250)
|
.properties(title="Race Distribution", width=350, height=250)
|
||||||
@@ -126,14 +137,14 @@ def _(alt, mo, q):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, patients):
|
def _(PALETTE, alt, mo, patients):
|
||||||
age_chart = (
|
age_chart = (
|
||||||
alt.Chart(patients.to_pandas())
|
alt.Chart(patients.to_pandas())
|
||||||
.mark_bar()
|
.mark_bar()
|
||||||
.encode(
|
.encode(
|
||||||
x=alt.X("age:Q", bin=alt.Bin(step=5), title="Age"),
|
x=alt.X("age:Q", bin=alt.Bin(step=5), title="Age"),
|
||||||
y=alt.Y("count():Q", title="Patients"),
|
y=alt.Y("count():Q", title="Patients"),
|
||||||
color=alt.Color("sex:N", scale=alt.Scale(scheme="set2")),
|
color=alt.Color("sex:N", scale=alt.Scale(range=PALETTE)),
|
||||||
tooltip=["count():Q"],
|
tooltip=["count():Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Age Distribution by Sex", width=600, height=300)
|
.properties(title="Age Distribution by Sex", width=600, height=300)
|
||||||
@@ -151,7 +162,7 @@ def _(alt, mo, patients):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("len:Q", title="Patients"),
|
x=alt.X("len:Q", title="Patients"),
|
||||||
y=alt.Y("state:N", sort="-x", title=None),
|
y=alt.Y("state:N", sort="-x", title=None),
|
||||||
color=alt.value("#66c2a5"),
|
color=alt.value(PALETTE[2]),
|
||||||
tooltip=["state:N", "len:Q"],
|
tooltip=["state:N", "len:Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Top 15 States", width=350, height=300)
|
.properties(title="Top 15 States", width=350, height=300)
|
||||||
@@ -170,7 +181,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
enc_types = q("""
|
enc_types = q("""
|
||||||
SELECT encounter_type, count(*) AS encounters
|
SELECT encounter_type, count(*) AS encounters
|
||||||
FROM core.encounter
|
FROM core.encounter
|
||||||
@@ -184,7 +195,7 @@ def _(alt, mo, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("encounters:Q", title="Count"),
|
x=alt.X("encounters:Q", title="Count"),
|
||||||
y=alt.Y("encounter_type:N", sort="-x", title=None),
|
y=alt.Y("encounter_type:N", sort="-x", title=None),
|
||||||
color=alt.value("#fc8d62"),
|
color=alt.value(PALETTE[7]),
|
||||||
tooltip=["encounter_type:N", "encounters:Q"],
|
tooltip=["encounter_type:N", "encounters:Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Encounters by Type", width=600, height=450)
|
.properties(title="Encounters by Type", width=600, height=450)
|
||||||
@@ -195,7 +206,7 @@ def _(alt, mo, q):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
enc_monthly = q("""
|
enc_monthly = q("""
|
||||||
SELECT strftime(encounter_start_date, '%Y-%m') AS month,
|
SELECT strftime(encounter_start_date, '%Y-%m') AS month,
|
||||||
encounter_type,
|
encounter_type,
|
||||||
@@ -216,7 +227,7 @@ def _(alt, mo, q):
|
|||||||
x=alt.X("month:T", title="Month"),
|
x=alt.X("month:T", title="Month"),
|
||||||
y=alt.Y("encounters:Q", title="Encounters"),
|
y=alt.Y("encounters:Q", title="Encounters"),
|
||||||
color=alt.Color(
|
color=alt.Color(
|
||||||
"encounter_type:N", title="Type", scale=alt.Scale(scheme="set2")
|
"encounter_type:N", title="Type", scale=alt.Scale(range=PALETTE)
|
||||||
),
|
),
|
||||||
tooltip=["month:T", "encounter_type:N", "encounters:Q"],
|
tooltip=["month:T", "encounter_type:N", "encounters:Q"],
|
||||||
)
|
)
|
||||||
@@ -236,10 +247,10 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
chronic = q("""
|
chronic = q("""
|
||||||
SELECT condition, count(DISTINCT person_id) AS patients
|
SELECT condition, count(DISTINCT person_id) AS patients
|
||||||
FROM chronic_conditions.chronic_conditions_long
|
FROM chronic_conditions.cms_chronic_conditions_long
|
||||||
GROUP BY condition
|
GROUP BY condition
|
||||||
ORDER BY patients DESC
|
ORDER BY patients DESC
|
||||||
LIMIT 20
|
LIMIT 20
|
||||||
@@ -251,7 +262,7 @@ def _(alt, mo, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("patients:Q", title="Patients"),
|
x=alt.X("patients:Q", title="Patients"),
|
||||||
y=alt.Y("condition:N", sort="-x", title=None),
|
y=alt.Y("condition:N", sort="-x", title=None),
|
||||||
color=alt.Color("patients:Q", scale=alt.Scale(scheme="reds"), legend=None),
|
color=alt.Color("patients:Q", scale=alt.Scale(range=[PALETTE[1] + "33", PALETTE[1]]), legend=None),
|
||||||
tooltip=["condition:N", "patients:Q"],
|
tooltip=["condition:N", "patients:Q"],
|
||||||
)
|
)
|
||||||
.properties(
|
.properties(
|
||||||
@@ -267,7 +278,7 @@ def _(alt, mo, q):
|
|||||||
def _(mo, q):
|
def _(mo, q):
|
||||||
comorbidity = q("""
|
comorbidity = q("""
|
||||||
SELECT person_id, count(DISTINCT condition) AS condition_count
|
SELECT person_id, count(DISTINCT condition) AS condition_count
|
||||||
FROM chronic_conditions.chronic_conditions_long
|
FROM chronic_conditions.cms_chronic_conditions_long
|
||||||
GROUP BY person_id
|
GROUP BY person_id
|
||||||
""")
|
""")
|
||||||
|
|
||||||
@@ -285,7 +296,7 @@ def _(mo, q):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, comorbidity):
|
def _(PALETTE, alt, comorbidity):
|
||||||
burden_chart = (
|
burden_chart = (
|
||||||
alt.Chart(comorbidity.to_pandas())
|
alt.Chart(comorbidity.to_pandas())
|
||||||
.mark_bar()
|
.mark_bar()
|
||||||
@@ -296,7 +307,7 @@ def _(alt, comorbidity):
|
|||||||
title="Number of Chronic Conditions",
|
title="Number of Chronic Conditions",
|
||||||
),
|
),
|
||||||
y=alt.Y("count():Q", title="Patients"),
|
y=alt.Y("count():Q", title="Patients"),
|
||||||
color=alt.value("#e78ac3"),
|
color=alt.value(PALETTE[5]),
|
||||||
tooltip=["count():Q"],
|
tooltip=["count():Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Distribution of Comorbidity Burden", width=600, height=300)
|
.properties(title="Distribution of Comorbidity Burden", width=600, height=300)
|
||||||
@@ -315,7 +326,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, pl, q):
|
def _(PALETTE, alt, mo, pl, q):
|
||||||
risk = q("""
|
risk = q("""
|
||||||
SELECT r.person_id, r.payment_risk_score, r.v24_risk_score,
|
SELECT r.person_id, r.payment_risk_score, r.v24_risk_score,
|
||||||
r.normalized_risk_score, r.member_months,
|
r.normalized_risk_score, r.member_months,
|
||||||
@@ -345,7 +356,7 @@ def _(alt, mo, pl, q):
|
|||||||
title="Payment Risk Score",
|
title="Payment Risk Score",
|
||||||
),
|
),
|
||||||
y=alt.Y("count():Q", title="Patients"),
|
y=alt.Y("count():Q", title="Patients"),
|
||||||
color=alt.Color("sex:N", scale=alt.Scale(scheme="set2")),
|
color=alt.Color("sex:N", scale=alt.Scale(range=PALETTE)),
|
||||||
tooltip=["count():Q"],
|
tooltip=["count():Q"],
|
||||||
)
|
)
|
||||||
.properties(title="HCC Payment Risk Score Distribution", width=600, height=300)
|
.properties(title="HCC Payment Risk Score Distribution", width=600, height=300)
|
||||||
@@ -357,7 +368,7 @@ def _(alt, mo, pl, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("age:Q", title="Age"),
|
x=alt.X("age:Q", title="Age"),
|
||||||
y=alt.Y("payment_risk_score:Q", title="Payment Risk Score"),
|
y=alt.Y("payment_risk_score:Q", title="Payment Risk Score"),
|
||||||
color=alt.Color("sex:N", scale=alt.Scale(scheme="set2")),
|
color=alt.Color("sex:N", scale=alt.Scale(range=PALETTE)),
|
||||||
size=alt.Size(
|
size=alt.Size(
|
||||||
"member_months:Q", scale=alt.Scale(range=[20, 200]), legend=None
|
"member_months:Q", scale=alt.Scale(range=[20, 200]), legend=None
|
||||||
),
|
),
|
||||||
@@ -396,7 +407,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, pl, q):
|
def _(PALETTE, alt, mo, pl, q):
|
||||||
pmpm = q("""
|
pmpm = q("""
|
||||||
SELECT year_month,
|
SELECT year_month,
|
||||||
member_months,
|
member_months,
|
||||||
@@ -436,7 +447,7 @@ def _(alt, mo, pl, q):
|
|||||||
x=alt.X("year_month:T", title="Month"),
|
x=alt.X("year_month:T", title="Month"),
|
||||||
y=alt.Y("pmpm:Q", stack=True, title="PMPM ($)"),
|
y=alt.Y("pmpm:Q", stack=True, title="PMPM ($)"),
|
||||||
color=alt.Color(
|
color=alt.Color(
|
||||||
"category:N", title="Category", scale=alt.Scale(scheme="set2")
|
"category:N", title="Category", scale=alt.Scale(range=PALETTE)
|
||||||
),
|
),
|
||||||
tooltip=[
|
tooltip=[
|
||||||
"year_month:T",
|
"year_month:T",
|
||||||
@@ -449,7 +460,7 @@ def _(alt, mo, pl, q):
|
|||||||
|
|
||||||
total_line = (
|
total_line = (
|
||||||
alt.Chart(pmpm.to_pandas())
|
alt.Chart(pmpm.to_pandas())
|
||||||
.mark_line(color="#e41a1c", strokeWidth=2, point=True)
|
.mark_line(color=PALETTE[1], strokeWidth=2, point=True)
|
||||||
.encode(
|
.encode(
|
||||||
x=alt.X("year_month:T", title="Month"),
|
x=alt.X("year_month:T", title="Month"),
|
||||||
y=alt.Y("total_pmpm:Q", title="Total PMPM ($)"),
|
y=alt.Y("total_pmpm:Q", title="Total PMPM ($)"),
|
||||||
@@ -471,7 +482,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, pl, q):
|
def _(PALETTE, alt, mo, pl, q):
|
||||||
qm = q("""
|
qm = q("""
|
||||||
SELECT measure_id, measure_name, denominator_sum, numerator_sum,
|
SELECT measure_id, measure_name, denominator_sum, numerator_sum,
|
||||||
exclusion_sum, performance_rate
|
exclusion_sum, performance_rate
|
||||||
@@ -501,8 +512,8 @@ def _(alt, mo, pl, q):
|
|||||||
y=alt.Y("measure_name:N", sort="-x", title=None),
|
y=alt.Y("measure_name:N", sort="-x", title=None),
|
||||||
color=alt.condition(
|
color=alt.condition(
|
||||||
alt.datum.performance_rate > 50,
|
alt.datum.performance_rate > 50,
|
||||||
alt.value("#66c2a5"),
|
alt.value(PALETTE[2]),
|
||||||
alt.value("#fc8d62"),
|
alt.value(PALETTE[1]),
|
||||||
),
|
),
|
||||||
tooltip=[
|
tooltip=[
|
||||||
"measure_id:N",
|
"measure_id:N",
|
||||||
@@ -533,7 +544,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
ed = q("""
|
ed = q("""
|
||||||
SELECT ed_classification_description AS ed_classification,
|
SELECT ed_classification_description AS ed_classification,
|
||||||
count(*) AS visits,
|
count(*) AS visits,
|
||||||
@@ -552,7 +563,7 @@ def _(alt, mo, q):
|
|||||||
color=alt.Color(
|
color=alt.Color(
|
||||||
"ed_classification:N",
|
"ed_classification:N",
|
||||||
title="Classification",
|
title="Classification",
|
||||||
scale=alt.Scale(scheme="set2"),
|
scale=alt.Scale(range=PALETTE),
|
||||||
),
|
),
|
||||||
tooltip=[
|
tooltip=[
|
||||||
"ed_classification:N",
|
"ed_classification:N",
|
||||||
@@ -576,7 +587,7 @@ def _(alt, mo, q):
|
|||||||
),
|
),
|
||||||
y=alt.Y("avg_paid:Q", title="Avg Paid ($)"),
|
y=alt.Y("avg_paid:Q", title="Avg Paid ($)"),
|
||||||
color=alt.Color(
|
color=alt.Color(
|
||||||
"ed_classification:N", scale=alt.Scale(scheme="set2"), legend=None
|
"ed_classification:N", scale=alt.Scale(range=PALETTE), legend=None
|
||||||
),
|
),
|
||||||
tooltip=["ed_classification:N", alt.Tooltip("avg_paid:Q", format="$,.0f")],
|
tooltip=["ed_classification:N", alt.Tooltip("avg_paid:Q", format="$,.0f")],
|
||||||
)
|
)
|
||||||
@@ -590,7 +601,7 @@ def _(alt, mo, q):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
ed_dx = q("""
|
ed_dx = q("""
|
||||||
SELECT primary_diagnosis_description AS diagnosis, count(*) AS visits
|
SELECT primary_diagnosis_description AS diagnosis, count(*) AS visits
|
||||||
FROM ed_classification.summary
|
FROM ed_classification.summary
|
||||||
@@ -605,7 +616,7 @@ def _(alt, mo, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("visits:Q", title="ED Visits"),
|
x=alt.X("visits:Q", title="ED Visits"),
|
||||||
y=alt.Y("diagnosis:N", sort="-x", title=None),
|
y=alt.Y("diagnosis:N", sort="-x", title=None),
|
||||||
color=alt.value("#8da0cb"),
|
color=alt.value(PALETTE[0]),
|
||||||
tooltip=["diagnosis:N", "visits:Q"],
|
tooltip=["diagnosis:N", "visits:Q"],
|
||||||
)
|
)
|
||||||
.properties(title="Top 15 ED Diagnoses", width=700, height=400)
|
.properties(title="Top 15 ED Diagnoses", width=700, height=400)
|
||||||
@@ -650,7 +661,7 @@ def _(mo, q):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
readmit_cohort = q("""
|
readmit_cohort = q("""
|
||||||
SELECT specialty_cohort AS cohort,
|
SELECT specialty_cohort AS cohort,
|
||||||
count(*) AS admissions,
|
count(*) AS admissions,
|
||||||
@@ -670,8 +681,8 @@ def _(alt, mo, q):
|
|||||||
y=alt.Y("cohort:N", sort="-x", title=None),
|
y=alt.Y("cohort:N", sort="-x", title=None),
|
||||||
color=alt.condition(
|
color=alt.condition(
|
||||||
alt.datum.rate > 20,
|
alt.datum.rate > 20,
|
||||||
alt.value("#e41a1c"),
|
alt.value(PALETTE[1]),
|
||||||
alt.value("#66c2a5"),
|
alt.value(PALETTE[2]),
|
||||||
),
|
),
|
||||||
tooltip=[
|
tooltip=[
|
||||||
"cohort:N",
|
"cohort:N",
|
||||||
@@ -696,7 +707,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, pl, q):
|
def _(PALETTE, alt, mo, pl, q):
|
||||||
brand_gen = q("""
|
brand_gen = q("""
|
||||||
SELECT brand_vs_generic, count(*) AS claims,
|
SELECT brand_vs_generic, count(*) AS claims,
|
||||||
round(sum(paid_amount), 2) AS total_paid
|
round(sum(paid_amount), 2) AS total_paid
|
||||||
@@ -722,7 +733,7 @@ def _(alt, mo, pl, q):
|
|||||||
color=alt.Color(
|
color=alt.Color(
|
||||||
"brand_vs_generic:N",
|
"brand_vs_generic:N",
|
||||||
scale=alt.Scale(
|
scale=alt.Scale(
|
||||||
domain=["brand", "generic"], range=["#fc8d62", "#66c2a5"]
|
domain=["brand", "generic"], range=[PALETTE[7], PALETTE[2]]
|
||||||
),
|
),
|
||||||
legend=None,
|
legend=None,
|
||||||
),
|
),
|
||||||
@@ -774,7 +785,7 @@ def _(mo):
|
|||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(alt, mo, q):
|
def _(PALETTE, alt, mo, q):
|
||||||
pqi = q("""
|
pqi = q("""
|
||||||
SELECT r.pqi_number, m.pqi_name AS pqi_description,
|
SELECT r.pqi_number, m.pqi_name AS pqi_description,
|
||||||
r.rate_per_100_thousand, r.num_count, r.denom_count
|
r.rate_per_100_thousand, r.num_count, r.denom_count
|
||||||
@@ -790,7 +801,7 @@ def _(alt, mo, q):
|
|||||||
.encode(
|
.encode(
|
||||||
x=alt.X("rate_per_100_thousand:Q", title="Rate per 100,000"),
|
x=alt.X("rate_per_100_thousand:Q", title="Rate per 100,000"),
|
||||||
y=alt.Y("pqi_description:N", sort="-x", title=None),
|
y=alt.Y("pqi_description:N", sort="-x", title=None),
|
||||||
color=alt.value("#8da0cb"),
|
color=alt.value(PALETTE[0]),
|
||||||
tooltip=[
|
tooltip=[
|
||||||
"pqi_number:N",
|
"pqi_number:N",
|
||||||
"pqi_description:N",
|
"pqi_description:N",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ requires-python = ">=3.12"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"databricks-cli>=0.18.0",
|
"databricks-cli>=0.18.0",
|
||||||
"databricks-sdk>=0.85.0",
|
"databricks-sdk>=0.85.0",
|
||||||
|
"duckdb>=1.0.0",
|
||||||
"fastapi>=0.135.1",
|
"fastapi>=0.135.1",
|
||||||
"fastexcel>=0.19.0",
|
"fastexcel>=0.19.0",
|
||||||
"fsspec>=2024.1.0",
|
"fsspec>=2024.1.0",
|
||||||
@@ -34,6 +35,8 @@ dev = [
|
|||||||
"pytest-cov>=7.0.0",
|
"pytest-cov>=7.0.0",
|
||||||
"marimo>=0.20.0",
|
"marimo>=0.20.0",
|
||||||
"ruff>=0.11.0",
|
"ruff>=0.11.0",
|
||||||
|
"altair>=6.0.0",
|
||||||
|
"pandas>=3.0.1",
|
||||||
]
|
]
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 88
|
line-length = 88
|
||||||
|
|||||||
@@ -26,31 +26,20 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import html as html_mod
|
import html as html_mod
|
||||||
import json
|
import json
|
||||||
|
import sys as _sys
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
from pathlib import Path as _Path
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
from aco.pipe.base import Pipeline
|
_styles_dir = str(_Path(__file__).resolve().parents[2] / "styles")
|
||||||
|
if _styles_dir not in _sys.path:
|
||||||
|
_sys.path.insert(0, _styles_dir)
|
||||||
|
|
||||||
# Tableau 10 palette for pipeline schemas, gray for externals.
|
from nature import EXTERNAL_COLOR as _EXTERNAL_COLOR # noqa: E402, I001
|
||||||
_SCHEMA_COLORS: dict[str, str] = {
|
from nature import SCHEMA_COLORS as _SCHEMA_COLORS # noqa: E402, F401
|
||||||
"core": "#e15759",
|
from nature import schema_color as _color # noqa: E402
|
||||||
"input_layer": "#76b7b2",
|
|
||||||
"cclf": "#4e79a7",
|
|
||||||
"claims_preprocessing": "#f28e2b",
|
|
||||||
"readmissions": "#59a14f",
|
|
||||||
"ahrq_measures": "#edc948",
|
|
||||||
"pharmacy": "#b07aa1",
|
|
||||||
"quality_measures": "#ff9da7",
|
|
||||||
"hcc_suspecting": "#9c755f",
|
|
||||||
"provider_attribution": "#bab0ac",
|
|
||||||
"main": "#86bcb6",
|
|
||||||
"data_quality": "#4e79a7",
|
|
||||||
}
|
|
||||||
_EXTERNAL_COLOR = "#888888"
|
|
||||||
|
|
||||||
|
from aco.pipe.base import Pipeline # noqa: E402
|
||||||
def _color(schema: str) -> str:
|
|
||||||
return _SCHEMA_COLORS.get(schema, _EXTERNAL_COLOR)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -271,7 +260,7 @@ def to_html(graph: Graph, *, title: str = "ACO Pipeline DAG") -> str:
|
|||||||
<script src="https://unpkg.com/cytoscape-dagre@2/cytoscape-dagre.js"></script>
|
<script src="https://unpkg.com/cytoscape-dagre@2/cytoscape-dagre.js"></script>
|
||||||
<style>
|
<style>
|
||||||
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
||||||
body {{ background: #1a1a2e; color: #e0e0e0; font-family: system-ui, sans-serif; }}
|
body {{ background: #1a1a2e; color: #e0e0e0; font-family: Helvetica, Arial, sans-serif; }}
|
||||||
#cy {{ width: 100vw; height: 100vh; }}
|
#cy {{ width: 100vw; height: 100vh; }}
|
||||||
#controls {{
|
#controls {{
|
||||||
position: fixed; top: 12px; left: 12px; z-index: 10;
|
position: fixed; top: 12px; left: 12px; z-index: 10;
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
/* THROWBACK THEME — Dashboard (nginx landing page)
|
/* LOCH — deep-navy design system for Dashboard (nginx landing page) */
|
||||||
Extracted from nginx/index.html inline styles */
|
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #5a7090;
|
--ds-steel: #5a7090;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
--tb-blue: #3366cc;
|
--ds-blue: #3366cc;
|
||||||
--tb-blue-light: #5588dd;
|
--ds-blue-light: #5588dd;
|
||||||
--tb-blue-bright: #88aaee;
|
--ds-blue-bright: #88aaee;
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #dd4466;
|
--ds-red-light: #dd4466;
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -26,10 +25,10 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'IBM Plex Mono', 'Courier New', monospace;
|
font-family: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
background: var(--tb-navy);
|
background: var(--ds-navy);
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
color: var(--tb-white);
|
color: var(--ds-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -41,20 +40,21 @@ body {
|
|||||||
header {
|
header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 40px 20px;
|
padding: 40px 20px;
|
||||||
border-bottom: 4px solid var(--tb-red);
|
border-bottom: 4px solid var(--ds-red);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
|
font-weight: 600;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
color: var(--tb-white);
|
color: var(--ds-white);
|
||||||
letter-spacing: 6px;
|
letter-spacing: 6px;
|
||||||
text-shadow: 3px 3px 0 var(--tb-navy-mid);
|
text-shadow: 3px 3px 0 var(--ds-navy-mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
color: var(--tb-blue-bright);
|
color: var(--ds-blue-bright);
|
||||||
font-size: 0.55rem;
|
font-size: 0.55rem;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
@@ -65,15 +65,15 @@ h1 {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 40px;
|
gap: 40px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
font-size: 0.5rem;
|
font-size: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.score-item {
|
.score-item {
|
||||||
color: var(--tb-white);
|
color: var(--ds-white);
|
||||||
background: var(--tb-blue);
|
background: var(--ds-blue);
|
||||||
padding: 6px 14px;
|
padding: 6px 14px;
|
||||||
border: 2px solid var(--tb-blue-light);
|
border: 2px solid var(--ds-blue-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
@@ -85,8 +85,8 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tile {
|
.tile {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
border: 3px solid var(--tb-slate);
|
border: 3px solid var(--ds-slate);
|
||||||
padding: 25px;
|
padding: 25px;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -97,8 +97,8 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tile:hover {
|
.tile:hover {
|
||||||
border-color: var(--tb-blue);
|
border-color: var(--ds-blue);
|
||||||
background: var(--tb-navy-mid);
|
background: var(--ds-navy-mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All tile variants use the same base style */
|
/* All tile variants use the same base style */
|
||||||
@@ -109,36 +109,36 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tile.storage .icon,
|
.tile.storage .icon,
|
||||||
.tile.database .icon { color: var(--tb-red); }
|
.tile.database .icon { color: var(--ds-red); }
|
||||||
.tile.git .icon { color: var(--tb-blue-bright); }
|
.tile.git .icon { color: var(--ds-blue-bright); }
|
||||||
.tile.ci .icon { color: var(--tb-blue-light); }
|
.tile.ci .icon { color: var(--ds-blue-light); }
|
||||||
.tile.notebook .icon,
|
.tile.notebook .icon,
|
||||||
.tile.research .icon { color: var(--tb-white); }
|
.tile.research .icon { color: var(--ds-white); }
|
||||||
.tile.catalog .icon { color: var(--tb-blue-bright); }
|
.tile.catalog .icon { color: var(--ds-blue-bright); }
|
||||||
.tile.query .icon { color: var(--tb-blue-light); }
|
.tile.query .icon { color: var(--ds-blue-light); }
|
||||||
.tile.observability .icon { color: var(--tb-red-light); }
|
.tile.observability .icon { color: var(--ds-red-light); }
|
||||||
.tile.metrics .icon { color: var(--tb-blue-bright); }
|
.tile.metrics .icon { color: var(--ds-blue-bright); }
|
||||||
.tile.logs .icon { color: var(--tb-blue-light); }
|
.tile.logs .icon { color: var(--ds-blue-light); }
|
||||||
.tile.proxy .icon { color: var(--tb-white); }
|
.tile.proxy .icon { color: var(--ds-white); }
|
||||||
|
|
||||||
.tile-title {
|
.tile-title {
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: var(--tb-white);
|
color: var(--ds-white);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile-desc {
|
.tile-desc {
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
color: var(--tb-steel);
|
color: var(--ds-steel);
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile-port {
|
.tile-port {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
color: var(--tb-blue-bright);
|
color: var(--ds-blue-bright);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ h1 {
|
|||||||
right: 15px;
|
right: 15px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: var(--tb-green);
|
background: var(--ds-green);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,20 +158,20 @@ h1 {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background: var(--tb-red);
|
background: var(--ds-red);
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
color: var(--tb-slate);
|
color: var(--ds-slate);
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
border-top: 3px solid var(--tb-slate);
|
border-top: 3px solid var(--ds-slate);
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer span {
|
footer span {
|
||||||
color: var(--tb-red);
|
color: var(--ds-red);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Badges */
|
/* Badges */
|
||||||
@@ -179,14 +179,14 @@ footer span {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
font-family: 'Press Start 2P', monospace;
|
font-family: 'IBM Plex Mono', monospace;
|
||||||
color: var(--tb-white);
|
color: var(--ds-white);
|
||||||
font-size: 0.35rem;
|
font-size: 0.35rem;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge.new { background: var(--tb-red); }
|
.badge.new { background: var(--ds-red); }
|
||||||
.badge.gpu { background: var(--tb-blue); }
|
.badge.gpu { background: var(--ds-blue); }
|
||||||
.badge.data { background: var(--tb-blue); }
|
.badge.data { background: var(--ds-blue); }
|
||||||
|
|||||||
233
styles/gitea.css
233
styles/gitea.css
@@ -1,81 +1,81 @@
|
|||||||
/* THROWBACK THEME FOR GITEA - Tecmo Super Bowl */
|
/* LOCH — deep-navy design system for Gitea */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
/* Theme metadata */
|
/* Theme metadata */
|
||||||
gitea-theme-meta-info {
|
gitea-theme-meta-info {
|
||||||
--theme-display-name: "Throwback";
|
--theme-display-name: "Loch";
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--is-dark-theme: true;
|
--is-dark-theme: true;
|
||||||
|
|
||||||
/* Throwback Color Palette */
|
/* Loch Color Palette */
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #5a7090;
|
--ds-steel: #5a7090;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #3366cc;
|
--ds-blue: #3366cc;
|
||||||
--tb-blue-light: #5588dd;
|
--ds-blue-light: #5588dd;
|
||||||
--tb-blue-bright: #88aaee;
|
--ds-blue-bright: #88aaee;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #dd4466;
|
--ds-red-light: #dd4466;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
--tb-green-light: #66cc66;
|
--ds-green-light: #66cc66;
|
||||||
--tb-yellow: #ddaa33;
|
--ds-yellow: #ddaa33;
|
||||||
|
|
||||||
/* Gitea color mappings */
|
/* Gitea color mappings */
|
||||||
--color-primary: var(--tb-blue);
|
--color-primary: var(--ds-blue);
|
||||||
--color-primary-light: var(--tb-blue-light);
|
--color-primary-light: var(--ds-blue-light);
|
||||||
--color-primary-dark: #2255aa;
|
--color-primary-dark: #2255aa;
|
||||||
--color-primary-alpha-10: rgba(51, 102, 204, 0.1);
|
--color-primary-alpha-10: rgba(51, 102, 204, 0.1);
|
||||||
--color-primary-alpha-20: rgba(51, 102, 204, 0.2);
|
--color-primary-alpha-20: rgba(51, 102, 204, 0.2);
|
||||||
--color-primary-alpha-40: rgba(51, 102, 204, 0.4);
|
--color-primary-alpha-40: rgba(51, 102, 204, 0.4);
|
||||||
|
|
||||||
--color-secondary: var(--tb-slate);
|
--color-secondary: var(--ds-slate);
|
||||||
--color-secondary-light: var(--tb-steel);
|
--color-secondary-light: var(--ds-steel);
|
||||||
--color-secondary-dark: var(--tb-navy-light);
|
--color-secondary-dark: var(--ds-navy-light);
|
||||||
|
|
||||||
/* Background colors */
|
/* Background colors */
|
||||||
--color-body: var(--tb-navy);
|
--color-body: var(--ds-navy);
|
||||||
--color-box-body: var(--tb-navy);
|
--color-box-body: var(--ds-navy);
|
||||||
--color-box-header: var(--tb-navy-light);
|
--color-box-header: var(--ds-navy-light);
|
||||||
|
|
||||||
/* Text colors */
|
/* Text colors */
|
||||||
--color-text: var(--tb-white);
|
--color-text: var(--ds-white);
|
||||||
--color-text-light: var(--tb-steel);
|
--color-text-light: var(--ds-steel);
|
||||||
--color-text-dark: var(--tb-white);
|
--color-text-dark: var(--ds-white);
|
||||||
|
|
||||||
/* Input colors */
|
/* Input colors */
|
||||||
--color-input-text: var(--tb-white);
|
--color-input-text: var(--ds-white);
|
||||||
--color-input-background: var(--tb-navy-mid);
|
--color-input-background: var(--ds-navy-mid);
|
||||||
--color-input-border: var(--tb-slate);
|
--color-input-border: var(--ds-slate);
|
||||||
|
|
||||||
/* Status colors */
|
/* Status colors */
|
||||||
--color-success: var(--tb-green);
|
--color-success: var(--ds-green);
|
||||||
--color-success-text: var(--tb-white);
|
--color-success-text: var(--ds-white);
|
||||||
--color-warning: var(--tb-yellow);
|
--color-warning: var(--ds-yellow);
|
||||||
--color-warning-text: var(--tb-navy);
|
--color-warning-text: var(--ds-navy);
|
||||||
--color-error: var(--tb-red);
|
--color-error: var(--ds-red);
|
||||||
--color-error-text: var(--tb-white);
|
--color-error-text: var(--ds-white);
|
||||||
--color-info: var(--tb-blue-light);
|
--color-info: var(--ds-blue-light);
|
||||||
--color-info-text: var(--tb-white);
|
--color-info-text: var(--ds-white);
|
||||||
|
|
||||||
/* Border */
|
/* Border */
|
||||||
--color-border: var(--tb-slate);
|
--color-border: var(--ds-slate);
|
||||||
|
|
||||||
/* Link colors */
|
/* Link colors */
|
||||||
--color-link: var(--tb-blue-bright);
|
--color-link: var(--ds-blue-bright);
|
||||||
--color-link-hover: var(--tb-white);
|
--color-link-hover: var(--ds-white);
|
||||||
|
|
||||||
/* Code */
|
/* Code */
|
||||||
--color-code-bg: var(--tb-navy-light);
|
--color-code-bg: var(--ds-navy-light);
|
||||||
--color-code-border: var(--tb-slate);
|
--color-code-border: var(--ds-slate);
|
||||||
|
|
||||||
/* Shadows */
|
/* Shadows */
|
||||||
--color-shadow: rgba(0, 0, 0, 0.4);
|
--color-shadow: rgba(0, 0, 0, 0.4);
|
||||||
@@ -84,40 +84,41 @@ gitea-theme-meta-info {
|
|||||||
/* Global styles */
|
/* Global styles */
|
||||||
body {
|
body {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Headings */
|
/* Headings */
|
||||||
h1, h2, h3, h4, h5, h6,
|
h1, h2, h3, h4, h5, h6,
|
||||||
.header-wrapper .header {
|
.header-wrapper .header {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 { font-size: 18px !important; color: var(--tb-white) !important; }
|
h1 { font-size: 18px !important; color: var(--ds-white) !important; }
|
||||||
h2 { font-size: 14px !important; color: var(--tb-blue-bright) !important; }
|
h2 { font-size: 14px !important; color: var(--ds-blue-bright) !important; }
|
||||||
h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
h3 { font-size: 12px !important; color: var(--ds-white) !important; }
|
||||||
|
|
||||||
/* Navbar */
|
/* Navbar */
|
||||||
.ui.secondary.menu.navbar,
|
.ui.secondary.menu.navbar,
|
||||||
.navbar {
|
.navbar {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar .item {
|
.navbar .item {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar .item:hover {
|
.navbar .item:hover {
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar .item.active {
|
.navbar .item.active {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons */
|
/* Buttons */
|
||||||
@@ -131,31 +132,31 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
|
|
||||||
.ui.primary.button,
|
.ui.primary.button,
|
||||||
.ui.blue.button {
|
.ui.blue.button {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-blue-light) !important;
|
border: 2px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.primary.button:hover,
|
.ui.primary.button:hover,
|
||||||
.ui.blue.button:hover {
|
.ui.blue.button:hover {
|
||||||
background: var(--tb-blue-light) !important;
|
background: var(--ds-blue-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.green.button {
|
.ui.green.button {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-green-light) !important;
|
border: 2px solid var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.green.button:hover {
|
.ui.green.button:hover {
|
||||||
background: var(--tb-green-light) !important;
|
background: var(--ds-green-light) !important;
|
||||||
color: var(--tb-navy) !important;
|
color: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.red.button {
|
.ui.red.button {
|
||||||
background: var(--tb-red) !important;
|
background: var(--ds-red) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Segments and boxes */
|
/* Segments and boxes */
|
||||||
@@ -163,39 +164,39 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
.ui.segments,
|
.ui.segments,
|
||||||
.repository,
|
.repository,
|
||||||
.box {
|
.box {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.attached.header,
|
.ui.attached.header,
|
||||||
.box-header {
|
.box-header {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 2px solid var(--tb-slate) !important;
|
border-bottom: 2px solid var(--ds-slate) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tables */
|
/* Tables */
|
||||||
.ui.table {
|
.ui.table {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.table th {
|
.ui.table th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.table td {
|
.ui.table td {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 1px solid var(--tb-navy-light) !important;
|
border: 1px solid var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.table tr:hover td {
|
.ui.table tr:hover td {
|
||||||
@@ -208,17 +209,17 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
.ui.form select,
|
.ui.form select,
|
||||||
.ui.input input {
|
.ui.input input {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.form input:focus,
|
.ui.form input:focus,
|
||||||
.ui.form textarea:focus,
|
.ui.form textarea:focus,
|
||||||
.ui.input input:focus {
|
.ui.input input:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Labels */
|
/* Labels */
|
||||||
@@ -229,16 +230,16 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
|
|
||||||
/* Dropdowns */
|
/* Dropdowns */
|
||||||
.ui.dropdown .menu {
|
.ui.dropdown .menu {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.dropdown .menu .item {
|
.ui.dropdown .menu .item {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.dropdown .menu .item:hover {
|
.ui.dropdown .menu .item:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code and diffs */
|
/* Code and diffs */
|
||||||
@@ -247,35 +248,35 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
.CodeMirror,
|
.CodeMirror,
|
||||||
.highlight {
|
.highlight {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diff-file-box .diff-file-header {
|
.diff-file-box .diff-file-header {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commit graph */
|
/* Commit graph */
|
||||||
.repository .commit-list .commit {
|
.repository .commit-list .commit {
|
||||||
border-bottom: 1px solid var(--tb-navy-light) !important;
|
border-bottom: 1px solid var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issues and PRs */
|
/* Issues and PRs */
|
||||||
.issue-list .item,
|
.issue-list .item,
|
||||||
.pull-list .item {
|
.pull-list .item {
|
||||||
border-bottom: 1px solid var(--tb-navy-light) !important;
|
border-bottom: 1px solid var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
.footer {
|
.footer {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-top: 3px solid var(--tb-slate) !important;
|
border-top: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
.ui.card,
|
.ui.card,
|
||||||
.ui.cards .card {
|
.ui.cards .card {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,27 +289,27 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
.ui.positive.message,
|
.ui.positive.message,
|
||||||
.ui.success.message {
|
.ui.success.message {
|
||||||
background: rgba(68, 170, 68, 0.2) !important;
|
background: rgba(68, 170, 68, 0.2) !important;
|
||||||
border: 2px solid var(--tb-green) !important;
|
border: 2px solid var(--ds-green) !important;
|
||||||
color: var(--tb-green-light) !important;
|
color: var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.negative.message,
|
.ui.negative.message,
|
||||||
.ui.error.message {
|
.ui.error.message {
|
||||||
background: rgba(204, 34, 68, 0.2) !important;
|
background: rgba(204, 34, 68, 0.2) !important;
|
||||||
border: 2px solid var(--tb-red) !important;
|
border: 2px solid var(--ds-red) !important;
|
||||||
color: var(--tb-red-light) !important;
|
color: var(--ds-red-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.warning.message {
|
.ui.warning.message {
|
||||||
background: rgba(221, 170, 51, 0.2) !important;
|
background: rgba(221, 170, 51, 0.2) !important;
|
||||||
border: 2px solid var(--tb-yellow) !important;
|
border: 2px solid var(--ds-yellow) !important;
|
||||||
color: var(--tb-yellow) !important;
|
color: var(--ds-yellow) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.info.message {
|
.ui.info.message {
|
||||||
background: rgba(85, 136, 221, 0.2) !important;
|
background: rgba(85, 136, 221, 0.2) !important;
|
||||||
border: 2px solid var(--tb-blue-light) !important;
|
border: 2px solid var(--ds-blue-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrollbars */
|
/* Scrollbars */
|
||||||
@@ -318,29 +319,29 @@ h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--tb-slate);
|
background: var(--ds-slate);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--tb-steel);
|
background: var(--ds-steel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selection */
|
/* Selection */
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
a {
|
a {
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
/* THROWBACK THEME - Universal Injectable CSS
|
/* LOCH — deep-navy design system
|
||||||
Tecmo Super Bowl inspired: deep navy, white text, patriotic red/blue
|
Universal injectable CSS.
|
||||||
Injected via Traefik rewrite-body plugin into:
|
Injected via Traefik rewrite-body plugin into:
|
||||||
Grafana, Traefik Dashboard, RustFS/MinIO, Jaeger, Prometheus, Trino
|
Grafana, Traefik Dashboard, RustFS/MinIO, Jaeger, Prometheus, Trino
|
||||||
Palette matches: Gitea, Woodpecker, Marimo, nginx dashboard themes */
|
Palette matches: Gitea, Woodpecker, Marimo, nginx dashboard themes */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
THROWBACK COLOR PALETTE
|
LOCH COLOR PALETTE
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #5a7090;
|
--ds-steel: #5a7090;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #3366cc;
|
--ds-blue: #3366cc;
|
||||||
--tb-blue-light: #5588dd;
|
--ds-blue-light: #5588dd;
|
||||||
--tb-blue-bright: #88aaee;
|
--ds-blue-bright: #88aaee;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #dd4466;
|
--ds-red-light: #dd4466;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
--tb-green-light: #66cc66;
|
--ds-green-light: #66cc66;
|
||||||
--tb-yellow: #ddaa33;
|
--ds-yellow: #ddaa33;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -34,34 +34,35 @@
|
|||||||
============================================ */
|
============================================ */
|
||||||
body, html {
|
body, html {
|
||||||
font-family: 'IBM Plex Mono', 'Courier New', monospace !important;
|
font-family: 'IBM Plex Mono', 'Courier New', monospace !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
HEADINGS
|
HEADINGS
|
||||||
============================================ */
|
============================================ */
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: 'Press Start 2P', 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
line-height: 1.8 !important;
|
line-height: 1.8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
h4, h5, h6 {
|
h4, h5, h6 {
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -75,9 +76,9 @@ header,
|
|||||||
[class*="topbar"],
|
[class*="topbar"],
|
||||||
[class*="top-bar"],
|
[class*="top-bar"],
|
||||||
[class*="app-bar"] {
|
[class*="app-bar"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -89,13 +90,13 @@ aside,
|
|||||||
[class*="side-nav"],
|
[class*="side-nav"],
|
||||||
[class*="drawer"],
|
[class*="drawer"],
|
||||||
[class*="menu-panel"] {
|
[class*="menu-panel"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border-right: 3px solid var(--tb-slate) !important;
|
border-right: 3px solid var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
TABLES (Scoreboard style)
|
TABLES (Table styling)
|
||||||
============================================ */
|
============================================ */
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse !important;
|
border-collapse: collapse !important;
|
||||||
@@ -103,26 +104,26 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 9px !important;
|
font-size: 9px !important;
|
||||||
padding: 10px 12px !important;
|
padding: 10px 12px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 1px !important;
|
letter-spacing: 1px !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
border: 1px solid var(--tb-navy-light) !important;
|
border: 1px solid var(--ds-navy-light) !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(even) td {
|
tr:nth-child(even) td {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:hover td {
|
tr:hover td {
|
||||||
@@ -138,9 +139,9 @@ button,
|
|||||||
[class*="button"] {
|
[class*="button"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-weight: 500 !important;
|
font-weight: 500 !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
transition: all 0.15s ease !important;
|
transition: all 0.15s ease !important;
|
||||||
}
|
}
|
||||||
@@ -149,8 +150,8 @@ button:hover,
|
|||||||
[role="button"]:hover,
|
[role="button"]:hover,
|
||||||
.btn:hover,
|
.btn:hover,
|
||||||
[class*="button"]:hover {
|
[class*="button"]:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:active,
|
button:active,
|
||||||
@@ -163,14 +164,14 @@ button:active,
|
|||||||
button[type="submit"],
|
button[type="submit"],
|
||||||
[class*="primary"],
|
[class*="primary"],
|
||||||
[class*="submit"] {
|
[class*="submit"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-blue-light) !important;
|
border: 2px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button[type="submit"]:hover,
|
button[type="submit"]:hover,
|
||||||
[class*="primary"]:hover {
|
[class*="primary"]:hover {
|
||||||
background: var(--tb-blue-light) !important;
|
background: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -182,16 +183,16 @@ select,
|
|||||||
[class*="input"],
|
[class*="input"],
|
||||||
[contenteditable="true"] {
|
[contenteditable="true"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus,
|
input:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
||||||
}
|
}
|
||||||
@@ -204,15 +205,15 @@ pre, code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border-radius: 3px !important;
|
border-radius: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
@@ -226,18 +227,18 @@ pre code {
|
|||||||
LINKS
|
LINKS
|
||||||
============================================ */
|
============================================ */
|
||||||
a {
|
a {
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
transition: color 0.15s ease !important;
|
transition: color 0.15s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--tb-blue-light) !important;
|
color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -248,9 +249,9 @@ a:visited {
|
|||||||
[class*="widget"],
|
[class*="widget"],
|
||||||
[class*="Paper"],
|
[class*="Paper"],
|
||||||
[class*="container"]:not(body):not(html) {
|
[class*="container"]:not(body):not(html) {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -264,16 +265,16 @@ a:visited {
|
|||||||
[class*="Popover"],
|
[class*="Popover"],
|
||||||
[class*="Menu-list"],
|
[class*="Menu-list"],
|
||||||
[class*="MenuList"] {
|
[class*="MenuList"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role="menuitem"]:hover,
|
[role="menuitem"]:hover,
|
||||||
[role="option"]:hover,
|
[role="option"]:hover,
|
||||||
[class*="MenuItem"]:hover {
|
[class*="MenuItem"]:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -286,9 +287,9 @@ a:visited {
|
|||||||
[class*="pill"] {
|
[class*="pill"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Status indicators */
|
/* Status indicators */
|
||||||
@@ -297,19 +298,19 @@ a:visited {
|
|||||||
[class*="running"],
|
[class*="running"],
|
||||||
[class*="active"],
|
[class*="active"],
|
||||||
[class*="ok"] {
|
[class*="ok"] {
|
||||||
color: var(--tb-green-light) !important;
|
color: var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="error"],
|
[class*="error"],
|
||||||
[class*="danger"],
|
[class*="danger"],
|
||||||
[class*="failed"],
|
[class*="failed"],
|
||||||
[class*="critical"] {
|
[class*="critical"] {
|
||||||
color: var(--tb-red) !important;
|
color: var(--ds-red) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="warning"],
|
[class*="warning"],
|
||||||
[class*="pending"] {
|
[class*="pending"] {
|
||||||
color: var(--tb-yellow) !important;
|
color: var(--ds-yellow) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -321,32 +322,32 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--tb-slate);
|
background: var(--ds-slate);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 2px solid var(--tb-navy-light);
|
border: 2px solid var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--tb-steel);
|
background: var(--ds-steel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
TEXT SELECTION
|
TEXT SELECTION
|
||||||
============================================ */
|
============================================ */
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
FOCUS STYLES
|
FOCUS STYLES
|
||||||
============================================ */
|
============================================ */
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid var(--tb-blue-light) !important;
|
outline: 2px solid var(--ds-blue-light) !important;
|
||||||
outline-offset: 2px !important;
|
outline-offset: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,15 +393,15 @@ img[alt*="Logo" i] {
|
|||||||
.grafana-app [class*="NavBar"],
|
.grafana-app [class*="NavBar"],
|
||||||
.grafana-app [class*="Topbar"],
|
.grafana-app [class*="Topbar"],
|
||||||
.grafana-app [aria-label="Main menu"] {
|
.grafana-app [aria-label="Main menu"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidenav */
|
/* Sidenav */
|
||||||
.grafana-app [class*="sidemenu"],
|
.grafana-app [class*="sidemenu"],
|
||||||
.grafana-app [class*="NavBar"][class*="wrapper"] {
|
.grafana-app [class*="NavBar"][class*="wrapper"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border-right: 3px solid var(--tb-slate) !important;
|
border-right: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dashboard container */
|
/* Dashboard container */
|
||||||
@@ -413,8 +414,8 @@ img[alt*="Logo" i] {
|
|||||||
.grafana-app .panel-container,
|
.grafana-app .panel-container,
|
||||||
.grafana-app [class*="panel-content"],
|
.grafana-app [class*="panel-content"],
|
||||||
.grafana-app [class*="PanelChrome"] {
|
.grafana-app [class*="PanelChrome"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,10 +423,10 @@ img[alt*="Logo" i] {
|
|||||||
.grafana-app .panel-title,
|
.grafana-app .panel-title,
|
||||||
.grafana-app [class*="panel-header"],
|
.grafana-app [class*="panel-header"],
|
||||||
.grafana-app [class*="PanelHeader"] {
|
.grafana-app [class*="PanelHeader"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 9px !important;
|
font-size: 9px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Explore page */
|
/* Explore page */
|
||||||
@@ -437,21 +438,21 @@ img[alt*="Logo" i] {
|
|||||||
/* Grafana query editor */
|
/* Grafana query editor */
|
||||||
.grafana-app [class*="query-editor"],
|
.grafana-app [class*="query-editor"],
|
||||||
.grafana-app [class*="QueryEditor"] {
|
.grafana-app [class*="QueryEditor"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alert list */
|
/* Alert list */
|
||||||
.grafana-app [class*="AlertList"],
|
.grafana-app [class*="AlertList"],
|
||||||
.grafana-app [class*="alert-rule"] {
|
.grafana-app [class*="alert-rule"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 1px solid var(--tb-slate) !important;
|
border: 1px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grafana page toolbar */
|
/* Grafana page toolbar */
|
||||||
.grafana-app [class*="page-toolbar"],
|
.grafana-app [class*="page-toolbar"],
|
||||||
.grafana-app [class*="PageToolbar"] {
|
.grafana-app [class*="PageToolbar"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -473,8 +474,8 @@ header img[alt*="Jaeger" i] {
|
|||||||
.jaeger-ui [class*="TopNav"],
|
.jaeger-ui [class*="TopNav"],
|
||||||
[class*="jaeger"] [class*="TopNav"],
|
[class*="jaeger"] [class*="TopNav"],
|
||||||
[data-testid="TopNav"] {
|
[data-testid="TopNav"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trace page */
|
/* Trace page */
|
||||||
@@ -486,8 +487,8 @@ header img[alt*="Jaeger" i] {
|
|||||||
/* Timeline viewer */
|
/* Timeline viewer */
|
||||||
.TraceTimelineViewer,
|
.TraceTimelineViewer,
|
||||||
[class*="TraceTimelineViewer"] {
|
[class*="TraceTimelineViewer"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Span bars */
|
/* Span bars */
|
||||||
@@ -499,16 +500,16 @@ header img[alt*="Jaeger" i] {
|
|||||||
.SearchForm,
|
.SearchForm,
|
||||||
[class*="SearchForm"],
|
[class*="SearchForm"],
|
||||||
[class*="search-form"] {
|
[class*="search-form"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trace result list */
|
/* Trace result list */
|
||||||
[class*="ResultItem"],
|
[class*="ResultItem"],
|
||||||
[class*="result-item"] {
|
[class*="result-item"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 1px solid var(--tb-slate) !important;
|
border: 1px solid var(--ds-slate) !important;
|
||||||
margin-bottom: 4px !important;
|
margin-bottom: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,15 +521,15 @@ header img[alt*="Jaeger" i] {
|
|||||||
/* Span detail */
|
/* Span detail */
|
||||||
[class*="SpanDetail"],
|
[class*="SpanDetail"],
|
||||||
[class*="AccordianKeyValues"] {
|
[class*="AccordianKeyValues"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Jaeger-specific selects */
|
/* Jaeger-specific selects */
|
||||||
.jaeger-ui select,
|
.jaeger-ui select,
|
||||||
[class*="jaeger"] select {
|
[class*="jaeger"] select {
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -547,23 +548,23 @@ nav.navbar svg,
|
|||||||
/* Main navbar */
|
/* Main navbar */
|
||||||
.prometheus-app nav.navbar,
|
.prometheus-app nav.navbar,
|
||||||
nav.navbar {
|
nav.navbar {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav.navbar .navbar-brand {
|
nav.navbar .navbar-brand {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expression input */
|
/* Expression input */
|
||||||
.prometheus-app .expression-input,
|
.prometheus-app .expression-input,
|
||||||
[class*="expression-input"],
|
[class*="expression-input"],
|
||||||
.cm-expression-input {
|
.cm-expression-input {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,8 +572,8 @@ nav.navbar .navbar-brand {
|
|||||||
.graph-container,
|
.graph-container,
|
||||||
[class*="graph-container"],
|
[class*="graph-container"],
|
||||||
.panel {
|
.panel {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,52 +581,52 @@ nav.navbar .navbar-brand {
|
|||||||
.graph-controls,
|
.graph-controls,
|
||||||
[class*="graph-controls"],
|
[class*="graph-controls"],
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 2px solid var(--tb-slate) !important;
|
border-bottom: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-link,
|
.nav-tabs .nav-link,
|
||||||
.nav-tabs a {
|
.nav-tabs a {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-link.active,
|
.nav-tabs .nav-link.active,
|
||||||
.nav-tabs .active a {
|
.nav-tabs .active a {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border-bottom: 3px solid var(--tb-blue) !important;
|
border-bottom: 3px solid var(--ds-blue) !important;
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alert/Rule manager */
|
/* Alert/Rule manager */
|
||||||
.rules-head,
|
.rules-head,
|
||||||
[class*="rules"] th {
|
[class*="rules"] th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prometheus targets page */
|
/* Prometheus targets page */
|
||||||
.target-head,
|
.target-head,
|
||||||
[class*="scrape-pool"] h2 {
|
[class*="scrape-pool"] h2 {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Status badges */
|
/* Status badges */
|
||||||
.badge-success,
|
.badge-success,
|
||||||
.label-success {
|
.label-success {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-danger,
|
.badge-danger,
|
||||||
.label-danger {
|
.label-danger {
|
||||||
background: var(--tb-red) !important;
|
background: var(--ds-red) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-warning,
|
.badge-warning,
|
||||||
.label-warning {
|
.label-warning {
|
||||||
background: var(--tb-yellow) !important;
|
background: var(--ds-yellow) !important;
|
||||||
color: var(--tb-navy) !important;
|
color: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -651,22 +652,22 @@ nav.navbar .navbar-brand {
|
|||||||
#app nav,
|
#app nav,
|
||||||
#app [class*="nav-bar"],
|
#app [class*="nav-bar"],
|
||||||
#app .navbar {
|
#app .navbar {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar */
|
/* Sidebar */
|
||||||
#app [class*="sidebar"],
|
#app [class*="sidebar"],
|
||||||
#app [class*="side-menu"],
|
#app [class*="side-menu"],
|
||||||
#app aside {
|
#app aside {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border-right: 3px solid var(--tb-slate) !important;
|
border-right: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar menu items */
|
/* Sidebar menu items */
|
||||||
#app [class*="sidebar"] a,
|
#app [class*="sidebar"] a,
|
||||||
#app [class*="side-menu"] a {
|
#app [class*="side-menu"] a {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
border-left: 3px solid transparent !important;
|
border-left: 3px solid transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,9 +675,9 @@ nav.navbar .navbar-brand {
|
|||||||
#app [class*="side-menu"] a:hover,
|
#app [class*="side-menu"] a:hover,
|
||||||
#app [class*="sidebar"] a.active,
|
#app [class*="sidebar"] a.active,
|
||||||
#app [class*="side-menu"] a.active {
|
#app [class*="side-menu"] a.active {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
border-left-color: var(--tb-blue) !important;
|
border-left-color: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main content area */
|
/* Main content area */
|
||||||
@@ -691,22 +692,22 @@ nav.navbar .navbar-brand {
|
|||||||
#app [class*="status"][class*="success"],
|
#app [class*="status"][class*="success"],
|
||||||
#app [class*="pill"][class*="green"],
|
#app [class*="pill"][class*="green"],
|
||||||
#app [class*="positive"] {
|
#app [class*="positive"] {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app [class*="status"][class*="negative"],
|
#app [class*="status"][class*="negative"],
|
||||||
#app [class*="status"][class*="error"],
|
#app [class*="status"][class*="error"],
|
||||||
#app [class*="pill"][class*="red"],
|
#app [class*="pill"][class*="red"],
|
||||||
#app [class*="negative"] {
|
#app [class*="negative"] {
|
||||||
background: var(--tb-red) !important;
|
background: var(--ds-red) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app [class*="status"][class*="warning"],
|
#app [class*="status"][class*="warning"],
|
||||||
#app [class*="pill"][class*="orange"] {
|
#app [class*="pill"][class*="orange"] {
|
||||||
background: var(--tb-yellow) !important;
|
background: var(--ds-yellow) !important;
|
||||||
color: var(--tb-navy) !important;
|
color: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Traefik table rows */
|
/* Traefik table rows */
|
||||||
@@ -717,8 +718,8 @@ nav.navbar .navbar-brand {
|
|||||||
/* Service detail panels */
|
/* Service detail panels */
|
||||||
#app [class*="detail"],
|
#app [class*="detail"],
|
||||||
#app [class*="panel-block"] {
|
#app [class*="panel-block"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -745,8 +746,8 @@ nav.navbar .navbar-brand {
|
|||||||
/* App bar */
|
/* App bar */
|
||||||
#root .MuiAppBar-root,
|
#root .MuiAppBar-root,
|
||||||
#root [class*="MuiAppBar"] {
|
#root [class*="MuiAppBar"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,45 +755,45 @@ nav.navbar .navbar-brand {
|
|||||||
#root .MuiDrawer-root,
|
#root .MuiDrawer-root,
|
||||||
#root .MuiDrawer-paper,
|
#root .MuiDrawer-paper,
|
||||||
#root [class*="MuiDrawer"] {
|
#root [class*="MuiDrawer"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border-right: 3px solid var(--tb-slate) !important;
|
border-right: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drawer list items */
|
/* Drawer list items */
|
||||||
#root .MuiListItem-root,
|
#root .MuiListItem-root,
|
||||||
#root .MuiListItemButton-root,
|
#root .MuiListItemButton-root,
|
||||||
#root [class*="MuiListItem"] {
|
#root [class*="MuiListItem"] {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiListItem-root:hover,
|
#root .MuiListItem-root:hover,
|
||||||
#root .MuiListItemButton-root:hover,
|
#root .MuiListItemButton-root:hover,
|
||||||
#root [class*="MuiListItem"]:hover {
|
#root [class*="MuiListItem"]:hover {
|
||||||
background: rgba(51, 102, 204, 0.2) !important;
|
background: rgba(51, 102, 204, 0.2) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .Mui-selected,
|
#root .Mui-selected,
|
||||||
#root [class*="Mui-selected"] {
|
#root [class*="Mui-selected"] {
|
||||||
background: rgba(51, 102, 204, 0.3) !important;
|
background: rgba(51, 102, 204, 0.3) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Paper */
|
/* MUI Paper */
|
||||||
#root .MuiPaper-root,
|
#root .MuiPaper-root,
|
||||||
#root [class*="MuiPaper"] {
|
#root [class*="MuiPaper"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Buttons */
|
/* MUI Buttons */
|
||||||
#root .MuiButton-root,
|
#root .MuiButton-root,
|
||||||
#root [class*="MuiButton"] {
|
#root [class*="MuiButton"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
text-transform: none !important;
|
text-transform: none !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
@@ -800,34 +801,34 @@ nav.navbar .navbar-brand {
|
|||||||
|
|
||||||
#root .MuiButton-root:hover,
|
#root .MuiButton-root:hover,
|
||||||
#root [class*="MuiButton"]:hover {
|
#root [class*="MuiButton"]:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiButton-containedPrimary,
|
#root .MuiButton-containedPrimary,
|
||||||
#root [class*="MuiButton-containedPrimary"] {
|
#root [class*="MuiButton-containedPrimary"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-blue-light) !important;
|
border: 2px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiButton-containedPrimary:hover {
|
#root .MuiButton-containedPrimary:hover {
|
||||||
background: var(--tb-blue-light) !important;
|
background: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Table */
|
/* MUI Table */
|
||||||
#root .MuiTableCell-root,
|
#root .MuiTableCell-root,
|
||||||
#root [class*="MuiTableCell"] {
|
#root [class*="MuiTableCell"] {
|
||||||
border-color: var(--tb-slate) !important;
|
border-color: var(--ds-slate) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiTableCell-head,
|
#root .MuiTableCell-head,
|
||||||
#root [class*="MuiTableCell-head"] {
|
#root [class*="MuiTableCell-head"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 9px !important;
|
font-size: 9px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
}
|
}
|
||||||
@@ -842,64 +843,64 @@ nav.navbar .navbar-brand {
|
|||||||
#root .MuiOutlinedInput-root,
|
#root .MuiOutlinedInput-root,
|
||||||
#root [class*="MuiInputBase"],
|
#root [class*="MuiInputBase"],
|
||||||
#root [class*="MuiOutlinedInput"] {
|
#root [class*="MuiOutlinedInput"] {
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiOutlinedInput-notchedOutline,
|
#root .MuiOutlinedInput-notchedOutline,
|
||||||
#root [class*="notchedOutline"] {
|
#root [class*="notchedOutline"] {
|
||||||
border-color: var(--tb-slate) !important;
|
border-color: var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiInputLabel-root,
|
#root .MuiInputLabel-root,
|
||||||
#root [class*="MuiInputLabel"] {
|
#root [class*="MuiInputLabel"] {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Dialogs */
|
/* MUI Dialogs */
|
||||||
#root .MuiDialog-paper,
|
#root .MuiDialog-paper,
|
||||||
#root [class*="MuiDialog-paper"] {
|
#root [class*="MuiDialog-paper"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Tabs */
|
/* MUI Tabs */
|
||||||
#root .MuiTab-root,
|
#root .MuiTab-root,
|
||||||
#root [class*="MuiTab"] {
|
#root [class*="MuiTab"] {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
text-transform: none !important;
|
text-transform: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiTab-root.Mui-selected,
|
#root .MuiTab-root.Mui-selected,
|
||||||
#root [class*="MuiTab"][class*="Mui-selected"] {
|
#root [class*="MuiTab"][class*="Mui-selected"] {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root .MuiTabs-indicator,
|
#root .MuiTabs-indicator,
|
||||||
#root [class*="MuiTabs-indicator"] {
|
#root [class*="MuiTabs-indicator"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Breadcrumbs */
|
/* MUI Breadcrumbs */
|
||||||
#root .MuiBreadcrumbs-root,
|
#root .MuiBreadcrumbs-root,
|
||||||
#root [class*="MuiBreadcrumbs"] {
|
#root [class*="MuiBreadcrumbs"] {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Chips */
|
/* MUI Chips */
|
||||||
#root .MuiChip-root,
|
#root .MuiChip-root,
|
||||||
#root [class*="MuiChip"] {
|
#root [class*="MuiChip"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUI Icons */
|
/* MUI Icons */
|
||||||
#root .MuiSvgIcon-root,
|
#root .MuiSvgIcon-root,
|
||||||
#root [class*="MuiSvgIcon"],
|
#root [class*="MuiSvgIcon"],
|
||||||
#root svg {
|
#root svg {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
fill: currentColor !important;
|
fill: currentColor !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,10 +912,10 @@ nav.navbar .navbar-brand {
|
|||||||
/* Trino has a simple UI - mostly tables and headers */
|
/* Trino has a simple UI - mostly tables and headers */
|
||||||
body > h2,
|
body > h2,
|
||||||
body > h3 {
|
body > h3 {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding: 10px 0 !important;
|
padding: 10px 0 !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
margin-bottom: 15px !important;
|
margin-bottom: 15px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,8 +928,8 @@ body > table {
|
|||||||
/* Trino worker status */
|
/* Trino worker status */
|
||||||
[class*="query-list"],
|
[class*="query-list"],
|
||||||
[class*="query-detail"] {
|
[class*="query-detail"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Progress bars used by various services */
|
/* Progress bars used by various services */
|
||||||
@@ -936,15 +937,15 @@ progress,
|
|||||||
[role="progressbar"],
|
[role="progressbar"],
|
||||||
[class*="progress-bar"],
|
[class*="progress-bar"],
|
||||||
[class*="ProgressBar"] {
|
[class*="ProgressBar"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 1px solid var(--tb-slate) !important;
|
border: 1px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress::-webkit-progress-bar {
|
progress::-webkit-progress-bar {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress::-webkit-progress-value {
|
progress::-webkit-progress-value {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
26
styles/loch.css
Normal file
26
styles/loch.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* LOCH — deep-navy design system
|
||||||
|
Single source of truth for the colour palette.
|
||||||
|
When changing a color here, propagate to the service-specific files:
|
||||||
|
inject.css, dashboard.css, gitea.css, woodpecker.css, marimo.css */
|
||||||
|
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--ds-navy: #0a1628;
|
||||||
|
--ds-navy-light: #162040;
|
||||||
|
--ds-navy-mid: #1e2d50;
|
||||||
|
--ds-slate: #2a3f5f;
|
||||||
|
--ds-steel: #5a7090;
|
||||||
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
|
--ds-blue: #3366cc;
|
||||||
|
--ds-blue-light: #5588dd;
|
||||||
|
--ds-blue-bright: #88aaee;
|
||||||
|
|
||||||
|
--ds-red: #cc2244;
|
||||||
|
--ds-red-light: #dd4466;
|
||||||
|
|
||||||
|
--ds-green: #44aa44;
|
||||||
|
--ds-green-light: #66cc66;
|
||||||
|
--ds-yellow: #ddaa33;
|
||||||
|
}
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
/* THROWBACK THEME - Tecmo Super Bowl */
|
/* LOCH — deep-navy design system */
|
||||||
/* Full marimo theme: semantic vars, Radix scales, prose, CodeMirror */
|
/* Full marimo theme: semantic vars, Radix scales, prose, CodeMirror */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
THROWBACK COLOR PALETTE
|
LOCH COLOR PALETTE
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #8a9fbb;
|
--ds-steel: #8a9fbb;
|
||||||
--tb-silver: #b0c0d8;
|
--ds-silver: #b0c0d8;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #4477dd;
|
--ds-blue: #4477dd;
|
||||||
--tb-blue-light: #6699ee;
|
--ds-blue-light: #6699ee;
|
||||||
--tb-blue-bright: #99bbff;
|
--ds-blue-bright: #99bbff;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #ee6688;
|
--ds-red-light: #ee6688;
|
||||||
--tb-red-bright: #ffaabc;
|
--ds-red-bright: #ffaabc;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
--tb-green-light: #77dd77;
|
--ds-green-light: #77dd77;
|
||||||
--tb-green-bright: #b1f1b1;
|
--ds-green-bright: #b1f1b1;
|
||||||
|
|
||||||
--tb-yellow: #eebb44;
|
--ds-yellow: #eebb44;
|
||||||
--tb-yellow-light: #ffdd77;
|
--ds-yellow-light: #ffdd77;
|
||||||
--tb-yellow-bright: #fff0bb;
|
--ds-yellow-bright: #fff0bb;
|
||||||
|
|
||||||
--tb-purple: #9977cc;
|
--ds-purple: #9977cc;
|
||||||
--tb-purple-light: #bb99ee;
|
--ds-purple-light: #bb99ee;
|
||||||
|
|
||||||
--tb-cyan: #55bbcc;
|
--ds-cyan: #55bbcc;
|
||||||
--tb-cyan-light: #88ddee;
|
--ds-cyan-light: #88ddee;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -44,57 +44,57 @@
|
|||||||
:root {
|
:root {
|
||||||
--monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
--heading-font: 'IBM Plex Mono', monospace;
|
||||||
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--marimo-monospace-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
--marimo-text-font: 'IBM Plex Mono', 'Courier New', monospace;
|
||||||
--marimo-heading-font: 'Press Start 2P', 'IBM Plex Mono', monospace;
|
--marimo-heading-font: 'IBM Plex Mono', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
MARIMO SEMANTIC VARIABLES
|
MARIMO SEMANTIC VARIABLES
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
--background: var(--tb-navy);
|
--background: var(--ds-navy);
|
||||||
--foreground: var(--tb-white);
|
--foreground: var(--ds-white);
|
||||||
|
|
||||||
--muted: var(--tb-navy-light);
|
--muted: var(--ds-navy-light);
|
||||||
--muted-foreground: var(--tb-steel);
|
--muted-foreground: var(--ds-steel);
|
||||||
|
|
||||||
--popover: var(--tb-navy-light);
|
--popover: var(--ds-navy-light);
|
||||||
--popover-foreground: var(--tb-white);
|
--popover-foreground: var(--ds-white);
|
||||||
|
|
||||||
--card: var(--tb-navy);
|
--card: var(--ds-navy);
|
||||||
--card-foreground: var(--tb-white);
|
--card-foreground: var(--ds-white);
|
||||||
|
|
||||||
--border: var(--tb-slate);
|
--border: var(--ds-slate);
|
||||||
--input: var(--tb-navy-mid);
|
--input: var(--ds-navy-mid);
|
||||||
--ring: var(--tb-blue-light);
|
--ring: var(--ds-blue-light);
|
||||||
--radius: 2px;
|
--radius: 2px;
|
||||||
|
|
||||||
--primary: var(--tb-blue);
|
--primary: var(--ds-blue);
|
||||||
--primary-foreground: var(--tb-white);
|
--primary-foreground: var(--ds-white);
|
||||||
|
|
||||||
--secondary: var(--tb-slate);
|
--secondary: var(--ds-slate);
|
||||||
--secondary-foreground: var(--tb-white);
|
--secondary-foreground: var(--ds-white);
|
||||||
|
|
||||||
--accent: var(--tb-navy-mid);
|
--accent: var(--ds-navy-mid);
|
||||||
--accent-foreground: var(--tb-blue-bright);
|
--accent-foreground: var(--ds-blue-bright);
|
||||||
|
|
||||||
--destructive: var(--tb-red);
|
--destructive: var(--ds-red);
|
||||||
--destructive-foreground: var(--tb-white);
|
--destructive-foreground: var(--ds-white);
|
||||||
|
|
||||||
--error: var(--tb-red);
|
--error: var(--ds-red);
|
||||||
--error-foreground: var(--tb-white);
|
--error-foreground: var(--ds-white);
|
||||||
|
|
||||||
--success: var(--tb-green-light);
|
--success: var(--ds-green-light);
|
||||||
--success-foreground: var(--tb-white);
|
--success-foreground: var(--ds-white);
|
||||||
|
|
||||||
--action: var(--tb-yellow);
|
--action: var(--ds-yellow);
|
||||||
--action-hover: var(--tb-yellow-light);
|
--action-hover: var(--ds-yellow-light);
|
||||||
--action-foreground: var(--tb-navy);
|
--action-foreground: var(--ds-navy);
|
||||||
|
|
||||||
--link: var(--tb-blue-bright);
|
--link: var(--ds-blue-bright);
|
||||||
--link-visited: var(--tb-purple-light);
|
--link-visited: var(--ds-purple-light);
|
||||||
|
|
||||||
--stale: rgba(238, 187, 68, 0.25);
|
--stale: rgba(238, 187, 68, 0.25);
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
--base-shadow-darker: rgba(0, 0, 0, 0.6);
|
--base-shadow-darker: rgba(0, 0, 0, 0.6);
|
||||||
--base-shadow-opacity: 20%;
|
--base-shadow-opacity: 20%;
|
||||||
|
|
||||||
--cm-background: var(--tb-navy);
|
--cm-background: var(--ds-navy);
|
||||||
|
|
||||||
--background-image: none;
|
--background-image: none;
|
||||||
--background-repeat: no-repeat;
|
--background-repeat: no-repeat;
|
||||||
@@ -332,51 +332,51 @@
|
|||||||
TAILWIND PROSE - Markdown content
|
TAILWIND PROSE - Markdown content
|
||||||
============================================ */
|
============================================ */
|
||||||
:root {
|
:root {
|
||||||
--tw-prose-body: var(--tb-white);
|
--tw-prose-body: var(--ds-white);
|
||||||
--tw-prose-headings: var(--tb-white);
|
--tw-prose-headings: var(--ds-white);
|
||||||
--tw-prose-lead: var(--tb-silver);
|
--tw-prose-lead: var(--ds-silver);
|
||||||
--tw-prose-links: var(--tb-blue-bright);
|
--tw-prose-links: var(--ds-blue-bright);
|
||||||
--tw-prose-bold: var(--tb-white);
|
--tw-prose-bold: var(--ds-white);
|
||||||
--tw-prose-counters: var(--tb-steel);
|
--tw-prose-counters: var(--ds-steel);
|
||||||
--tw-prose-bullets: var(--tb-steel);
|
--tw-prose-bullets: var(--ds-steel);
|
||||||
--tw-prose-hr: var(--tb-slate);
|
--tw-prose-hr: var(--ds-slate);
|
||||||
--tw-prose-quotes: var(--tb-silver);
|
--tw-prose-quotes: var(--ds-silver);
|
||||||
--tw-prose-quote-borders: var(--tb-slate);
|
--tw-prose-quote-borders: var(--ds-slate);
|
||||||
--tw-prose-captions: var(--tb-steel);
|
--tw-prose-captions: var(--ds-steel);
|
||||||
--tw-prose-kbd: var(--tb-white);
|
--tw-prose-kbd: var(--ds-white);
|
||||||
--tw-prose-kbd-shadows: rgba(240, 240, 240, 0.1);
|
--tw-prose-kbd-shadows: rgba(240, 240, 240, 0.1);
|
||||||
--tw-prose-code: var(--tb-blue-bright);
|
--tw-prose-code: var(--ds-blue-bright);
|
||||||
--tw-prose-pre-code: var(--tb-silver);
|
--tw-prose-pre-code: var(--ds-silver);
|
||||||
--tw-prose-pre-bg: var(--tb-navy-light);
|
--tw-prose-pre-bg: var(--ds-navy-light);
|
||||||
--tw-prose-th-borders: var(--tb-slate);
|
--tw-prose-th-borders: var(--ds-slate);
|
||||||
--tw-prose-td-borders: var(--tb-navy-mid);
|
--tw-prose-td-borders: var(--ds-navy-mid);
|
||||||
|
|
||||||
/* Invert variants (used in dark mode) */
|
/* Invert variants (used in dark mode) */
|
||||||
--tw-prose-invert-body: var(--tb-white);
|
--tw-prose-invert-body: var(--ds-white);
|
||||||
--tw-prose-invert-headings: var(--tb-white);
|
--tw-prose-invert-headings: var(--ds-white);
|
||||||
--tw-prose-invert-lead: var(--tb-silver);
|
--tw-prose-invert-lead: var(--ds-silver);
|
||||||
--tw-prose-invert-links: var(--tb-blue-bright);
|
--tw-prose-invert-links: var(--ds-blue-bright);
|
||||||
--tw-prose-invert-bold: var(--tb-white);
|
--tw-prose-invert-bold: var(--ds-white);
|
||||||
--tw-prose-invert-counters: var(--tb-steel);
|
--tw-prose-invert-counters: var(--ds-steel);
|
||||||
--tw-prose-invert-bullets: var(--tb-steel);
|
--tw-prose-invert-bullets: var(--ds-steel);
|
||||||
--tw-prose-invert-hr: var(--tb-slate);
|
--tw-prose-invert-hr: var(--ds-slate);
|
||||||
--tw-prose-invert-quotes: var(--tb-silver);
|
--tw-prose-invert-quotes: var(--ds-silver);
|
||||||
--tw-prose-invert-quote-borders: var(--tb-slate);
|
--tw-prose-invert-quote-borders: var(--ds-slate);
|
||||||
--tw-prose-invert-captions: var(--tb-steel);
|
--tw-prose-invert-captions: var(--ds-steel);
|
||||||
--tw-prose-invert-kbd: var(--tb-white);
|
--tw-prose-invert-kbd: var(--ds-white);
|
||||||
--tw-prose-invert-kbd-shadows: rgba(240, 240, 240, 0.1);
|
--tw-prose-invert-kbd-shadows: rgba(240, 240, 240, 0.1);
|
||||||
--tw-prose-invert-code: var(--tb-blue-bright);
|
--tw-prose-invert-code: var(--ds-blue-bright);
|
||||||
--tw-prose-invert-pre-code: var(--tb-silver);
|
--tw-prose-invert-pre-code: var(--ds-silver);
|
||||||
--tw-prose-invert-pre-bg: var(--tb-navy-light);
|
--tw-prose-invert-pre-bg: var(--ds-navy-light);
|
||||||
--tw-prose-invert-th-borders: var(--tb-slate);
|
--tw-prose-invert-th-borders: var(--ds-slate);
|
||||||
--tw-prose-invert-td-borders: var(--tb-navy-mid);
|
--tw-prose-invert-td-borders: var(--ds-navy-mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
BODY & BACKGROUNDS
|
BODY & BACKGROUNDS
|
||||||
============================================ */
|
============================================ */
|
||||||
body {
|
body {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -385,7 +385,7 @@ body {
|
|||||||
.cm-editor {
|
.cm-editor {
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-content {
|
.cm-content {
|
||||||
@@ -394,41 +394,41 @@ body {
|
|||||||
|
|
||||||
.cm-line {
|
.cm-line {
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-gutters {
|
.cm-gutters {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-right: 2px solid var(--tb-slate) !important;
|
border-right: 2px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-lineNumbers .cm-gutterElement {
|
.cm-lineNumbers .cm-gutterElement {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syntax highlighting */
|
/* Syntax highlighting */
|
||||||
.cm-keyword, .tok-keyword { color: var(--tb-blue-bright) !important; }
|
.cm-keyword, .tok-keyword { color: var(--ds-blue-bright) !important; }
|
||||||
.cm-string, .tok-string { color: var(--tb-green-light) !important; }
|
.cm-string, .tok-string { color: var(--ds-green-light) !important; }
|
||||||
.cm-number, .tok-number { color: var(--tb-yellow) !important; }
|
.cm-number, .tok-number { color: var(--ds-yellow) !important; }
|
||||||
.cm-comment, .tok-comment { color: var(--tb-steel) !important; font-style: italic !important; }
|
.cm-comment, .tok-comment { color: var(--ds-steel) !important; font-style: italic !important; }
|
||||||
.cm-function, .tok-function { color: var(--tb-white) !important; }
|
.cm-function, .tok-function { color: var(--ds-white) !important; }
|
||||||
.cm-variableName, .tok-variableName { color: var(--tb-white) !important; }
|
.cm-variableName, .tok-variableName { color: var(--ds-white) !important; }
|
||||||
.cm-operator, .tok-operator { color: var(--tb-blue-light) !important; }
|
.cm-operator, .tok-operator { color: var(--ds-blue-light) !important; }
|
||||||
.cm-propertyName, .tok-propertyName { color: var(--tb-blue-bright) !important; }
|
.cm-propertyName, .tok-propertyName { color: var(--ds-blue-bright) !important; }
|
||||||
.tok-standard, .cm-builtin { color: var(--tb-red-light) !important; }
|
.tok-standard, .cm-builtin { color: var(--ds-red-light) !important; }
|
||||||
.tok-definition, .cm-def { color: var(--tb-blue-bright) !important; }
|
.tok-definition, .cm-def { color: var(--ds-blue-bright) !important; }
|
||||||
.tok-typeName { color: var(--tb-yellow) !important; }
|
.tok-typeName { color: var(--ds-yellow) !important; }
|
||||||
.tok-bool { color: var(--tb-red-light) !important; }
|
.tok-bool { color: var(--ds-red-light) !important; }
|
||||||
|
|
||||||
.cm-cursor {
|
.cm-cursor {
|
||||||
border-left: 2px solid var(--tb-white) !important;
|
border-left: 2px solid var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-selectionBackground,
|
.cm-selectionBackground,
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-activeLine {
|
.cm-activeLine {
|
||||||
@@ -440,18 +440,19 @@ body {
|
|||||||
============================================ */
|
============================================ */
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: var(--heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
line-height: 1.8 !important;
|
line-height: 1.8 !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 { font-size: 18px !important; }
|
h1 { font-size: 18px !important; }
|
||||||
h2 { font-size: 14px !important; color: var(--tb-blue-bright) !important; }
|
h2 { font-size: 14px !important; color: var(--ds-blue-bright) !important; }
|
||||||
h3 { font-size: 12px !important; }
|
h3 { font-size: 12px !important; }
|
||||||
h4, h5, h6 { font-size: 11px !important; }
|
h4, h5, h6 { font-size: 11px !important; }
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
TABLES (Scoreboard style)
|
TABLES (Table styling)
|
||||||
============================================ */
|
============================================ */
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse !important;
|
border-collapse: collapse !important;
|
||||||
@@ -459,27 +460,27 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: var(--heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
padding: 10px 12px !important;
|
padding: 10px 12px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 1px !important;
|
letter-spacing: 1px !important;
|
||||||
border: 1px solid var(--tb-slate) !important;
|
border: 1px solid var(--ds-slate) !important;
|
||||||
border-bottom: 2px solid var(--tb-blue) !important;
|
border-bottom: 2px solid var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
border: 1px solid var(--tb-navy-light) !important;
|
border: 1px solid var(--ds-navy-light) !important;
|
||||||
font-size: 13px !important;
|
font-size: 13px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(even) td {
|
tr:nth-child(even) td {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:hover td {
|
tr:hover td {
|
||||||
@@ -501,15 +502,15 @@ button,
|
|||||||
button[data-variant="primary"],
|
button[data-variant="primary"],
|
||||||
button.primary,
|
button.primary,
|
||||||
[data-action="run"] {
|
[data-action="run"] {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-green-light) !important;
|
border: 2px solid var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
button[data-variant="primary"]:hover,
|
button[data-variant="primary"]:hover,
|
||||||
button.primary:hover,
|
button.primary:hover,
|
||||||
[data-action="run"]:hover {
|
[data-action="run"]:hover {
|
||||||
background: var(--tb-green-light) !important;
|
background: var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -519,9 +520,9 @@ input,
|
|||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 2px !important;
|
border-radius: 2px !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
}
|
}
|
||||||
@@ -529,7 +530,7 @@ select {
|
|||||||
input:focus,
|
input:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 0 0 2px rgba(102, 153, 238, 0.3) !important;
|
box-shadow: 0 0 0 2px rgba(102, 153, 238, 0.3) !important;
|
||||||
}
|
}
|
||||||
@@ -542,16 +543,16 @@ pre, code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border-radius: 2px !important;
|
border-radius: 2px !important;
|
||||||
font-size: 0.9em !important;
|
font-size: 0.9em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 2px !important;
|
border-radius: 2px !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
@@ -565,18 +566,18 @@ pre code {
|
|||||||
LINKS
|
LINKS
|
||||||
============================================ */
|
============================================ */
|
||||||
a {
|
a {
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
transition: color 0.15s ease !important;
|
transition: color 0.15s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--tb-purple-light) !important;
|
color: var(--ds-purple-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -588,17 +589,17 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--tb-slate);
|
background: var(--ds-slate);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 2px solid var(--tb-navy-light);
|
border: 2px solid var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--tb-steel);
|
background: var(--ds-steel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
@@ -608,16 +609,16 @@ a:visited {
|
|||||||
[data-state="open"][data-side] {
|
[data-state="open"][data-side] {
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 2px !important;
|
border-radius: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[role="menu"],
|
[role="menu"],
|
||||||
[role="listbox"] {
|
[role="listbox"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 2px !important;
|
border-radius: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,8 +626,8 @@ a:visited {
|
|||||||
[role="option"]:hover,
|
[role="option"]:hover,
|
||||||
[role="menuitem"][data-highlighted],
|
[role="menuitem"][data-highlighted],
|
||||||
[role="option"][data-highlighted] {
|
[role="option"][data-highlighted] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Badges and pills */
|
/* Badges and pills */
|
||||||
@@ -639,7 +640,7 @@ a:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid var(--tb-blue-light) !important;
|
outline: 2px solid var(--ds-blue-light) !important;
|
||||||
outline-offset: 2px !important;
|
outline-offset: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,7 +650,7 @@ a:visited {
|
|||||||
[data-testid="outputs"],
|
[data-testid="outputs"],
|
||||||
.output-area {
|
.output-area {
|
||||||
background: rgba(22, 32, 64, 0.5) !important;
|
background: rgba(22, 32, 64, 0.5) !important;
|
||||||
border-top: 2px solid var(--tb-slate) !important;
|
border-top: 2px solid var(--ds-slate) !important;
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,20 +668,20 @@ svg {
|
|||||||
HOME PAGE
|
HOME PAGE
|
||||||
============================================ */
|
============================================ */
|
||||||
a[rel="noreferrer"][target="_blank"] {
|
a[rel="noreferrer"][target="_blank"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a[rel="noreferrer"][target="_blank"]:hover {
|
a[rel="noreferrer"][target="_blank"]:hover {
|
||||||
border-color: var(--tb-blue) !important;
|
border-color: var(--ds-blue) !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a[rel="noreferrer"][target="_blank"] h2 {
|
a[rel="noreferrer"][target="_blank"] h2 {
|
||||||
font-family: var(--heading-font) !important;
|
font-family: var(--heading-font) !important;
|
||||||
font-size: 12px !important;
|
font-size: 12px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
}
|
}
|
||||||
@@ -690,27 +691,27 @@ h2.text-xl {
|
|||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
letter-spacing: 2px !important;
|
letter-spacing: 2px !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
border-bottom: 2px solid var(--tb-slate);
|
border-bottom: 2px solid var(--ds-slate);
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border.rounded {
|
.divide-y.border.rounded {
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border > a,
|
.divide-y.border > a,
|
||||||
.divide-y.border > div > a {
|
.divide-y.border > div > a {
|
||||||
border-color: var(--tb-navy-light) !important;
|
border-color: var(--ds-navy-light) !important;
|
||||||
transition: all 0.1s ease !important;
|
transition: all 0.1s ease !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border > a:hover,
|
.divide-y.border > a:hover,
|
||||||
.divide-y.border > div > a:hover {
|
.divide-y.border > div > a:hover {
|
||||||
background: rgba(68, 119, 221, 0.2) !important;
|
background: rgba(68, 119, 221, 0.2) !important;
|
||||||
border-left: 3px solid var(--tb-blue) !important;
|
border-left: 3px solid var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divide-y.border a .flex-1 span {
|
.divide-y.border a .flex-1 span {
|
||||||
@@ -727,7 +728,7 @@ h2.text-xl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
PIXEL-PERFECT BORDERS
|
BORDERS
|
||||||
============================================ */
|
============================================ */
|
||||||
.rounded-lg,
|
.rounded-lg,
|
||||||
.rounded-md {
|
.rounded-md {
|
||||||
@@ -743,33 +744,33 @@ h2.text-xl {
|
|||||||
TOP BAR / ACTION BUTTONS
|
TOP BAR / ACTION BUTTONS
|
||||||
============================================ */
|
============================================ */
|
||||||
.absolute.top-3.right-5 button {
|
.absolute.top-3.right-5 button {
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.absolute.top-3.right-5 button:hover {
|
.absolute.top-3.right-5 button:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
SEARCH INPUT
|
SEARCH INPUT
|
||||||
============================================ */
|
============================================ */
|
||||||
input#search {
|
input#search {
|
||||||
border: 3px solid var(--tb-slate) !important;
|
border: 3px solid var(--ds-slate) !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
font-family: var(--monospace-font) !important;
|
font-family: var(--monospace-font) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
input#search:focus {
|
input#search:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
box-shadow: 0 0 8px rgba(102, 153, 238, 0.3) !important;
|
box-shadow: 0 0 8px rgba(102, 153, 238, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
BUTTON PRESS EFFECT
|
BUTTON STATES
|
||||||
============================================ */
|
============================================ */
|
||||||
button:active,
|
button:active,
|
||||||
[role="button"]:active {
|
[role="button"]:active {
|
||||||
@@ -782,10 +783,10 @@ button:active,
|
|||||||
============================================ */
|
============================================ */
|
||||||
.dark .text-foreground,
|
.dark .text-foreground,
|
||||||
.text-foreground {
|
.text-foreground {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .text-muted-foreground,
|
.dark .text-muted-foreground,
|
||||||
.text-muted-foreground {
|
.text-muted-foreground {
|
||||||
color: var(--tb-steel) !important;
|
color: var(--ds-steel) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
209
styles/nature.py
Normal file
209
styles/nature.py
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
"""Nature Research figure standards — shared palette and theme.
|
||||||
|
|
||||||
|
Implements the specifications from Nature's "Preparing Figures" guide
|
||||||
|
(bib key ``9ASETLJ4``). Provides:
|
||||||
|
|
||||||
|
- ``PALETTE`` — 8-colour accessible sequence (colorblind-safe)
|
||||||
|
- ``SCHEMA_COLORS`` — pipeline schema → colour mapping for DAG viz
|
||||||
|
- ``altair_theme()`` — register-and-enable for Altair charts
|
||||||
|
- ``mpl_rc()`` — dict of matplotlib rcParams
|
||||||
|
- ``cytoscape_style()`` — Cytoscape.js stylesheet fragment
|
||||||
|
|
||||||
|
Key rules (Nature):
|
||||||
|
* Sans-serif typeface (Helvetica, Arial)
|
||||||
|
* Body text 5–7 pt; panel labels 8 pt bold lowercase
|
||||||
|
* Axis lines and tick marks mandatory
|
||||||
|
* No background gridlines, drop shadows, or decorative elements
|
||||||
|
* RGB colour space; accessible palette
|
||||||
|
* Units in parentheses on axis labels
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
# ── Accessible 8-colour palette ──────────────────────────────────────
|
||||||
|
# Adapted from Paul Tol's "bright" qualitative scheme — verified
|
||||||
|
# colourblind-safe via Coblis and WCAG contrast tools.
|
||||||
|
PALETTE = [
|
||||||
|
"#4477AA", # blue
|
||||||
|
"#EE6677", # red / rose
|
||||||
|
"#228833", # green
|
||||||
|
"#CCBB44", # yellow
|
||||||
|
"#66CCEE", # cyan
|
||||||
|
"#AA3377", # purple
|
||||||
|
"#BBBBBB", # grey
|
||||||
|
"#EE8866", # orange
|
||||||
|
]
|
||||||
|
|
||||||
|
# Semantic aliases
|
||||||
|
BLUE, RED, GREEN, YELLOW, CYAN, PURPLE, GREY, ORANGE = PALETTE
|
||||||
|
|
||||||
|
# ── Typography ────────────────────────────────────────────────────────
|
||||||
|
FONT_FAMILY = "Helvetica, Arial, sans-serif"
|
||||||
|
FONT_SIZE_BODY = 7 # pt — Nature range 5-7
|
||||||
|
FONT_SIZE_AXIS = 7 # pt
|
||||||
|
FONT_SIZE_TITLE = 8 # pt — panel label size
|
||||||
|
FONT_SIZE_LABEL = 8 # pt — bold lowercase panel labels
|
||||||
|
LINE_WIDTH = 0.75 # pt — axis/tick stroke
|
||||||
|
TICK_SIZE = 4 # pt
|
||||||
|
|
||||||
|
# ── Figure dimensions (single-column Nature width: 89 mm) ───────────
|
||||||
|
FIG_WIDTH_MM = 89
|
||||||
|
FIG_HEIGHT_MM = 60
|
||||||
|
FIG_WIDTH_IN = FIG_WIDTH_MM / 25.4
|
||||||
|
FIG_HEIGHT_IN = FIG_HEIGHT_MM / 25.4
|
||||||
|
DPI = 450 # Nature min for exported figures
|
||||||
|
|
||||||
|
# ── Background ────────────────────────────────────────────────────────
|
||||||
|
BG_DARK = "#1a1a2e" # app/notebook dark background
|
||||||
|
BG_CHART = "transparent" # chart area — let container bg show through
|
||||||
|
AXIS_COLOR = "#cccccc" # axis lines, ticks
|
||||||
|
TEXT_COLOR = "#e0e0e0" # labels on dark bg
|
||||||
|
TITLE_COLOR = "#ffffff" # title / panel label
|
||||||
|
|
||||||
|
|
||||||
|
# ── Pipeline schema colours (for DAG / lineage viz) ──────────────────
|
||||||
|
SCHEMA_COLORS: dict[str, str] = {
|
||||||
|
"core": BLUE,
|
||||||
|
"input_layer": CYAN,
|
||||||
|
"cclf": "#5588CC",
|
||||||
|
"claims_preprocessing": ORANGE,
|
||||||
|
"readmissions": GREEN,
|
||||||
|
"ahrq_measures": YELLOW,
|
||||||
|
"pharmacy": PURPLE,
|
||||||
|
"quality_measures": RED,
|
||||||
|
"hcc_suspecting": "#AA7744",
|
||||||
|
"provider_attribution": GREY,
|
||||||
|
"main": "#55AA99",
|
||||||
|
"data_quality": "#5588CC",
|
||||||
|
}
|
||||||
|
EXTERNAL_COLOR = "#888888"
|
||||||
|
|
||||||
|
|
||||||
|
def schema_color(schema: str) -> str:
|
||||||
|
"""Return the palette colour for a pipeline schema."""
|
||||||
|
return SCHEMA_COLORS.get(schema, EXTERNAL_COLOR)
|
||||||
|
|
||||||
|
|
||||||
|
# ── Altair theme ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _altair_theme() -> dict:
|
||||||
|
"""Vega-Lite config dict conforming to Nature specs."""
|
||||||
|
return {
|
||||||
|
"config": {
|
||||||
|
"background": BG_CHART,
|
||||||
|
"font": FONT_FAMILY,
|
||||||
|
"title": {
|
||||||
|
"font": FONT_FAMILY,
|
||||||
|
"fontSize": FONT_SIZE_TITLE,
|
||||||
|
"fontWeight": "bold",
|
||||||
|
"color": TITLE_COLOR,
|
||||||
|
"anchor": "start",
|
||||||
|
},
|
||||||
|
"axis": {
|
||||||
|
"labelFont": FONT_FAMILY,
|
||||||
|
"labelFontSize": FONT_SIZE_AXIS,
|
||||||
|
"labelColor": TEXT_COLOR,
|
||||||
|
"titleFont": FONT_FAMILY,
|
||||||
|
"titleFontSize": FONT_SIZE_AXIS,
|
||||||
|
"titleColor": TEXT_COLOR,
|
||||||
|
"gridColor": "transparent",
|
||||||
|
"gridOpacity": 0,
|
||||||
|
"domainColor": AXIS_COLOR,
|
||||||
|
"domainWidth": LINE_WIDTH,
|
||||||
|
"tickColor": AXIS_COLOR,
|
||||||
|
"tickSize": TICK_SIZE,
|
||||||
|
"tickWidth": LINE_WIDTH,
|
||||||
|
},
|
||||||
|
"legend": {
|
||||||
|
"labelFont": FONT_FAMILY,
|
||||||
|
"labelFontSize": FONT_SIZE_BODY,
|
||||||
|
"labelColor": TEXT_COLOR,
|
||||||
|
"titleFont": FONT_FAMILY,
|
||||||
|
"titleFontSize": FONT_SIZE_BODY,
|
||||||
|
"titleColor": TEXT_COLOR,
|
||||||
|
"symbolSize": 60,
|
||||||
|
},
|
||||||
|
"view": {
|
||||||
|
"stroke": "transparent",
|
||||||
|
},
|
||||||
|
"range": {
|
||||||
|
"category": PALETTE,
|
||||||
|
},
|
||||||
|
"mark": {
|
||||||
|
"color": PALETTE[0],
|
||||||
|
},
|
||||||
|
"bar": {
|
||||||
|
"color": PALETTE[0],
|
||||||
|
},
|
||||||
|
"arc": {
|
||||||
|
"stroke": BG_DARK,
|
||||||
|
"strokeWidth": 1,
|
||||||
|
},
|
||||||
|
"line": {
|
||||||
|
"strokeWidth": 1.5,
|
||||||
|
},
|
||||||
|
"point": {
|
||||||
|
"size": 40,
|
||||||
|
},
|
||||||
|
"area": {
|
||||||
|
"opacity": 0.7,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def altair_theme() -> None:
|
||||||
|
"""Register and enable the Nature theme for Altair."""
|
||||||
|
import altair as alt
|
||||||
|
|
||||||
|
alt.themes.register("nature", _altair_theme)
|
||||||
|
alt.themes.enable("nature")
|
||||||
|
|
||||||
|
|
||||||
|
# ── Matplotlib rcParams ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
def mpl_rc() -> dict:
|
||||||
|
"""Return an rcParams dict for ``matplotlib.rcParams.update()``."""
|
||||||
|
return {
|
||||||
|
"font.family": "sans-serif",
|
||||||
|
"font.sans-serif": ["Helvetica", "Arial", "DejaVu Sans"],
|
||||||
|
"font.size": FONT_SIZE_BODY,
|
||||||
|
"axes.titlesize": FONT_SIZE_TITLE,
|
||||||
|
"axes.titleweight": "bold",
|
||||||
|
"axes.labelsize": FONT_SIZE_AXIS,
|
||||||
|
"axes.linewidth": LINE_WIDTH,
|
||||||
|
"axes.edgecolor": AXIS_COLOR,
|
||||||
|
"axes.labelcolor": TEXT_COLOR,
|
||||||
|
"axes.facecolor": "none",
|
||||||
|
"axes.grid": False,
|
||||||
|
"axes.prop_cycle": __import__("cycler").cycler(color=PALETTE),
|
||||||
|
"xtick.major.size": TICK_SIZE,
|
||||||
|
"xtick.major.width": LINE_WIDTH,
|
||||||
|
"xtick.color": AXIS_COLOR,
|
||||||
|
"xtick.labelsize": FONT_SIZE_BODY,
|
||||||
|
"ytick.major.size": TICK_SIZE,
|
||||||
|
"ytick.major.width": LINE_WIDTH,
|
||||||
|
"ytick.color": AXIS_COLOR,
|
||||||
|
"ytick.labelsize": FONT_SIZE_BODY,
|
||||||
|
"figure.figsize": (FIG_WIDTH_IN, FIG_HEIGHT_IN),
|
||||||
|
"figure.dpi": DPI,
|
||||||
|
"figure.facecolor": BG_DARK,
|
||||||
|
"savefig.dpi": DPI,
|
||||||
|
"savefig.facecolor": BG_DARK,
|
||||||
|
"legend.fontsize": FONT_SIZE_BODY,
|
||||||
|
"legend.frameon": False,
|
||||||
|
"text.color": TEXT_COLOR,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ── Cytoscape.js style helpers ───────────────────────────────────────
|
||||||
|
|
||||||
|
def cytoscape_node_style() -> dict:
|
||||||
|
"""Base Cytoscape.js node style properties (Nature-conformant)."""
|
||||||
|
return {
|
||||||
|
"font-family": FONT_FAMILY,
|
||||||
|
"font-size": "9px",
|
||||||
|
"text-valign": "center",
|
||||||
|
"text-halign": "center",
|
||||||
|
"shape": "round-rectangle",
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/* THROWBACK COLOR PALETTE — Single Source of Truth
|
|
||||||
Tecmo Super Bowl inspired: deep navy, white text, patriotic red/blue
|
|
||||||
When changing a color here, propagate to the service-specific files:
|
|
||||||
inject.css, dashboard.css, gitea.css, woodpecker.css, marimo.css */
|
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--tb-navy: #0a1628;
|
|
||||||
--tb-navy-light: #162040;
|
|
||||||
--tb-navy-mid: #1e2d50;
|
|
||||||
--tb-slate: #2a3f5f;
|
|
||||||
--tb-steel: #5a7090;
|
|
||||||
--tb-white: #f0f0f0;
|
|
||||||
|
|
||||||
--tb-blue: #3366cc;
|
|
||||||
--tb-blue-light: #5588dd;
|
|
||||||
--tb-blue-bright: #88aaee;
|
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
|
||||||
--tb-red-light: #dd4466;
|
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
|
||||||
--tb-green-light: #66cc66;
|
|
||||||
--tb-yellow: #ddaa33;
|
|
||||||
}
|
|
||||||
@@ -1,69 +1,70 @@
|
|||||||
/* THROWBACK THEME FOR WOODPECKER CI - Tecmo Super Bowl */
|
/* LOCH — deep-navy design system for Woodpecker CI */
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Throwback Color Palette */
|
/* Loch Color Palette */
|
||||||
--tb-navy: #0a1628;
|
--ds-navy: #0a1628;
|
||||||
--tb-navy-light: #162040;
|
--ds-navy-light: #162040;
|
||||||
--tb-navy-mid: #1e2d50;
|
--ds-navy-mid: #1e2d50;
|
||||||
--tb-slate: #2a3f5f;
|
--ds-slate: #2a3f5f;
|
||||||
--tb-steel: #5a7090;
|
--ds-steel: #5a7090;
|
||||||
--tb-white: #f0f0f0;
|
--ds-white: #f0f0f0;
|
||||||
|
|
||||||
--tb-blue: #3366cc;
|
--ds-blue: #3366cc;
|
||||||
--tb-blue-light: #5588dd;
|
--ds-blue-light: #5588dd;
|
||||||
--tb-blue-bright: #88aaee;
|
--ds-blue-bright: #88aaee;
|
||||||
|
|
||||||
--tb-red: #cc2244;
|
--ds-red: #cc2244;
|
||||||
--tb-red-light: #dd4466;
|
--ds-red-light: #dd4466;
|
||||||
|
|
||||||
--tb-green: #44aa44;
|
--ds-green: #44aa44;
|
||||||
--tb-green-light: #66cc66;
|
--ds-green-light: #66cc66;
|
||||||
--tb-yellow: #ddaa33;
|
--ds-yellow: #ddaa33;
|
||||||
|
|
||||||
/* Woodpecker color overrides */
|
/* Woodpecker color overrides */
|
||||||
--color-wp-primary-100: var(--tb-blue-bright);
|
--color-wp-primary-100: var(--ds-blue-bright);
|
||||||
--color-wp-primary-200: var(--tb-blue-light);
|
--color-wp-primary-200: var(--ds-blue-light);
|
||||||
--color-wp-primary-300: var(--tb-blue);
|
--color-wp-primary-300: var(--ds-blue);
|
||||||
--color-wp-primary-400: #2255aa;
|
--color-wp-primary-400: #2255aa;
|
||||||
--color-wp-primary-500: var(--tb-navy);
|
--color-wp-primary-500: var(--ds-navy);
|
||||||
|
|
||||||
--color-wp-success-100: var(--tb-green-light);
|
--color-wp-success-100: var(--ds-green-light);
|
||||||
--color-wp-success-200: var(--tb-green);
|
--color-wp-success-200: var(--ds-green);
|
||||||
|
|
||||||
--color-wp-error-100: var(--tb-red-light);
|
--color-wp-error-100: var(--ds-red-light);
|
||||||
--color-wp-error-200: var(--tb-red);
|
--color-wp-error-200: var(--ds-red);
|
||||||
|
|
||||||
--color-wp-warning-100: var(--tb-yellow);
|
--color-wp-warning-100: var(--ds-yellow);
|
||||||
--color-wp-warning-200: #bb8822;
|
--color-wp-warning-200: #bb8822;
|
||||||
|
|
||||||
--color-wp-gray-100: var(--tb-white);
|
--color-wp-gray-100: var(--ds-white);
|
||||||
--color-wp-gray-200: var(--tb-steel);
|
--color-wp-gray-200: var(--ds-steel);
|
||||||
--color-wp-gray-300: var(--tb-slate);
|
--color-wp-gray-300: var(--ds-slate);
|
||||||
--color-wp-gray-400: var(--tb-navy-mid);
|
--color-wp-gray-400: var(--ds-navy-mid);
|
||||||
--color-wp-gray-500: var(--tb-navy-light);
|
--color-wp-gray-500: var(--ds-navy-light);
|
||||||
--color-wp-gray-600: var(--tb-navy);
|
--color-wp-gray-600: var(--ds-navy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global styles */
|
/* Global styles */
|
||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Headings */
|
/* Headings */
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
letter-spacing: 0.5px !important;
|
letter-spacing: 0.5px !important;
|
||||||
line-height: 1.8 !important;
|
line-height: 1.8 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 { font-size: 18px !important; color: var(--tb-white) !important; }
|
h1 { font-size: 18px !important; color: var(--ds-white) !important; }
|
||||||
h2 { font-size: 14px !important; color: var(--tb-blue-bright) !important; }
|
h2 { font-size: 14px !important; color: var(--ds-blue-bright) !important; }
|
||||||
h3 { font-size: 12px !important; color: var(--tb-white) !important; }
|
h3 { font-size: 12px !important; color: var(--ds-white) !important; }
|
||||||
|
|
||||||
/* Header/Navbar */
|
/* Header/Navbar */
|
||||||
header,
|
header,
|
||||||
@@ -71,16 +72,16 @@ nav,
|
|||||||
.navbar,
|
.navbar,
|
||||||
[class*="header"],
|
[class*="header"],
|
||||||
[class*="Header"] {
|
[class*="Header"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border-bottom: 3px solid var(--tb-slate) !important;
|
border-bottom: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar */
|
/* Sidebar */
|
||||||
aside,
|
aside,
|
||||||
[class*="sidebar"],
|
[class*="sidebar"],
|
||||||
[class*="Sidebar"] {
|
[class*="Sidebar"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border-right: 3px solid var(--tb-slate) !important;
|
border-right: 3px solid var(--ds-slate) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main content area */
|
/* Main content area */
|
||||||
@@ -97,8 +98,8 @@ main,
|
|||||||
[class*="Panel"],
|
[class*="Panel"],
|
||||||
[class*="box"],
|
[class*="box"],
|
||||||
[class*="Box"] {
|
[class*="Box"] {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,16 +119,16 @@ button,
|
|||||||
[class*="primary"],
|
[class*="primary"],
|
||||||
[class*="Primary"],
|
[class*="Primary"],
|
||||||
button[type="submit"] {
|
button[type="submit"] {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-blue-light) !important;
|
border: 2px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="primary"]:hover,
|
[class*="primary"]:hover,
|
||||||
[class*="Primary"]:hover,
|
[class*="Primary"]:hover,
|
||||||
button[type="submit"]:hover {
|
button[type="submit"]:hover {
|
||||||
background: var(--tb-blue-light) !important;
|
background: var(--ds-blue-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Success/green buttons */
|
/* Success/green buttons */
|
||||||
@@ -135,15 +136,15 @@ button[type="submit"]:hover {
|
|||||||
[class*="Success"],
|
[class*="Success"],
|
||||||
[class*="green"],
|
[class*="green"],
|
||||||
[class*="Green"] {
|
[class*="Green"] {
|
||||||
background: var(--tb-green) !important;
|
background: var(--ds-green) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-green-light) !important;
|
border: 2px solid var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="success"]:hover,
|
[class*="success"]:hover,
|
||||||
[class*="Success"]:hover {
|
[class*="Success"]:hover {
|
||||||
background: var(--tb-green-light) !important;
|
background: var(--ds-green-light) !important;
|
||||||
color: var(--tb-navy) !important;
|
color: var(--ds-navy) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Danger/red buttons */
|
/* Danger/red buttons */
|
||||||
@@ -153,8 +154,8 @@ button[type="submit"]:hover {
|
|||||||
[class*="Error"],
|
[class*="Error"],
|
||||||
[class*="red"],
|
[class*="red"],
|
||||||
[class*="Red"] {
|
[class*="Red"] {
|
||||||
background: var(--tb-red) !important;
|
background: var(--ds-red) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forms */
|
/* Forms */
|
||||||
@@ -162,9 +163,9 @@ input,
|
|||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy-mid) !important;
|
background: var(--ds-navy-mid) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
}
|
}
|
||||||
@@ -172,37 +173,37 @@ select {
|
|||||||
input:focus,
|
input:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
select:focus {
|
select:focus {
|
||||||
border-color: var(--tb-blue-light) !important;
|
border-color: var(--ds-blue-light) !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
box-shadow: 0 0 0 2px rgba(85, 136, 221, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tables */
|
/* Tables */
|
||||||
table {
|
table {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-collapse: collapse !important;
|
border-collapse: collapse !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
font-family: 'Press Start 2P', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
font-size: 10px !important;
|
font-size: 10px !important;
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
padding: 10px 12px !important;
|
padding: 10px 12px !important;
|
||||||
border: 1px solid var(--tb-blue-light) !important;
|
border: 1px solid var(--ds-blue-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
padding: 8px 12px !important;
|
padding: 8px 12px !important;
|
||||||
border: 1px solid var(--tb-navy-light) !important;
|
border: 1px solid var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(even) td {
|
tr:nth-child(even) td {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:hover td {
|
tr:hover td {
|
||||||
@@ -214,14 +215,14 @@ tr:hover td {
|
|||||||
[class*="Running"],
|
[class*="Running"],
|
||||||
[class*="pending"],
|
[class*="pending"],
|
||||||
[class*="Pending"] {
|
[class*="Pending"] {
|
||||||
color: var(--tb-yellow) !important;
|
color: var(--ds-yellow) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="success"],
|
[class*="success"],
|
||||||
[class*="Success"],
|
[class*="Success"],
|
||||||
[class*="passed"],
|
[class*="passed"],
|
||||||
[class*="Passed"] {
|
[class*="Passed"] {
|
||||||
color: var(--tb-green-light) !important;
|
color: var(--ds-green-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="failure"],
|
[class*="failure"],
|
||||||
@@ -230,7 +231,7 @@ tr:hover td {
|
|||||||
[class*="Failed"],
|
[class*="Failed"],
|
||||||
[class*="error"],
|
[class*="error"],
|
||||||
[class*="Error"] {
|
[class*="Error"] {
|
||||||
color: var(--tb-red) !important;
|
color: var(--ds-red) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build logs */
|
/* Build logs */
|
||||||
@@ -241,28 +242,28 @@ code,
|
|||||||
[class*="console"],
|
[class*="console"],
|
||||||
[class*="Console"] {
|
[class*="Console"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy) !important;
|
background: var(--ds-navy) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inline code */
|
/* Inline code */
|
||||||
code {
|
code {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
a {
|
a {
|
||||||
color: var(--tb-blue-bright) !important;
|
color: var(--ds-blue-bright) !important;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
text-decoration: underline !important;
|
text-decoration: underline !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,8 +274,8 @@ a:hover {
|
|||||||
[class*="Menu"],
|
[class*="Menu"],
|
||||||
[class*="popover"],
|
[class*="popover"],
|
||||||
[class*="Popover"] {
|
[class*="Popover"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ a:hover {
|
|||||||
[class*="menu"] li:hover,
|
[class*="menu"] li:hover,
|
||||||
[role="menuitem"]:hover,
|
[role="menuitem"]:hover,
|
||||||
[role="option"]:hover {
|
[role="option"]:hover {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Badges and tags */
|
/* Badges and tags */
|
||||||
@@ -302,9 +303,9 @@ a:hover {
|
|||||||
[class*="tooltip"],
|
[class*="tooltip"],
|
||||||
[class*="Tooltip"] {
|
[class*="Tooltip"] {
|
||||||
font-family: 'IBM Plex Mono', monospace !important;
|
font-family: 'IBM Plex Mono', monospace !important;
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,17 +313,17 @@ a:hover {
|
|||||||
progress,
|
progress,
|
||||||
[class*="progress"],
|
[class*="progress"],
|
||||||
[class*="Progress"] {
|
[class*="Progress"] {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress::-webkit-progress-bar {
|
progress::-webkit-progress-bar {
|
||||||
background: var(--tb-navy-light) !important;
|
background: var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress::-webkit-progress-value {
|
progress::-webkit-progress-value {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrollbars */
|
/* Scrollbars */
|
||||||
@@ -332,22 +333,22 @@ progress::-webkit-progress-value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: var(--tb-navy-light);
|
background: var(--ds-navy-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--tb-slate);
|
background: var(--ds-slate);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: var(--tb-steel);
|
background: var(--ds-steel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selection */
|
/* Selection */
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--tb-blue) !important;
|
background: var(--ds-blue) !important;
|
||||||
color: var(--tb-white) !important;
|
color: var(--ds-white) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icons - ensure visibility */
|
/* Icons - ensure visibility */
|
||||||
@@ -360,7 +361,7 @@ svg,
|
|||||||
/* Avatar images */
|
/* Avatar images */
|
||||||
img[class*="avatar"],
|
img[class*="avatar"],
|
||||||
[class*="avatar"] img {
|
[class*="avatar"] img {
|
||||||
border: 2px solid var(--tb-slate) !important;
|
border: 2px solid var(--ds-slate) !important;
|
||||||
border-radius: 4px !important;
|
border-radius: 4px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +370,7 @@ img[class*="avatar"],
|
|||||||
[class*="Item"],
|
[class*="Item"],
|
||||||
[class*="list-item"],
|
[class*="list-item"],
|
||||||
[class*="ListItem"] {
|
[class*="ListItem"] {
|
||||||
border-bottom: 1px solid var(--tb-navy-light) !important;
|
border-bottom: 1px solid var(--ds-navy-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="item"]:hover,
|
[class*="item"]:hover,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"woodpecker-server" (dict "port" "8000" "theme" true "subdomain" "ci" "mw" "local-only,secure-headers")
|
"woodpecker-server" (dict "port" "8000" "theme" true "subdomain" "ci" "mw" "local-only,secure-headers")
|
||||||
"notebooks" (dict "port" "2718" "theme" true "mw" "local-only,secure-headers")
|
"notebooks" (dict "port" "2718" "theme" true "mw" "local-only,secure-headers")
|
||||||
"zotero" (dict "port" "8080" "theme" true "mw" "secure-headers")
|
"zotero" (dict "port" "8080" "theme" true "mw" "secure-headers")
|
||||||
|
"api" (dict "port" "8000" "theme" false "mw" "secure-headers")
|
||||||
"nessie" (dict "port" "19120" "theme" false "mw" "local-only,infra-headers")
|
"nessie" (dict "port" "19120" "theme" false "mw" "local-only,infra-headers")
|
||||||
"trino" (dict "port" "8080" "theme" true "mw" "local-only,infra-headers")
|
"trino" (dict "port" "8080" "theme" true "mw" "local-only,infra-headers")
|
||||||
"polaris" (dict "port" "8181" "theme" false "mw" "local-only,infra-headers")
|
"polaris" (dict "port" "8181" "theme" false "mw" "local-only,infra-headers")
|
||||||
@@ -40,13 +41,13 @@ http:
|
|||||||
referrerPolicy: "strict-origin-when-cross-origin"
|
referrerPolicy: "strict-origin-when-cross-origin"
|
||||||
customResponseHeaders:
|
customResponseHeaders:
|
||||||
X-Robots-Tag: "noindex, nofollow"
|
X-Robots-Tag: "noindex, nofollow"
|
||||||
inject-throwback:
|
inject-loch:
|
||||||
plugin:
|
plugin:
|
||||||
rewrite-body:
|
rewrite-body:
|
||||||
lastModified: true
|
lastModified: true
|
||||||
rewrites:
|
rewrites:
|
||||||
- regex: "</head>"
|
- regex: "</head>"
|
||||||
replacement: '<link rel="icon" type="image/png" sizes="32x32" href="http://{{ $domain }}/fav32.png"><link rel="stylesheet" type="text/css" href="http://{{ $domain }}/throwback.css"></head>'
|
replacement: '<link rel="icon" type="image/png" sizes="32x32" href="http://{{ $domain }}/fav32.png"><link rel="stylesheet" type="text/css" href="http://{{ $domain }}/loch.css"></head>'
|
||||||
routers:
|
routers:
|
||||||
{{- range $name, $svc := $reef }}
|
{{- range $name, $svc := $reef }}
|
||||||
{{ $name }}:
|
{{ $name }}:
|
||||||
@@ -55,7 +56,7 @@ http:
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
{{- $mwList := list -}}
|
{{- $mwList := list -}}
|
||||||
{{- if get $svc "theme" }}{{ $mwList = append $mwList "inject-throwback" }}{{ end -}}
|
{{- if get $svc "theme" }}{{ $mwList = append $mwList "inject-loch" }}{{ end -}}
|
||||||
{{- $extra := get $svc "mw" | default "" -}}
|
{{- $extra := get $svc "mw" | default "" -}}
|
||||||
{{- if ne $extra "" }}{{ range splitList "," $extra }}{{ $mwList = append $mwList (trim .) }}{{ end }}{{ end -}}
|
{{- if ne $extra "" }}{{ range splitList "," $extra }}{{ $mwList = append $mwList (trim .) }}{{ end }}{{ end -}}
|
||||||
{{- if $mwList }}
|
{{- if $mwList }}
|
||||||
@@ -72,7 +73,7 @@ http:
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
{{- $mwList := list -}}
|
{{- $mwList := list -}}
|
||||||
{{- if get $svc "theme" }}{{ $mwList = append $mwList "inject-throwback" }}{{ end -}}
|
{{- if get $svc "theme" }}{{ $mwList = append $mwList "inject-loch" }}{{ end -}}
|
||||||
{{- $extra := get $svc "mw" | default "" -}}
|
{{- $extra := get $svc "mw" | default "" -}}
|
||||||
{{- if ne $extra "" }}{{ range splitList "," $extra }}{{ $mwList = append $mwList (trim .) }}{{ end }}{{ end -}}
|
{{- if ne $extra "" }}{{ range splitList "," $extra }}{{ $mwList = append $mwList (trim .) }}{{ end }}{{ end -}}
|
||||||
{{- if $mwList }}
|
{{- if $mwList }}
|
||||||
@@ -88,7 +89,7 @@ http:
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
middlewares:
|
middlewares:
|
||||||
- inject-throwback
|
- inject-loch
|
||||||
- local-only
|
- local-only
|
||||||
- infra-headers
|
- infra-headers
|
||||||
services:
|
services:
|
||||||
|
|||||||
143
uv.lock
generated
143
uv.lock
generated
@@ -1,6 +1,14 @@
|
|||||||
version = 1
|
version = 1
|
||||||
revision = 3
|
revision = 3
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
resolution-markers = [
|
||||||
|
"python_full_version >= '3.14' and sys_platform == 'win32'",
|
||||||
|
"python_full_version >= '3.14' and sys_platform == 'emscripten'",
|
||||||
|
"python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||||
|
"python_full_version < '3.14' and sys_platform == 'win32'",
|
||||||
|
"python_full_version < '3.14' and sys_platform == 'emscripten'",
|
||||||
|
"python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "agate"
|
name = "agate"
|
||||||
@@ -20,6 +28,22 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/d1/53/89b197cb472a3175d73384761a3413fd58e6b65a794c1102d148b8de87bd/agate-1.9.1-py2.py3-none-any.whl", hash = "sha256:1cf329510b3dde07c4ad1740b7587c9c679abc3dcd92bb1107eabc10c2e03c50", size = 95085, upload-time = "2023-12-21T20:05:21.954Z" },
|
{ url = "https://files.pythonhosted.org/packages/d1/53/89b197cb472a3175d73384761a3413fd58e6b65a794c1102d148b8de87bd/agate-1.9.1-py2.py3-none-any.whl", hash = "sha256:1cf329510b3dde07c4ad1740b7587c9c679abc3dcd92bb1107eabc10c2e03c50", size = 95085, upload-time = "2023-12-21T20:05:21.954Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "altair"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "jinja2" },
|
||||||
|
{ name = "jsonschema" },
|
||||||
|
{ name = "narwhals" },
|
||||||
|
{ name = "packaging" },
|
||||||
|
{ name = "typing-extensions", marker = "python_full_version < '3.15'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f7/c0/184a89bd5feba14ff3c41cfaf1dd8a82c05f5ceedbc92145e17042eb08a4/altair-6.0.0.tar.gz", hash = "sha256:614bf5ecbe2337347b590afb111929aa9c16c9527c4887d96c9bc7f6640756b4", size = 763834, upload-time = "2025-11-12T08:59:11.519Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/db/33/ef2f2409450ef6daa61459d5de5c08128e7d3edb773fefd0a324d1310238/altair-6.0.0-py3-none-any.whl", hash = "sha256:09ae95b53d5fe5b16987dccc785a7af8588f2dca50de1e7a156efa8a461515f8", size = 795410, upload-time = "2025-11-12T08:59:09.804Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-doc"
|
name = "annotated-doc"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
@@ -1112,6 +1136,67 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" },
|
{ url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "numpy"
|
||||||
|
version = "2.4.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/10/8b/c265f4823726ab832de836cdd184d0986dcf94480f81e8739692a7ac7af2/numpy-2.4.3.tar.gz", hash = "sha256:483a201202b73495f00dbc83796c6ae63137a9bdade074f7648b3e32613412dd", size = 20727743, upload-time = "2026-03-09T07:58:53.426Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a9/ed/6388632536f9788cea23a3a1b629f25b43eaacd7d7377e5d6bc7b9deb69b/numpy-2.4.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:61b0cbabbb6126c8df63b9a3a0c4b1f44ebca5e12ff6997b80fcf267fb3150ef", size = 16669628, upload-time = "2026-03-09T07:56:24.252Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/1b/ee2abfc68e1ce728b2958b6ba831d65c62e1b13ce3017c13943f8f9b5b2e/numpy-2.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7395e69ff32526710748f92cd8c9849b361830968ea3e24a676f272653e8983e", size = 14696872, upload-time = "2026-03-09T07:56:26.991Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ba/d1/780400e915ff5638166f11ca9dc2c5815189f3d7cf6f8759a1685e586413/numpy-2.4.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:abdce0f71dcb4a00e4e77f3faf05e4616ceccfe72ccaa07f47ee79cda3b7b0f4", size = 5203489, upload-time = "2026-03-09T07:56:29.414Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/bb/baffa907e9da4cc34a6e556d6d90e032f6d7a75ea47968ea92b4858826c4/numpy-2.4.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:48da3a4ee1336454b07497ff7ec83903efa5505792c4e6d9bf83d99dc07a1e18", size = 6550814, upload-time = "2026-03-09T07:56:32.225Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/12/8c9f0c6c95f76aeb20fc4a699c33e9f827fa0d0f857747c73bb7b17af945/numpy-2.4.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32e3bef222ad6b052280311d1d60db8e259e4947052c3ae7dd6817451fc8a4c5", size = 15666601, upload-time = "2026-03-09T07:56:34.461Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/79/cc665495e4d57d0aa6fbcc0aa57aa82671dfc78fbf95fe733ed86d98f52a/numpy-2.4.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7dd01a46700b1967487141a66ac1a3cf0dd8ebf1f08db37d46389401512ca97", size = 16621358, upload-time = "2026-03-09T07:56:36.852Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/40/b4ecb7224af1065c3539f5ecfff879d090de09608ad1008f02c05c770cb3/numpy-2.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:76f0f283506c28b12bba319c0fab98217e9f9b54e6160e9c79e9f7348ba32e9c", size = 17016135, upload-time = "2026-03-09T07:56:39.337Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f7/b1/6a88e888052eed951afed7a142dcdf3b149a030ca59b4c71eef085858e43/numpy-2.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737f630a337364665aba3b5a77e56a68cc42d350edd010c345d65a3efa3addcc", size = 18345816, upload-time = "2026-03-09T07:56:42.31Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/8f/103a60c5f8c3d7fc678c19cd7b2476110da689ccb80bc18050efbaeae183/numpy-2.4.3-cp312-cp312-win32.whl", hash = "sha256:26952e18d82a1dbbc2f008d402021baa8d6fc8e84347a2072a25e08b46d698b9", size = 5960132, upload-time = "2026-03-09T07:56:44.851Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d7/7c/f5ee1bf6ed888494978046a809df2882aad35d414b622893322df7286879/numpy-2.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:65f3c2455188f09678355f5cae1f959a06b778bc66d535da07bf2ef20cd319d5", size = 12316144, upload-time = "2026-03-09T07:56:47.057Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/71/46/8d1cb3f7a00f2fb6394140e7e6623696e54c6318a9d9691bb4904672cf42/numpy-2.4.3-cp312-cp312-win_arm64.whl", hash = "sha256:2abad5c7fef172b3377502bde47892439bae394a71bc329f31df0fd829b41a9e", size = 10220364, upload-time = "2026-03-09T07:56:49.849Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b6/d0/1fe47a98ce0df229238b77611340aff92d52691bcbc10583303181abf7fc/numpy-2.4.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b346845443716c8e542d54112966383b448f4a3ba5c66409771b8c0889485dd3", size = 16665297, upload-time = "2026-03-09T07:56:52.296Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/27/d9/4e7c3f0e68dfa91f21c6fb6cf839bc829ec920688b1ce7ec722b1a6202fb/numpy-2.4.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2629289168f4897a3c4e23dc98d6f1731f0fc0fe52fb9db19f974041e4cc12b9", size = 14691853, upload-time = "2026-03-09T07:56:54.992Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/66/bd096b13a87549683812b53ab211e6d413497f84e794fb3c39191948da97/numpy-2.4.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bb2e3cf95854233799013779216c57e153c1ee67a0bf92138acca0e429aefaee", size = 5198435, upload-time = "2026-03-09T07:56:57.184Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/2f/687722910b5a5601de2135c891108f51dfc873d8e43c8ed9f4ebb440b4a2/numpy-2.4.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:7f3408ff897f8ab07a07fbe2823d7aee6ff644c097cc1f90382511fe982f647f", size = 6546347, upload-time = "2026-03-09T07:56:59.531Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bf/ec/7971c4e98d86c564750393fab8d7d83d0a9432a9d78bb8a163a6dc59967a/numpy-2.4.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:decb0eb8a53c3b009b0962378065589685d66b23467ef5dac16cbe818afde27f", size = 15664626, upload-time = "2026-03-09T07:57:01.385Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7e/eb/7daecbea84ec935b7fc732e18f532073064a3816f0932a40a17f3349185f/numpy-2.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc", size = 16608916, upload-time = "2026-03-09T07:57:04.008Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/58/2a2b4a817ffd7472dca4421d9f0776898b364154e30c95f42195041dc03b/numpy-2.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6bd06731541f89cdc01b261ba2c9e037f1543df7472517836b78dfb15bd6e476", size = 17015824, upload-time = "2026-03-09T07:57:06.347Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4a/ca/627a828d44e78a418c55f82dd4caea8ea4a8ef24e5144d9e71016e52fb40/numpy-2.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22654fe6be0e5206f553a9250762c653d3698e46686eee53b399ab90da59bd92", size = 18334581, upload-time = "2026-03-09T07:57:09.114Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/c0/76f93962fc79955fcba30a429b62304332345f22d4daec1cb33653425643/numpy-2.4.3-cp313-cp313-win32.whl", hash = "sha256:d71e379452a2f670ccb689ec801b1218cd3983e253105d6e83780967e899d687", size = 5958618, upload-time = "2026-03-09T07:57:11.432Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b1/3c/88af0040119209b9b5cb59485fa48b76f372c73068dbf9254784b975ac53/numpy-2.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:0a60e17a14d640f49146cb38e3f105f571318db7826d9b6fef7e4dce758faecd", size = 12312824, upload-time = "2026-03-09T07:57:13.586Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/58/ce/3d07743aced3d173f877c3ef6a454c2174ba42b584ab0b7e6d99374f51ed/numpy-2.4.3-cp313-cp313-win_arm64.whl", hash = "sha256:c9619741e9da2059cd9c3f206110b97583c7152c1dc9f8aafd4beb450ac1c89d", size = 10221218, upload-time = "2026-03-09T07:57:16.183Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/62/09/d96b02a91d09e9d97862f4fc8bfebf5400f567d8eb1fe4b0cc4795679c15/numpy-2.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7aa4e54f6469300ebca1d9eb80acd5253cdfa36f2c03d79a35883687da430875", size = 14819570, upload-time = "2026-03-09T07:57:18.564Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/ca/0b1aba3905fdfa3373d523b2b15b19029f4f3031c87f4066bd9d20ef6c6b/numpy-2.4.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d1b90d840b25874cf5cd20c219af10bac3667db3876d9a495609273ebe679070", size = 5326113, upload-time = "2026-03-09T07:57:21.052Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c0/63/406e0fd32fcaeb94180fd6a4c41e55736d676c54346b7efbce548b94a914/numpy-2.4.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a749547700de0a20a6718293396ec237bb38218049cfce788e08fcb716e8cf73", size = 6646370, upload-time = "2026-03-09T07:57:22.804Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b6/d0/10f7dc157d4b37af92720a196be6f54f889e90dcd30dce9dc657ed92c257/numpy-2.4.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94f3c4a151a2e529adf49c1d54f0f57ff8f9b233ee4d44af623a81553ab86368", size = 15723499, upload-time = "2026-03-09T07:57:24.693Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/f1/d1c2bf1161396629701bc284d958dc1efa3a5a542aab83cf11ee6eb4cba5/numpy-2.4.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22c31dc07025123aedf7f2db9e91783df13f1776dc52c6b22c620870dc0fab22", size = 16657164, upload-time = "2026-03-09T07:57:27.676Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/be/cca19230b740af199ac47331a21c71e7a3d0ba59661350483c1600d28c37/numpy-2.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:148d59127ac95979d6f07e4d460f934ebdd6eed641db9c0db6c73026f2b2101a", size = 17081544, upload-time = "2026-03-09T07:57:30.664Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/c5/9602b0cbb703a0936fb40f8a95407e8171935b15846de2f0776e08af04c7/numpy-2.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a97cbf7e905c435865c2d939af3d93f99d18eaaa3cabe4256f4304fb51604349", size = 18380290, upload-time = "2026-03-09T07:57:33.763Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ed/81/9f24708953cd30be9ee36ec4778f4b112b45165812f2ada4cc5ea1c1f254/numpy-2.4.3-cp313-cp313t-win32.whl", hash = "sha256:be3b8487d725a77acccc9924f65fd8bce9af7fac8c9820df1049424a2115af6c", size = 6082814, upload-time = "2026-03-09T07:57:36.491Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e2/9e/52f6eaa13e1a799f0ab79066c17f7016a4a8ae0c1aefa58c82b4dab690b4/numpy-2.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1ec84fd7c8e652b0f4aaaf2e6e9cc8eaa9b1b80a537e06b2e3a2fb176eedcb26", size = 12452673, upload-time = "2026-03-09T07:57:38.281Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/04/b8cece6ead0b30c9fbd99bb835ad7ea0112ac5f39f069788c5558e3b1ab2/numpy-2.4.3-cp313-cp313t-win_arm64.whl", hash = "sha256:120df8c0a81ebbf5b9020c91439fccd85f5e018a927a39f624845be194a2be02", size = 10290907, upload-time = "2026-03-09T07:57:40.747Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/70/ae/3936f79adebf8caf81bd7a599b90a561334a658be4dcc7b6329ebf4ee8de/numpy-2.4.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5884ce5c7acfae1e4e1b6fde43797d10aa506074d25b531b4f54bde33c0c31d4", size = 16664563, upload-time = "2026-03-09T07:57:43.817Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9b/62/760f2b55866b496bb1fa7da2a6db076bef908110e568b02fcfc1422e2a3a/numpy-2.4.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:297837823f5bc572c5f9379b0c9f3a3365f08492cbdc33bcc3af174372ebb168", size = 14702161, upload-time = "2026-03-09T07:57:46.169Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/32/af/a7a39464e2c0a21526fb4fb76e346fb172ebc92f6d1c7a07c2c139cc17b1/numpy-2.4.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:a111698b4a3f8dcbe54c64a7708f049355abd603e619013c346553c1fd4ca90b", size = 5208738, upload-time = "2026-03-09T07:57:48.506Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/29/8c/2a0cf86a59558fa078d83805589c2de490f29ed4fb336c14313a161d358a/numpy-2.4.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:4bd4741a6a676770e0e97fe9ab2e51de01183df3dcbcec591d26d331a40de950", size = 6543618, upload-time = "2026-03-09T07:57:50.591Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/b8/612ce010c0728b1c363fa4ea3aa4c22fe1c5da1de008486f8c2f5cb92fae/numpy-2.4.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54f29b877279d51e210e0c80709ee14ccbbad647810e8f3d375561c45ef613dd", size = 15680676, upload-time = "2026-03-09T07:57:52.34Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a9/7e/4f120ecc54ba26ddf3dc348eeb9eb063f421de65c05fc961941798feea18/numpy-2.4.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:679f2a834bae9020f81534671c56fd0cc76dd7e5182f57131478e23d0dc59e24", size = 16613492, upload-time = "2026-03-09T07:57:54.91Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/86/1b6020db73be330c4b45d5c6ee4295d59cfeef0e3ea323959d053e5a6909/numpy-2.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d84f0f881cb2225c2dfd7f78a10a5645d487a496c6668d6cc39f0f114164f3d0", size = 17031789, upload-time = "2026-03-09T07:57:57.641Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/07/3a/3b90463bf41ebc21d1b7e06079f03070334374208c0f9a1f05e4ae8455e7/numpy-2.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d213c7e6e8d211888cc359bab7199670a00f5b82c0978b9d1c75baf1eddbeac0", size = 18339941, upload-time = "2026-03-09T07:58:00.577Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/74/6d736c4cd962259fd8bae9be27363eb4883a2f9069763747347544c2a487/numpy-2.4.3-cp314-cp314-win32.whl", hash = "sha256:52077feedeff7c76ed7c9f1a0428558e50825347b7545bbb8523da2cd55c547a", size = 6007503, upload-time = "2026-03-09T07:58:03.331Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/48/39/c56ef87af669364356bb011922ef0734fc49dad51964568634c72a009488/numpy-2.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:0448e7f9caefb34b4b7dd2b77f21e8906e5d6f0365ad525f9f4f530b13df2afc", size = 12444915, upload-time = "2026-03-09T07:58:06.353Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9d/1f/ab8528e38d295fd349310807496fabb7cf9fe2e1f70b97bc20a483ea9d4a/numpy-2.4.3-cp314-cp314-win_arm64.whl", hash = "sha256:b44fd60341c4d9783039598efadd03617fa28d041fc37d22b62d08f2027fa0e7", size = 10494875, upload-time = "2026-03-09T07:58:08.734Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/ef/b7c35e4d5ef141b836658ab21a66d1a573e15b335b1d111d31f26c8ef80f/numpy-2.4.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0a195f4216be9305a73c0e91c9b026a35f2161237cf1c6de9b681637772ea657", size = 14822225, upload-time = "2026-03-09T07:58:11.034Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/8d/7730fa9278cf6648639946cc816e7cc89f0d891602584697923375f801ed/numpy-2.4.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:cd32fbacb9fd1bf041bf8e89e4576b6f00b895f06d00914820ae06a616bdfef7", size = 5328769, upload-time = "2026-03-09T07:58:13.67Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/01/d2a137317c958b074d338807c1b6a383406cdf8b8e53b075d804cc3d211d/numpy-2.4.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:2e03c05abaee1f672e9d67bc858f300b5ccba1c21397211e8d77d98350972093", size = 6649461, upload-time = "2026-03-09T07:58:15.912Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5c/34/812ce12bc0f00272a4b0ec0d713cd237cb390666eb6206323d1cc9cedbb2/numpy-2.4.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d1ce23cce91fcea443320a9d0ece9b9305d4368875bab09538f7a5b4131938a", size = 15725809, upload-time = "2026-03-09T07:58:17.787Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/25/c0/2aed473a4823e905e765fee3dc2cbf504bd3e68ccb1150fbdabd5c39f527/numpy-2.4.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c59020932feb24ed49ffd03704fbab89f22aa9c0d4b180ff45542fe8918f5611", size = 16655242, upload-time = "2026-03-09T07:58:20.476Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/c8/7e052b2fc87aa0e86de23f20e2c42bd261c624748aa8efd2c78f7bb8d8c6/numpy-2.4.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9684823a78a6cd6ad7511fc5e25b07947d1d5b5e2812c93fe99d7d4195130720", size = 17080660, upload-time = "2026-03-09T07:58:23.067Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/3d/0876746044db2adcb11549f214d104f2e1be00f07a67edbb4e2812094847/numpy-2.4.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0200b25c687033316fb39f0ff4e3e690e8957a2c3c8d22499891ec58c37a3eb5", size = 18380384, upload-time = "2026-03-09T07:58:25.839Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/07/12/8160bea39da3335737b10308df4f484235fd297f556745f13092aa039d3b/numpy-2.4.3-cp314-cp314t-win32.whl", hash = "sha256:5e10da9e93247e554bb1d22f8edc51847ddd7dde52d85ce31024c1b4312bfba0", size = 6154547, upload-time = "2026-03-09T07:58:28.289Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/42/f3/76534f61f80d74cc9cdf2e570d3d4eeb92c2280a27c39b0aaf471eda7b48/numpy-2.4.3-cp314-cp314t-win_amd64.whl", hash = "sha256:45f003dbdffb997a03da2d1d0cb41fbd24a87507fb41605c0420a3db5bd4667b", size = 12633645, upload-time = "2026-03-09T07:58:30.384Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/b6/7c0d4334c15983cec7f92a69e8ce9b1e6f31857e5ee3a413ac424e6bd63d/numpy-2.4.3-cp314-cp314t-win_arm64.whl", hash = "sha256:4d382735cecd7bcf090172489a525cd7d4087bc331f7df9f60ddc9a296cf208e", size = 10565454, upload-time = "2026-03-09T07:58:33.031Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oauthlib"
|
name = "oauthlib"
|
||||||
version = "3.3.1"
|
version = "3.3.1"
|
||||||
@@ -1151,6 +1236,58 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
|
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pandas"
|
||||||
|
version = "3.0.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "numpy" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/2e/0c/b28ed414f080ee0ad153f848586d61d1878f91689950f037f976ce15f6c8/pandas-3.0.1.tar.gz", hash = "sha256:4186a699674af418f655dbd420ed87f50d56b4cd6603784279d9eef6627823c8", size = 4641901, upload-time = "2026-02-17T22:20:16.434Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/51/b467209c08dae2c624873d7491ea47d2b47336e5403309d433ea79c38571/pandas-3.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:476f84f8c20c9f5bc47252b66b4bb25e1a9fc2fa98cead96744d8116cb85771d", size = 10344357, upload-time = "2026-02-17T22:18:38.262Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7c/f1/e2567ffc8951ab371db2e40b2fe068e36b81d8cf3260f06ae508700e5504/pandas-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0ab749dfba921edf641d4036c4c21c0b3ea70fea478165cb98a998fb2a261955", size = 9884543, upload-time = "2026-02-17T22:18:41.476Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d7/39/327802e0b6d693182403c144edacbc27eb82907b57062f23ef5a4c4a5ea7/pandas-3.0.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8e36891080b87823aff3640c78649b91b8ff6eea3c0d70aeabd72ea43ab069b", size = 10396030, upload-time = "2026-02-17T22:18:43.822Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3d/fe/89d77e424365280b79d99b3e1e7d606f5165af2f2ecfaf0c6d24c799d607/pandas-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:532527a701281b9dd371e2f582ed9094f4c12dd9ffb82c0c54ee28d8ac9520c4", size = 10876435, upload-time = "2026-02-17T22:18:45.954Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/a6/2a75320849dd154a793f69c951db759aedb8d1dd3939eeacda9bdcfa1629/pandas-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:356e5c055ed9b0da1580d465657bc7d00635af4fd47f30afb23025352ba764d1", size = 11405133, upload-time = "2026-02-17T22:18:48.533Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/58/53/1d68fafb2e02d7881df66aa53be4cd748d25cbe311f3b3c85c93ea5d30ca/pandas-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d810036895f9ad6345b8f2a338dd6998a74e8483847403582cab67745bff821", size = 11932065, upload-time = "2026-02-17T22:18:50.837Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/75/08/67cc404b3a966b6df27b38370ddd96b3b023030b572283d035181854aac5/pandas-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:536232a5fe26dd989bd633e7a0c450705fdc86a207fec7254a55e9a22950fe43", size = 9741627, upload-time = "2026-02-17T22:18:53.905Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/86/4f/caf9952948fb00d23795f09b893d11f1cacb384e666854d87249530f7cbe/pandas-3.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:0f463ebfd8de7f326d38037c7363c6dacb857c5881ab8961fb387804d6daf2f7", size = 9052483, upload-time = "2026-02-17T22:18:57.31Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/48/aad6ec4f8d007534c091e9a7172b3ec1b1ee6d99a9cbb936b5eab6c6cf58/pandas-3.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5272627187b5d9c20e55d27caf5f2cd23e286aba25cadf73c8590e432e2b7262", size = 10317509, upload-time = "2026-02-17T22:18:59.498Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/14/5990826f779f79148ae9d3a2c39593dc04d61d5d90541e71b5749f35af95/pandas-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:661e0f665932af88c7877f31da0dc743fe9c8f2524bdffe23d24fdcb67ef9d56", size = 9860561, upload-time = "2026-02-17T22:19:02.265Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fa/80/f01ff54664b6d70fed71475543d108a9b7c888e923ad210795bef04ffb7d/pandas-3.0.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75e6e292ff898679e47a2199172593d9f6107fd2dd3617c22c2946e97d5df46e", size = 10365506, upload-time = "2026-02-17T22:19:05.017Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791", size = 10873196, upload-time = "2026-02-17T22:19:07.204Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/48/a9/9301c83d0b47c23ac5deab91c6b39fd98d5b5db4d93b25df8d381451828f/pandas-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eca8b4510f6763f3d37359c2105df03a7a221a508f30e396a51d0713d462e68a", size = 11370859, upload-time = "2026-02-17T22:19:09.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/59/fe/0c1fc5bd2d29c7db2ab372330063ad555fb83e08422829c785f5ec2176ca/pandas-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:06aff2ad6f0b94a17822cf8b83bbb563b090ed82ff4fe7712db2ce57cd50d9b8", size = 11924584, upload-time = "2026-02-17T22:19:11.562Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/7d/216a1588b65a7aa5f4535570418a599d943c85afb1d95b0876fc00aa1468/pandas-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:9fea306c783e28884c29057a1d9baa11a349bbf99538ec1da44c8476563d1b25", size = 9742769, upload-time = "2026-02-17T22:19:13.926Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/cb/810a22a6af9a4e97c8ab1c946b47f3489c5bca5adc483ce0ffc84c9cc768/pandas-3.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:a8d37a43c52917427e897cb2e429f67a449327394396a81034a4449b99afda59", size = 9043855, upload-time = "2026-02-17T22:19:16.09Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/fa/423c89086cca1f039cf1253c3ff5b90f157b5b3757314aa635f6bf3e30aa/pandas-3.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d54855f04f8246ed7b6fc96b05d4871591143c46c0b6f4af874764ed0d2d6f06", size = 10752673, upload-time = "2026-02-17T22:19:18.304Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/23/b5a08ec1f40020397f0faba72f1e2c11f7596a6169c7b3e800abff0e433f/pandas-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e1b677accee34a09e0dc2ce5624e4a58a1870ffe56fc021e9caf7f23cd7668f", size = 10404967, upload-time = "2026-02-17T22:19:20.726Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5c/81/94841f1bb4afdc2b52a99daa895ac2c61600bb72e26525ecc9543d453ebc/pandas-3.0.1-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9cabbdcd03f1b6cd254d6dda8ae09b0252524be1592594c00b7895916cb1324", size = 10320575, upload-time = "2026-02-17T22:19:24.919Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/8b/2ae37d66a5342a83adadfd0cb0b4bf9c3c7925424dd5f40d15d6cfaa35ee/pandas-3.0.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ae2ab1f166668b41e770650101e7090824fd34d17915dd9cd479f5c5e0065e9", size = 10710921, upload-time = "2026-02-17T22:19:27.181Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/61/772b2e2757855e232b7ccf7cb8079a5711becb3a97f291c953def15a833f/pandas-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6bf0603c2e30e2cafac32807b06435f28741135cb8697eae8b28c7d492fc7d76", size = 11334191, upload-time = "2026-02-17T22:19:29.411Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1b/08/b16c6df3ef555d8495d1d265a7963b65be166785d28f06a350913a4fac78/pandas-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6c426422973973cae1f4a23e51d4ae85974f44871b24844e4f7de752dd877098", size = 11782256, upload-time = "2026-02-17T22:19:32.34Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/55/80/178af0594890dee17e239fca96d3d8670ba0f5ff59b7d0439850924a9c09/pandas-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b03f91ae8c10a85c1613102c7bef5229b5379f343030a3ccefeca8a33414cf35", size = 10485047, upload-time = "2026-02-17T22:19:34.605Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/8b/4bb774a998b97e6c2fd62a9e6cfdaae133b636fd1c468f92afb4ae9a447a/pandas-3.0.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:99d0f92ed92d3083d140bf6b97774f9f13863924cf3f52a70711f4e7588f9d0a", size = 10322465, upload-time = "2026-02-17T22:19:36.803Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/72/3a/5b39b51c64159f470f1ca3b1c2a87da290657ca022f7cd11442606f607d1/pandas-3.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3b66857e983208654294bb6477b8a63dee26b37bdd0eb34d010556e91261784f", size = 9910632, upload-time = "2026-02-17T22:19:39.001Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/f7/b449ffb3f68c11da12fc06fbf6d2fa3a41c41e17d0284d23a79e1c13a7e4/pandas-3.0.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56cf59638bf24dc9bdf2154c81e248b3289f9a09a6d04e63608c159022352749", size = 10440535, upload-time = "2026-02-17T22:19:41.157Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/55/77/6ea82043db22cb0f2bbfe7198da3544000ddaadb12d26be36e19b03a2dc5/pandas-3.0.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1a9f55e0f46951874b863d1f3906dcb57df2d9be5c5847ba4dfb55b2c815249", size = 10893940, upload-time = "2026-02-17T22:19:43.493Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/03/30/f1b502a72468c89412c1b882a08f6eed8a4ee9dc033f35f65d0663df6081/pandas-3.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1849f0bba9c8a2fb0f691d492b834cc8dadf617e29015c66e989448d58d011ee", size = 11442711, upload-time = "2026-02-17T22:19:46.074Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/f0/ebb6ddd8fc049e98cabac5c2924d14d1dda26a20adb70d41ea2e428d3ec4/pandas-3.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3d288439e11b5325b02ae6e9cc83e6805a62c40c5a6220bea9beb899c073b1c", size = 11963918, upload-time = "2026-02-17T22:19:48.838Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/f8/8ce132104074f977f907442790eaae24e27bce3b3b454e82faa3237ff098/pandas-3.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:93325b0fe372d192965f4cca88d97667f49557398bbf94abdda3bf1b591dbe66", size = 9862099, upload-time = "2026-02-17T22:19:51.081Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/b7/6af9aac41ef2456b768ef0ae60acf8abcebb450a52043d030a65b4b7c9bd/pandas-3.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:97ca08674e3287c7148f4858b01136f8bdfe7202ad25ad04fec602dd1d29d132", size = 9185333, upload-time = "2026-02-17T22:19:53.266Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/fc/848bb6710bc6061cb0c5badd65b92ff75c81302e0e31e496d00029fe4953/pandas-3.0.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:58eeb1b2e0fb322befcf2bbc9ba0af41e616abadb3d3414a6bc7167f6cbfce32", size = 10772664, upload-time = "2026-02-17T22:19:55.806Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/69/5c/866a9bbd0f79263b4b0db6ec1a341be13a1473323f05c122388e0f15b21d/pandas-3.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cd9af1276b5ca9e298bd79a26bda32fa9cc87ed095b2a9a60978d2ca058eaf87", size = 10421286, upload-time = "2026-02-17T22:19:58.091Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/51/a4/2058fb84fb1cfbfb2d4a6d485e1940bb4ad5716e539d779852494479c580/pandas-3.0.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94f87a04984d6b63788327cd9f79dda62b7f9043909d2440ceccf709249ca988", size = 10342050, upload-time = "2026-02-17T22:20:01.376Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/1b/674e89996cc4be74db3c4eb09240c4bb549865c9c3f5d9b086ff8fcfbf00/pandas-3.0.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85fe4c4df62e1e20f9db6ebfb88c844b092c22cd5324bdcf94bfa2fc1b391221", size = 10740055, upload-time = "2026-02-17T22:20:04.328Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d0/f8/e954b750764298c22fa4614376531fe63c521ef517e7059a51f062b87dca/pandas-3.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:331ca75a2f8672c365ae25c0b29e46f5ac0c6551fdace8eec4cd65e4fac271ff", size = 11357632, upload-time = "2026-02-17T22:20:06.647Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6d/02/c6e04b694ffd68568297abd03588b6d30295265176a5c01b7459d3bc35a3/pandas-3.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15860b1fdb1973fffade772fdb931ccf9b2f400a3f5665aef94a00445d7d8dd5", size = 11810974, upload-time = "2026-02-17T22:20:08.946Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/41/d7dfb63d2407f12055215070c42fc6ac41b66e90a2946cdc5e759058398b/pandas-3.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:44f1364411d5670efa692b146c748f4ed013df91ee91e9bec5677fb1fd58b937", size = 10884622, upload-time = "2026-02-17T22:20:11.711Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/68/b0/34937815889fa982613775e4b97fddd13250f11012d769949c5465af2150/pandas-3.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:108dd1790337a494aa80e38def654ca3f0968cf4f362c85f44c15e471667102d", size = 9452085, upload-time = "2026-02-17T22:20:14.331Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parsedatetime"
|
name = "parsedatetime"
|
||||||
version = "2.6"
|
version = "2.6"
|
||||||
@@ -1907,6 +2044,7 @@ source = { virtual = "." }
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "databricks-cli" },
|
{ name = "databricks-cli" },
|
||||||
{ name = "databricks-sdk" },
|
{ name = "databricks-sdk" },
|
||||||
|
{ name = "duckdb" },
|
||||||
{ name = "fastapi" },
|
{ name = "fastapi" },
|
||||||
{ name = "fastexcel" },
|
{ name = "fastexcel" },
|
||||||
{ name = "fsspec" },
|
{ name = "fsspec" },
|
||||||
@@ -1921,11 +2059,13 @@ dependencies = [
|
|||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
|
{ name = "altair" },
|
||||||
{ name = "coverage" },
|
{ name = "coverage" },
|
||||||
{ name = "dbt-core" },
|
{ name = "dbt-core" },
|
||||||
{ name = "dbt-duckdb" },
|
{ name = "dbt-duckdb" },
|
||||||
{ name = "marimo" },
|
{ name = "marimo" },
|
||||||
{ name = "openpyxl" },
|
{ name = "openpyxl" },
|
||||||
|
{ name = "pandas" },
|
||||||
{ name = "pdfplumber" },
|
{ name = "pdfplumber" },
|
||||||
{ name = "polars" },
|
{ name = "polars" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
@@ -1937,6 +2077,7 @@ dev = [
|
|||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "databricks-cli", specifier = ">=0.18.0" },
|
{ name = "databricks-cli", specifier = ">=0.18.0" },
|
||||||
{ name = "databricks-sdk", specifier = ">=0.85.0" },
|
{ name = "databricks-sdk", specifier = ">=0.85.0" },
|
||||||
|
{ name = "duckdb", specifier = ">=1.0.0" },
|
||||||
{ name = "fastapi", specifier = ">=0.135.1" },
|
{ name = "fastapi", specifier = ">=0.135.1" },
|
||||||
{ name = "fastexcel", specifier = ">=0.19.0" },
|
{ name = "fastexcel", specifier = ">=0.19.0" },
|
||||||
{ name = "fsspec", specifier = ">=2024.1.0" },
|
{ name = "fsspec", specifier = ">=2024.1.0" },
|
||||||
@@ -1951,11 +2092,13 @@ requires-dist = [
|
|||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
|
{ name = "altair", specifier = ">=6.0.0" },
|
||||||
{ name = "coverage", specifier = ">=7.13.4" },
|
{ name = "coverage", specifier = ">=7.13.4" },
|
||||||
{ name = "dbt-core", specifier = "==1.10.15" },
|
{ name = "dbt-core", specifier = "==1.10.15" },
|
||||||
{ name = "dbt-duckdb", specifier = ">=1.10,<1.11" },
|
{ name = "dbt-duckdb", specifier = ">=1.10,<1.11" },
|
||||||
{ name = "marimo", specifier = ">=0.20.0" },
|
{ name = "marimo", specifier = ">=0.20.0" },
|
||||||
{ name = "openpyxl", specifier = ">=3.1.5" },
|
{ name = "openpyxl", specifier = ">=3.1.5" },
|
||||||
|
{ name = "pandas", specifier = ">=3.0.1" },
|
||||||
{ name = "pdfplumber", specifier = ">=0.11.9" },
|
{ name = "pdfplumber", specifier = ">=0.11.9" },
|
||||||
{ name = "polars", specifier = ">=1.38.1" },
|
{ name = "polars", specifier = ">=1.38.1" },
|
||||||
{ name = "pytest", specifier = ">=9.0.2" },
|
{ name = "pytest", specifier = ">=9.0.2" },
|
||||||
|
|||||||
Reference in New Issue
Block a user