/* RosterChief control panel — a deliberately separate stylesheet. * * The control panel is a distinct surface (see design_handoff_rosterchief_platform/README.md): * industrial, dark command bar over a light workspace, its own type system (Barlow / * Barlow Condensed / IBM Plex Mono) and colour tokens, and — per that handoff — "never * club-branded". It does not import assets/app.css and does not load daisyUI: sharing either * would mean the panel inherits the club-facing app's theme variables and component shapes, * which is exactly what "standalone" rules out. * * One wrinkle: a handful of templates the control panel renders — `controlpanel/_form_fields.html`, * `templatetags/field.html`, and the `daisy`/`form_field` template tags in * `controlpanel/templatetags/ui.py` — are also used by the sitewide login/MFA templates * (templates/account/, templates/allauth/), so their *markup* is off limits here (changing it * would reskin the login page too). Those templates emit daisyUI-shaped class names * (`input`, `select`, `textarea`, `checkbox`, `toggle`, `file-input`, `btn`, `badge`, `card`, * `table`, `modal`, `alert`, `avatar`, `progress`, `form-control`, `label`, `divide-y`, `link`) * without daisyUI itself supplying their CSS (it isn't loaded here). So this file hand-rolls * industrial-styled definitions for exactly that class vocabulary — same names, new look — * scoped to controlpanel templates only via @source below, so nothing here reaches the * pages built on assets/app.css. */ @import "tailwindcss"; @source "../controlpanel"; @theme { --font-display: "Barlow Condensed", ui-sans-serif, system-ui, sans-serif; --font-sans: "Barlow", ui-sans-serif, system-ui, sans-serif; --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace; --color-ink: #0b1220; /* darkest -- command bar, sidebars, dark cards */ --color-navy: #101e36; --color-steel: #1b2b47; /* inset controls on dark */ --color-hairline: #1e2b42; /* rules on dark surfaces */ --color-paper: #f4f5f7; /* app/page background */ --color-line: #e3e6eb; /* 1px borders on light */ --color-rule: #eef0f3; /* table row dividers */ --color-edge: #d6dae1; /* stronger light border -- control panel, inputs */ --color-stroke: #c9cfd8; /* secondary-button border */ --color-muted: #6c7787; /* secondary text */ --color-dim: #8b95a4; /* tertiary text, inactive icons */ --color-slate: #3a4658; /* body copy on light */ --color-on-dark: #93a0b4; --color-on-dark-dim: #7c8aa0; --color-on-dark-faint: #5c6b85; /* Fixed platform brand red -- the control panel is never club-branded (per the design handoff), so this is NOT the club.secondary_color CSS variable used elsewhere. */ --color-club: #e4002b; --color-club-dark: #b00021; --color-ice: #14b8e8; --color-ice-ink: #04212c; --color-ok: #14a05a; --color-ok-bg: #e6f6ee; --color-ok-border: #bfe7d3; --color-ok-text: #0c7a43; --color-warn: #f0a22e; --color-warn-bg: #fff5e4; --color-warn-border: #f6e0b8; --color-warn-text: #9a6410; --color-warn-deep: #7a4e08; --color-danger-bg: #fdecec; --color-danger-border: #f5c9ce; --color-info-bg: #eaf7fc; --color-info-border: #c3e7f4; --color-info-text: #0a6f91; --color-row-sel: #fff7f8; /* selected table row */ --color-row-focus: #f4f9ff; /* focused/active row */ --color-row-warn: #fffdf6; /* row needing attention */ --color-subhead: #f8f9fa; /* table header fill */ --radius-box: 0.25rem; /* control panel is square by intent -- 4px, not the usual rounded-xl */ } /* --- fonts: self-hosted, same latin/latin-ext split as assets/app.css and the same reasoning -- no request to Google's CDN on an EU club platform's admin surface. --- */ @font-face { font-family: "Barlow"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/barlow-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: "Barlow"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/barlow-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: "Barlow"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/barlow-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: "Barlow"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/barlow-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: "Barlow"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-latin-600-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: "Barlow"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-latin-ext-600-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: "Barlow"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/barlow-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: "Barlow"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/barlow-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: "Barlow Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-condensed-latin-600-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: "Barlow Condensed"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/barlow-condensed-latin-ext-600-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: "Barlow Condensed"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/barlow-condensed-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: "Barlow Condensed"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/barlow-condensed-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: "Barlow Condensed"; font-style: normal; font-weight: 800; font-display: swap; src: url("../fonts/barlow-condensed-latin-800-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: "Barlow Condensed"; font-style: normal; font-weight: 800; font-display: swap; src: url("../fonts/barlow-condensed-latin-ext-800-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: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/ibm-plex-mono-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: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/ibm-plex-mono-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: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/ibm-plex-mono-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: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/ibm-plex-mono-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: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/ibm-plex-mono-latin-600-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: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/ibm-plex-mono-latin-ext-600-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; } /* @layer base, not a bare rule: a bare `body { background: ... }` is unlayered CSS, which * beats every Tailwind utility class regardless of specificity -- including a `bg-ink` on *
itself (see controlpanel/templates/controlpanel/_auth_base.html), which would * silently lose to this and always render var(--color-paper) instead. Layering it puts it * where Tailwind's own base styles live, so a `bg-*`/`text-*` utility on wins as * expected; this only supplies the default for whichever page doesn't set one. */ @layer base { body { background: var(--color-paper); color: var(--color-slate); font-family: var(--font-sans); } } /* --- component layer: the daisyUI-shaped class vocabulary the shared form/message templates render (controlpanel/templates/controlpanel/_form_fields.html, controlpanel/templates/templatetags/field.html, controlpanel/templatetags/ui.py), plus the same names used directly in controlpanel's own page templates. Hand-rolled rather than @plugin "daisyui" -- see the file banner. --- */ @layer components { /* Buttons -- 34-36px desktop per the handoff; controlpanel is desktop-only. */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; /* Matches .input/.select's own 2.25rem -- see that rule's comment; .btn itself never had the clipping problem (flex centring), this is purely so a button sitting next to a field in the same row lines up. */ height: 2.25rem; padding-inline: 0.875rem; border-radius: var(--radius-box); font-family: var(--font-display); font-weight: 800; font-size: 0.8125rem; letter-spacing: 0.1em; text-transform: uppercase; background: var(--color-ink); color: #fff; border: 1px solid transparent; cursor: pointer; transition: opacity 0.15s ease; white-space: nowrap; } .btn:hover { opacity: 0.85; } .btn:disabled { opacity: 0.45; cursor: not-allowed; } .btn-primary { background: var(--color-club); color: #fff; } .btn-success { background: var(--color-ok); color: #fff; } .btn-warning { background: var(--color-warn); color: var(--color-ink); } .btn-error { background: var(--color-club-dark); color: #fff; } .btn-ghost { background: transparent; color: var(--color-ink); } .btn-ghost:hover { background: var(--color-rule); opacity: 1; } .btn-outline { background: #fff; color: var(--color-ink); border-color: var(--color-stroke); } .btn-outline:hover { background: var(--color-subhead); opacity: 1; } .btn-outline.btn-primary { background: #fff; color: var(--color-club-dark); border-color: var(--color-danger-border); } .btn-outline.btn-error { background: #fff; color: var(--color-club-dark); border-color: var(--color-danger-border); } .btn-outline.btn-success { background: #fff; color: var(--color-ok-text); border-color: var(--color-ok-border); } /* accent -- allauth tags the passkey/security-key buttons "accent" (see templates/allauth/elements/button.html and the manual btn-accent usages in templates/account/login.html, password_change.html, mfa/authenticate.html). Not one of the daisyUI semantic colours the rest of the app uses, so it gets its own token: the ice cyan, which otherwise only appears on focus rings. */ .btn-accent { background: var(--color-ice); color: var(--color-ice-ink); } .btn-outline.btn-accent { background: #fff; color: var(--color-ice-ink); border-color: var(--color-ice); } /* A bare text link shaped like a button-slot -- allauth's button element renders this for anything tagged "link" (a lower-emphasis alternative action). */ .btn-link { height: auto; padding-inline: 0; background: transparent; color: var(--color-club-dark); border-color: transparent; text-transform: none; letter-spacing: normal; font-family: var(--font-sans); font-weight: 600; text-decoration: underline; } .btn-link:hover { opacity: 1; text-decoration: none; } .btn-soft { background: color-mix(in oklab, currentColor 12%, transparent); } .btn-square { padding-inline: 0; width: 2.25rem; } .btn-sm { height: 1.75rem; padding-inline: 0.625rem; font-size: 0.75rem; } .btn-xs { height: 1.5rem; padding-inline: 0.5rem; font-size: 0.6875rem; gap: 0.25rem; } /* Badges / status pills -- rounded-full per the handoff's "status pills" spec. */ .badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.15rem 0.6rem; border-radius: 999px; font-family: var(--font-display); font-weight: 700; font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; background: var(--color-rule); color: var(--color-slate); border: 1px solid var(--color-line); white-space: nowrap; } .badge-sm { font-size: 0.625rem; padding: 0.1rem 0.45rem; } .badge-xs { font-size: 0.5625rem; padding: 0.05rem 0.35rem; } .badge-success { background: var(--color-ok-bg); color: var(--color-ok-text); border-color: var(--color-ok-border); } .badge-error { background: var(--color-danger-bg); color: var(--color-club-dark); border-color: var(--color-danger-border); } .badge-warning { background: var(--color-warn-bg); color: var(--color-warn-text); border-color: var(--color-warn-border); } .badge-info { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--color-info-border); } .badge-ghost, .badge-outline { background: #fff; color: var(--color-muted); border-color: var(--color-edge); } .badge-neutral { background: var(--color-ink); color: #fff; border-color: var(--color-ink); } /* Cards -- square by intent (4px radius), hairline border, no shadow. */ .card { background: #fff; border: 1px solid var(--color-edge); border-radius: var(--radius-box); } .card-body { padding: 1.125rem; display: flex; flex-direction: column; gap: 0.5rem; } .card-title { display: flex; align-items: center; gap: 0.5rem; font-family: var(--font-display); font-weight: 800; font-size: 0.9375rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-ink); } /* The action row a card/form/panel puts its buttons in -- allauth's own form and panel elements (templates/allauth/elements/form.html, panel.html) render this unconditionally, pairing it with justify-end plus a margin/padding utility that varies per call site. */ .card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; } /* Tables -- CSS-grid-flavoured look via plain