feat: monorepo migration phase 1 & 2

This commit is contained in:
2026-10-07 10:18:46 +01:00
parent 096b6b488f
commit e92ae5064c
183 changed files with 31132 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# CRR brand
Canonical CRR visual assets and framework-independent CSS, consumed by both apps.
- `assets/logo.png`: the original Tournament logo, copied without conversion.
- `assets/favicon.png`: the original Tournament favicon.
- `styles/tokens.css`: shared palette around `#ed1c24`, font stack, radii,
shadows, spacing and focus-ring values.
- `styles/base.css`: box sizing, body defaults, links, controls, focus and tables.
- `styles/components.css`: the existing primary/quiet button, panel and error
alert patterns used by both Vue and Jinja. Existing class names are supported
directly so templates retain their own structure.
Load tokens, base and components **before** the application's own stylesheet.
Application CSS owns sizes, typography hierarchy, responsive layout, control
spacing, specialist badges and print-card dimensions. Local variable names are
aliases of `--crr-*` tokens, keeping existing styles/components compatible.
Tournament resolves `@crr-brand` through Vite and uses `assets/` as its public
asset directory. Shifts mounts this directory at `/brand` using FastAPI
`StaticFiles`; Jinja uses `url_for('brand', ...)` so `ROOT_PATH` is respected.
Its PDF exporter reads this same logo. Both Docker builds copy the package from
the repository-root context, preserving its relative path to each application.
Brand-only changes trigger both application CI jobs. This package contains no
domain code or UI framework components and has no independent public version.
After changing branding, run both app checks/builds and `make branding-visual-check`
to compare desktop/mobile geometry and Tournament print cards against the legacy
baseline. `make migration-visual-check` compares rendered pages to the approved
Phase 2 screenshots. Baseline staging and Playwright prerequisites are documented
in `migration/README.md`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

+35
View File
@@ -0,0 +1,35 @@
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--crr-background);
color: var(--crr-text);
font-family: var(--crr-font-family);
}
a { color: inherit; }
button, input, select { font: inherit; }
button { cursor: pointer; }
input, select {
width: 100%;
border: 1px solid var(--crr-control-border);
border-radius: var(--crr-radius-control);
background: var(--crr-surface);
color: var(--crr-text);
}
input:focus, select:focus {
outline: none;
border-color: var(--crr-primary);
box-shadow: var(--crr-focus-shadow);
}
button:focus-visible, a:focus-visible, summary:focus-visible {
outline: var(--crr-focus-outline);
outline-offset: 2px;
}
table { width: 100%; border-collapse: collapse; }
th { text-transform: uppercase; }
+37
View File
@@ -0,0 +1,37 @@
.button {
border: 1px solid var(--crr-primary);
border-radius: var(--crr-radius-control);
background: var(--crr-primary);
color: #fff;
text-decoration: none;
}
.primary { background: var(--crr-primary); color: #fff; }
.button:where(:not(.danger)):hover:not(:disabled), .primary:hover:not(:disabled) {
border-color: var(--crr-primary-hover);
background: var(--crr-primary-hover);
}
.button--quiet, .secondary {
border-color: var(--crr-control-border);
background: transparent;
color: var(--crr-quiet-text);
}
.button--quiet:hover:not(:disabled), .secondary:hover:not(:disabled) {
border-color: var(--crr-quiet-hover-border);
background: var(--crr-quiet-hover);
color: var(--crr-text);
}
.panel {
border: 1px solid var(--crr-border);
border-radius: var(--crr-radius-panel);
background: var(--crr-surface);
}
.notice--error, .flash.error {
border-color: var(--crr-danger-border);
background: var(--crr-danger-soft);
color: var(--crr-danger-dark);
}
+34
View File
@@ -0,0 +1,34 @@
:root {
--crr-primary: #ed1c24;
--crr-primary-hover: #c81018;
--crr-primary-dark: #b80f17;
--crr-brand-soft: #fff0f1;
--crr-background: #f4f4f1;
--crr-surface: #fff;
--crr-text: #18191b;
--crr-muted: #62676f;
--crr-border: #dedfe2;
--crr-control-border: #c9cbd0;
--crr-quiet-text: #363a40;
--crr-quiet-hover: #f4f4f5;
--crr-quiet-hover-border: #93989f;
--crr-danger: #b42318;
--crr-danger-dark: #8f1d14;
--crr-danger-soft: #fff4f4;
--crr-danger-border: #f1b8b8;
--crr-warning: #8a6100;
--crr-radius-control: .5rem;
--crr-radius-panel: .9rem;
--crr-radius-pill: 999px;
--crr-shadow-soft: 0 12px 36px rgb(25 25 25 / 8%);
--crr-shadow-panel: 0 5px 18px rgb(25 25 25 / 3%);
--crr-space-1: .25rem;
--crr-space-2: .5rem;
--crr-space-3: .75rem;
--crr-space-4: 1rem;
--crr-space-6: 1.5rem;
--crr-space-8: 2rem;
--crr-font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--crr-focus-shadow: 0 0 0 3px rgb(237 28 36 / 14%);
--crr-focus-outline: 3px solid rgb(237 28 36 / 24%);
}