Containerise: Dockerfile, Compose stack and wildcard TLS
One server now, the same image and env vars for many later: point DJANGO_DATABASE_URL / DJANGO_REDIS_URL at central services, set a bucket, drop the db and redis services, run several web containers behind a load balancer. No code changes. The wildcard certificate is what shapes this. Subdomain tenancy needs *.rosterchief.app, and Let's Encrypt will not issue a wildcard over HTTP-01 -- only DNS-01 -- so Caddy is built with a DNS provider plugin and needs an API token. That single constraint is why the proxy is Caddy rather than the usual nginx+certbot. The image apt-installs libpango and friends, which is what WeasyPrint binds to. The PDF invoices that cannot render on a Mac without Homebrew work in the container by construction. Migrations are NOT run by the entrypoint: with more than one web container they would race, and a starting gunicorn worker is a bad place to discover a failed migration. Deploy runs them once, explicitly. Two things the local build check caught, either of which would have failed the image build at collectstatic (manifest storage treats a missing referenced file as fatal): - chart.js ended with a sourceMappingURL pointing at a .map we never vendored. Stripped, with an npm script so re-vendoring cannot bring it back. - The Tailwind INPUT file lived at static/src/app.css, inside the served static tree, so collectstatic collected it and then choked on its @import "tailwindcss". It belongs outside: it is a build input, not an asset. Now assets/app.css. Verified locally under gunicorn + WhiteNoise + manifest storage: pages serve and the CSS comes back hashed. The image itself is unverified -- there is no container runtime on this machine. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,9 @@
|
||||
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--default-font-family: var(--font-sans);
|
||||
--default-mono-font-family: var(--font-mono);
|
||||
--font-ubuntu: "Ubuntu", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-roboto: "Roboto", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-tourney: "Tourney", ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
}
|
||||
@layer base {
|
||||
@@ -189,6 +191,67 @@
|
||||
}
|
||||
}
|
||||
@layer utilities {
|
||||
.diff {
|
||||
@layer daisyui.l1.l2 {
|
||||
position: relative;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
webkit-user-select: none;
|
||||
user-select: none;
|
||||
align-items: normal;
|
||||
grid-template-rows: 1fr 1.8rem 1fr;
|
||||
direction: ltr;
|
||||
container-type: inline-size;
|
||||
grid-template-columns: auto 1fr;
|
||||
&:focus-visible, &:has(.diff-item-1:focus-visible) {
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 2px;
|
||||
outline-offset: 1px;
|
||||
outline-color: var(--color-base-content);
|
||||
}
|
||||
&:focus-visible {
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 2px;
|
||||
outline-offset: 1px;
|
||||
outline-color: var(--color-base-content);
|
||||
.diff-resizer {
|
||||
min-width: 95cqi;
|
||||
max-width: 95cqi;
|
||||
}
|
||||
}
|
||||
&:has(.diff-item-1:focus-visible) {
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 2px;
|
||||
outline-offset: 1px;
|
||||
.diff-resizer {
|
||||
min-width: 5cqi;
|
||||
max-width: 5cqi;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.diff-item-2 {
|
||||
&::after {
|
||||
height: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@supports (-webkit-overflow-scrolling: touch) and (overflow: -webkit-paged-x) {
|
||||
&:focus {
|
||||
.diff-resizer {
|
||||
min-width: 5cqi;
|
||||
max-width: 5cqi;
|
||||
}
|
||||
}
|
||||
&:has(.diff-item-1:focus) {
|
||||
.diff-resizer {
|
||||
min-width: 95cqi;
|
||||
max-width: 95cqi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tooltip {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
@@ -726,6 +789,57 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.diff-item-2 {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
grid-column-start: 1;
|
||||
grid-row: span 3 / span 3;
|
||||
grid-row-start: 1;
|
||||
&:after {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: calc(1 / 2 * 100%);
|
||||
right: 1px;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
border-radius: calc(infinity * 1px);
|
||||
background-color: var(--color-base-100);
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
background-color: color-mix(in oklab, var(--color-base-100) 98%, transparent);
|
||||
}
|
||||
width: 1.2rem;
|
||||
height: 1.8rem;
|
||||
border: 2px solid var(--color-base-100);
|
||||
content: "";
|
||||
box-shadow: 0 0 0 2px #0000002a;
|
||||
outline: 2px solid var(--color-base-content);
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
outline: 2px solid color-mix(in oklab, var(--color-base-content) 10%, #0000);
|
||||
}
|
||||
outline-offset: -3px;
|
||||
translate: 50% -50%;
|
||||
transition: height 0.3s linear(0, 0.931 13.8%, 1.196 21.4%, 1.343 29.8%, 1.378 36%, 1.365 43.2%, 1.059 78%, 1);
|
||||
}
|
||||
> * {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100cqi;
|
||||
max-width: none;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
@supports (-webkit-overflow-scrolling: touch) and (overflow: -webkit-paged-x) {
|
||||
&:after {
|
||||
--tw-content: none;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dropdown {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
@@ -974,6 +1088,23 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.loading {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
pointer-events: none;
|
||||
display: inline-block;
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: currentcolor;
|
||||
vertical-align: middle;
|
||||
width: calc(var(--size-selector, 0.25rem) * 6);
|
||||
mask-size: 100%;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='8s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='6s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='6s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapse {
|
||||
&:not(td, tr, colgroup) {
|
||||
visibility: revert-layer;
|
||||
@@ -1141,6 +1272,44 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.\!filter {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
[type="radio"] {
|
||||
width: auto !important;
|
||||
}
|
||||
input {
|
||||
overflow: hidden !important;
|
||||
opacity: 100% !important;
|
||||
scale: 1 !important;
|
||||
transition: visibility 0.1s allow-discrete, margin 0.1s, opacity 0.3s, padding 0.3s, border-width 0.1s !important;
|
||||
&.filter-reset {
|
||||
aspect-ratio: 1 / 1 !important;
|
||||
&::after {
|
||||
--tw-content: "×" !important;
|
||||
content: var(--tw-content) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
> input:not(:last-child), > :not(:last-child) input {
|
||||
margin-inline-end: 0.25rem !important;
|
||||
}
|
||||
}
|
||||
@layer daisyui.l1 {
|
||||
&:not(:has(:checked:not(.filter-reset))) :is(.filter-reset, [type="reset"]):not(:focus-visible) {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
&:not(:has(:checked:not(.filter-reset))) :is(.filter-reset, [type="reset"]):not(:focus-visible), &:not(:has(:focus-visible)):has(:checked:not(.filter-reset, [type="checkbox"])) :is(input, button):not(:checked, .filter-reset, [type="reset"]) {
|
||||
margin-inline: 0 !important;
|
||||
width: 0 !important;
|
||||
padding-inline: 0 !important;
|
||||
opacity: 0% !important;
|
||||
scale: 0 !important;
|
||||
border-width: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.filter {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: flex;
|
||||
@@ -1179,6 +1348,36 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.validator-hint {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
visibility: hidden;
|
||||
margin-top: calc(0.25rem * 2);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
.validator {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
&:user-valid, &:has(:user-valid) {
|
||||
&, &:focus, &:checked, &[aria-checked="true"], &:focus-within {
|
||||
--input-color: var(--color-success);
|
||||
}
|
||||
}
|
||||
&:user-invalid, &:has(:user-invalid), &[aria-invalid]:not([aria-invalid="false"]), &:has([aria-invalid]:not([aria-invalid="false"])) {
|
||||
&, &:focus, &:checked, &[aria-checked="true"], &:focus-within {
|
||||
--input-color: var(--color-error);
|
||||
}
|
||||
& ~ .validator-hint {
|
||||
visibility: visible;
|
||||
color: var(--color-error);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:user-invalid, &:has(:user-invalid), &[aria-invalid]:not([aria-invalid="false"]), &:has([aria-invalid]:not([aria-invalid="false"])) {
|
||||
& ~ .validator-hint {
|
||||
display: revert-layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapse-open {
|
||||
@layer daisyui.l1.l2 {
|
||||
grid-template-rows: max-content 1fr;
|
||||
@@ -1550,6 +1749,105 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.range {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
appearance: none;
|
||||
webkit-appearance: none;
|
||||
--range-thumb: var(--color-base-100);
|
||||
--range-thumb-size: calc(var(--size-selector, 0.25rem) * 6);
|
||||
--range-progress: currentColor;
|
||||
--range-fill: 1;
|
||||
--range-p: 0.25rem;
|
||||
--range-bg: currentColor;
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
--range-bg: color-mix(in oklab, currentColor 10%, #0000);
|
||||
}
|
||||
--range-fill-x: calc(
|
||||
(var(--range-dir, 1) * -100cqw) - (var(--range-dir, 1) * var(--range-thumb-size) / 2)
|
||||
);
|
||||
--range-fill-y: 0;
|
||||
--range-fill-spread: calc(100cqw * var(--range-fill));
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
vertical-align: middle;
|
||||
width: clamp(3rem, 20rem, 100%);
|
||||
--radius-selector-max: calc(
|
||||
var(--radius-selector) + var(--radius-selector) + var(--radius-selector)
|
||||
);
|
||||
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
||||
border: none;
|
||||
height: var(--range-thumb-size);
|
||||
[dir="rtl"] & {
|
||||
--range-dir: -1;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
&:focus-visible {
|
||||
outline: 2px solid;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
background-color: var(--range-bg);
|
||||
border-radius: var(--radius-selector);
|
||||
height: calc(var(--range-thumb-size) * 0.5);
|
||||
}
|
||||
@media (forced-colors: active) {
|
||||
&::-webkit-slider-runnable-track {
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
@media (forced-colors: active) {
|
||||
&::-moz-range-track {
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
||||
background-color: var(--range-thumb);
|
||||
height: var(--range-thumb-size);
|
||||
width: var(--range-thumb-size);
|
||||
border: var(--range-p) solid;
|
||||
appearance: none;
|
||||
webkit-appearance: none;
|
||||
inset-block-start: 50%;
|
||||
color: var(--range-progress);
|
||||
transform: translateY(-50%);
|
||||
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
||||
}
|
||||
}
|
||||
&::-moz-range-track {
|
||||
width: 100%;
|
||||
background-color: var(--range-bg);
|
||||
border-radius: var(--radius-selector);
|
||||
height: calc(var(--range-thumb-size) * 0.5);
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
||||
background-color: currentColor;
|
||||
height: var(--range-thumb-size);
|
||||
width: var(--range-thumb-size);
|
||||
border: var(--range-p) solid;
|
||||
color: var(--range-progress);
|
||||
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
||||
@supports (color: color-mix(in lab, red, red)) {
|
||||
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
||||
}
|
||||
}
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 30%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.indicator {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
@@ -1791,6 +2089,27 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.diff-resizer {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
z-index: 2;
|
||||
grid-column-start: 1;
|
||||
grid-row-start: 2;
|
||||
height: calc(0.25rem * 3);
|
||||
width: 50cqi;
|
||||
max-width: calc(100cqi - 1rem);
|
||||
min-width: 1rem;
|
||||
resize: horizontal;
|
||||
overflow: hidden;
|
||||
opacity: 0%;
|
||||
transform: scaleY(5) translate(0.32rem, 50%);
|
||||
cursor: ew-resize;
|
||||
transform-origin: 100% 100%;
|
||||
clip-path: inset(calc(100% - 0.75rem) 0 0 calc(100% - 0.75rem));
|
||||
transition: min-width 0.3s ease-out, max-width 0.3s ease-out;
|
||||
}
|
||||
}
|
||||
.select {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
position: relative;
|
||||
@@ -1977,6 +2296,42 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.swap {
|
||||
@layer daisyui.l1.l2 {
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
cursor: pointer;
|
||||
place-content: center;
|
||||
vertical-align: middle;
|
||||
webkit-user-select: none;
|
||||
user-select: none;
|
||||
input {
|
||||
appearance: none;
|
||||
border: none;
|
||||
}
|
||||
> * {
|
||||
grid-column-start: 1;
|
||||
grid-row-start: 1;
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
transition-property: transform, rotate, opacity;
|
||||
transition-duration: 0.2s;
|
||||
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
.swap-on, .swap-indeterminate, input:indeterminate ~ .swap-on {
|
||||
opacity: 0%;
|
||||
}
|
||||
input:is(:checked, :indeterminate) {
|
||||
& ~ .swap-off {
|
||||
opacity: 0%;
|
||||
}
|
||||
}
|
||||
input:checked ~ .swap-on, input:indeterminate ~ .swap-indeterminate {
|
||||
opacity: 100%;
|
||||
backface-visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapse-title {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
grid-column-start: 1;
|
||||
@@ -2333,12 +2688,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
.static {
|
||||
position: static;
|
||||
}
|
||||
.sticky {
|
||||
position: sticky;
|
||||
}
|
||||
.dropdown-right {
|
||||
@layer daisyui.l1.l2 {
|
||||
--anchor-h: right;
|
||||
@@ -2873,6 +3237,62 @@
|
||||
.my-6 {
|
||||
margin-block: calc(var(--spacing) * 6);
|
||||
}
|
||||
.breadcrumbs {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
padding-block: calc(0.25rem * 2);
|
||||
> menu, > ul, > ol {
|
||||
display: flex;
|
||||
min-height: min-content;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
> li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> * {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
gap: calc(0.25rem * 2);
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
--tw-outline-style: none;
|
||||
outline-style: none;
|
||||
@media (forced-colors: active) {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
&:focus-visible {
|
||||
outline: 2px solid currentColor;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
& + *:before {
|
||||
content: "";
|
||||
margin-inline-start: calc(0.25rem * 2);
|
||||
margin-inline-end: calc(0.25rem * 3);
|
||||
display: block;
|
||||
height: calc(0.25rem * 1.5);
|
||||
width: calc(0.25rem * 1.5);
|
||||
opacity: 40%;
|
||||
rotate: 45deg;
|
||||
border-top: 1px solid;
|
||||
border-right: 1px solid;
|
||||
background-color: #0000;
|
||||
}
|
||||
[dir="rtl"] & + *:before {
|
||||
rotate: -135deg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.label {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: inline-flex;
|
||||
@@ -3101,6 +3521,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.fieldset {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: grid;
|
||||
gap: calc(0.25rem * 1.5);
|
||||
padding-block: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-rows: max-content;
|
||||
}
|
||||
}
|
||||
.card-actions {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
display: flex;
|
||||
@@ -3183,9 +3613,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.\!hidden {
|
||||
display: none !important;
|
||||
}
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
.contents {
|
||||
display: contents;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
@@ -3210,6 +3646,12 @@
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
.table-caption {
|
||||
display: table-caption;
|
||||
}
|
||||
.table-cell {
|
||||
display: table-cell;
|
||||
}
|
||||
.h-16 {
|
||||
height: calc(var(--spacing) * 16);
|
||||
}
|
||||
@@ -3708,6 +4150,12 @@
|
||||
.text-warning {
|
||||
color: var(--color-warning);
|
||||
}
|
||||
.lowercase {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.tabular-nums {
|
||||
--tw-numeric-spacing: tabular-nums;
|
||||
font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
|
||||
@@ -3755,6 +4203,17 @@
|
||||
outline-style: var(--tw-outline-style);
|
||||
outline-width: 1px;
|
||||
}
|
||||
.blur {
|
||||
--tw-blur: blur(8px);
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||
}
|
||||
.invert {
|
||||
--tw-invert: invert(100%);
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||
}
|
||||
.\!filter {
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,) !important;
|
||||
}
|
||||
.filter {
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,194 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/* Scan Django templates for utility classes (Tailwind's auto-detection doesn't
|
||||
know about our template dirs). */
|
||||
@source "../../templates";
|
||||
@source "../../controlpanel";
|
||||
|
||||
/* daisyUI: light is the default, dark applies automatically when the OS asks
|
||||
for it. An explicit data-theme on <html> (set by the toggle) overrides both. */
|
||||
@plugin "daisyui" {
|
||||
themes: light --default, dark --prefersdark;
|
||||
}
|
||||
|
||||
/* Fonts are self-hosted (files copied from the @fontsource packages into
|
||||
static/fonts/, paths are relative to the built css at /static/css/app.css).
|
||||
Google's CDN would leak every visitor's IP to a third party on page load,
|
||||
which we don't want to inherit for an EU club platform.
|
||||
|
||||
Two subsets each: `latin` covers western europe, `latin-ext` carries the
|
||||
polish/czech/turkish letters that turn up in member names. The unicode-range
|
||||
means a browser only fetches latin-ext when a page actually uses those glyphs.
|
||||
|
||||
Ubuntu is static (it has no variable version); its real weights are 400/500/700,
|
||||
so `font-semibold` (600) is synthesised up to 700 by the browser. JetBrains Mono
|
||||
and Roboto are variable: one file covers the whole weight axis. */
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-400-normal.woff2") format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-ext-400-normal.woff2") format("woff2");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-400-italic.woff2") format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-ext-400-italic.woff2") format("woff2");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-500-normal.woff2") format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-ext-500-normal.woff2") format("woff2");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-700-normal.woff2") format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("../fonts/ubuntu-latin-ext-700-normal.woff2") format("woff2");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
font-style: normal;
|
||||
font-weight: 100 800;
|
||||
font-display: swap;
|
||||
src: url("../fonts/jetbrains-mono-latin-wght-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
font-style: normal;
|
||||
font-weight: 100 800;
|
||||
font-display: swap;
|
||||
src: url("../fonts/jetbrains-mono-latin-ext-wght-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/roboto-latin-standard-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/roboto-latin-ext-standard-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* Tourney is a display face for jersey numbers and the like. Its variable file
|
||||
carries two axes -- weight 100-900 and width 75-125 -- so font-stretch has to be
|
||||
declared as a range too, otherwise the browser clamps to the default width and
|
||||
`font-stretch: 125%` (a wide shirt number) silently does nothing. */
|
||||
@font-face {
|
||||
font-family: "Tourney";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-display: swap;
|
||||
src: url("../fonts/tourney-latin-standard-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Tourney";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-display: swap;
|
||||
src: url("../fonts/tourney-latin-ext-standard-normal.woff2") format("woff2-variations");
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* Setting --font-sans / --font-mono changes the body and <code> defaults; every
|
||||
--font-* also generates a utility, so --font-roboto gives us `font-roboto` to
|
||||
opt into Roboto where we want it. */
|
||||
@theme {
|
||||
--font-sans: "Ubuntu", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;
|
||||
--font-ubuntu: "Ubuntu", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-roboto: "Roboto", ui-sans-serif, system-ui, sans-serif;
|
||||
--font-tourney: "Tourney", ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
/* The logo is a background image, not `content:` -- content-replacement on a real
|
||||
element (rather than ::before/::after) isn't supported in Firefox.
|
||||
|
||||
Default = dark-ink logo, for a light background. The media query covers "auto",
|
||||
where the toggle deliberately sets no data-theme at all; the attribute selectors
|
||||
are more specific, so an explicit choice always beats the OS. */
|
||||
.logo {
|
||||
background-image: var(--logo-dark);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.logo {
|
||||
background-image: var(--logo-light);
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="light"] .logo {
|
||||
background-image: var(--logo-dark);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logo {
|
||||
background-image: var(--logo-light);
|
||||
}
|
||||
Reference in New Issue
Block a user