Moved into the filter strip, right-aligned like every other page's own Calendar/List or Week/Month/Season toggle, and switched from the bespoke .preview-tab/.preview-tab-active classes (now unused, removed) to the same raw bg-steel pill markup event_list.html already uses. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
2038 lines
61 KiB
CSS
2038 lines
61 KiB
CSS
/* RosterChief club management -- a deliberately separate stylesheet from both
|
|
* assets/app.css (the old daisyUI skin, still used by the auth/public chain via
|
|
* _club_base.html) and assets/controlpanel.css (the platform-staff surface, which is
|
|
* explicitly never club-branded).
|
|
*
|
|
* Management IS club-branded (see design_handoff_rosterchief_platform/README.md, "Club
|
|
* theming"): --color-club and --color-club-dark below resolve through --tenant-club /
|
|
* --tenant-club-dark custom properties, which management/templates/management/base.html
|
|
* sets per-request from Club.secondary_color -- everything else (structure, type,
|
|
* neutrals, status colours, table chrome, form fields) is locked platform-wide, same
|
|
* rule the design doc gives for the public site.
|
|
*
|
|
* Same "hand-roll the daisyUI-shaped class vocabulary" pattern as controlpanel.css: a
|
|
* few shared templates (`_form_fields.html`, `templatetags/field.html`,
|
|
* `controlpanel/templatetags/ui.py`'s `daisy`/`form_field`) render class names
|
|
* (`input`, `select`, `textarea`, `checkbox`, `toggle`, `btn`, `badge`, `card`, `table`,
|
|
* `modal`, `alert`, `avatar`, `progress`, `form-control`, `label`, `divide-y`, `link`)
|
|
* without daisyUI itself supplying their CSS here (it isn't loaded here either) -- see
|
|
* management/templates/management/_form_fields.html for management's own copy of that
|
|
* shared machinery (forked, not reused, so the login/MFA pages stay untouched -- same
|
|
* reasoning as controlpanel's fork, see that file's own banner comment).
|
|
*/
|
|
@import "tailwindcss";
|
|
|
|
@source "../management";
|
|
|
|
@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;
|
|
--color-navy: #101e36;
|
|
--color-steel: #1b2b47;
|
|
--color-hairline: #1e2b42;
|
|
--color-paper: #f4f5f7;
|
|
--color-line: #e3e6eb;
|
|
--color-rule: #eef0f3;
|
|
--color-edge: #d6dae1;
|
|
--color-stroke: #c9cfd8;
|
|
--color-muted: #6c7787;
|
|
--color-dim: #8b95a4;
|
|
--color-slate: #3a4658;
|
|
--color-on-dark: #93a0b4;
|
|
--color-on-dark-dim: #7c8aa0;
|
|
--color-on-dark-faint: #5c6b85;
|
|
|
|
/* Club-themeable: see the file banner. Falls back to the platform red so a club
|
|
that hasn't set a secondary_color yet still gets a sane, branded-looking accent. */
|
|
--color-club: var(--tenant-club, #e4002b);
|
|
--color-club-dark: var(--tenant-club-dark, #b00021);
|
|
/* base.html sets --tenant-club-content from Club.secondary_content_color (already
|
|
WCAG-luminance-computed black/white, see Club._content_color_for) -- e.g. the
|
|
active nav item's own text, which sits on --color-club and can't assume white
|
|
reads on every club's chosen colour. */
|
|
--color-club-content: var(--tenant-club-content, #ffffff);
|
|
|
|
/* The sidebar's own background/foreground -- base.html sets --tenant-sidebar-bg/fg
|
|
from Club.primary_color/primary_content_color when the club has set one, same
|
|
WCAG black-or-white choice as club-content above. Falls back to the original
|
|
fixed dark-ink look otherwise. Derived shades (dim/faint/hairline/chip) are
|
|
color-mix'd toward the background rather than kept as a separate light/dark
|
|
palette -- that self-corrects for either direction (dark-on-light primary colour,
|
|
or light-on-dark) instead of needing two hand-tuned scales. */
|
|
--color-sidebar-bg: var(--tenant-sidebar-bg, var(--color-ink));
|
|
--color-sidebar-fg: var(--tenant-sidebar-fg, #ffffff);
|
|
--color-sidebar-fg-dim: color-mix(in srgb, var(--color-sidebar-fg) 68%, var(--color-sidebar-bg));
|
|
--color-sidebar-fg-faint: color-mix(in srgb, var(--color-sidebar-fg) 38%, var(--color-sidebar-bg));
|
|
--color-sidebar-hairline: color-mix(in srgb, var(--color-sidebar-fg) 16%, var(--color-sidebar-bg));
|
|
--color-sidebar-chip: color-mix(in srgb, var(--color-sidebar-fg) 24%, var(--color-sidebar-bg));
|
|
|
|
--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: #14b8e8;
|
|
--color-info-bg: #eaf7fc;
|
|
--color-info-border: #c3e7f4;
|
|
--color-info-text: #0a6f91;
|
|
|
|
--color-row-sel: #fff7f8;
|
|
--color-row-focus: #f4f9ff;
|
|
--color-row-warn: #fffdf6;
|
|
--color-subhead: #f8f9fa;
|
|
|
|
/* Calendar resource colour (training rink, in the design's Season calendar screen) --
|
|
management-only, controlpanel.css has no equivalent. */
|
|
--color-violet: #7c5cfc;
|
|
|
|
--radius-box: 0.75rem; /* management cards/buttons are rounded-xl, not controlpanel's square 4px */
|
|
}
|
|
|
|
/* --- fonts: identical set to controlpanel.css, same self-hosted files (shared static/fonts/
|
|
directory -- one download, two stylesheets). See that file for the licensing/privacy
|
|
rationale (no Google Fonts CDN request). --- */
|
|
|
|
@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 {
|
|
body {
|
|
background: var(--color-paper);
|
|
color: var(--color-slate);
|
|
font-family: var(--font-sans);
|
|
}
|
|
}
|
|
|
|
/* --- component layer: same daisyUI-shaped class vocabulary as controlpanel.css, rounded
|
|
-xl (0.75rem) rather than controlpanel's square 4px -- see design tokens table,
|
|
"Radius: mobile cards rounded-[14px]; ... desktop cards rounded-xl". --- */
|
|
|
|
@layer components {
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
height: 2.25rem;
|
|
padding-inline: 1rem;
|
|
border-radius: var(--radius-box);
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
font-size: 0.8125rem;
|
|
letter-spacing: 0.08em;
|
|
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;
|
|
}
|
|
|
|
/* "ice" in the mobile/coach-app design tokens -- same #14B8E8 as --color-info here,
|
|
used e.g. for the Sign-up page's oldest-waiting row accent (signup_list.html). */
|
|
.btn-info {
|
|
background: var(--color-info);
|
|
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);
|
|
}
|
|
|
|
.btn-outline.btn-info {
|
|
background: #fff;
|
|
color: var(--color-info-text);
|
|
border-color: var(--color-info-border);
|
|
}
|
|
|
|
.btn-sm {
|
|
height: 1.875rem;
|
|
padding-inline: 0.75rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.btn-xs {
|
|
height: 1.5rem;
|
|
padding-inline: 0.5rem;
|
|
font-size: 0.6875rem;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.btn-square {
|
|
padding-inline: 0;
|
|
width: 2.25rem;
|
|
}
|
|
|
|
/* The design's own D-series badges/chips (D8's "Draft"/status pills aside) mostly run
|
|
small cornered boxes, not a full pill -- e.g. D2's team tags (U16/U18/Women, 8px)
|
|
and D8's filter chips (All 42/Overdue, 6px). A flat 999px read as noticeably rounder
|
|
than either once actually rendered at badge height, so this is a fixed value rather
|
|
than reusing --radius-box (0.75rem/12px), which is tuned for cards, not a ~22px chip. */
|
|
.badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.15rem 0.6rem;
|
|
border-radius: 6px;
|
|
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);
|
|
}
|
|
|
|
.card {
|
|
background: #fff;
|
|
border: 1px solid var(--color-line);
|
|
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: 1rem;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.table thead tr {
|
|
background: var(--color-subhead);
|
|
border-bottom: 1px solid var(--color-line);
|
|
}
|
|
|
|
.table thead th {
|
|
padding: 0.5rem 1rem;
|
|
text-align: left;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: 0.6875rem;
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.table tbody tr {
|
|
border-bottom: 1px solid var(--color-rule);
|
|
}
|
|
|
|
.table tbody tr:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
/* Scoped to .cursor-pointer, not every .table row -- most tables in the app
|
|
aren't themselves clickable (actions live in per-row buttons instead), and a
|
|
row-wide hover there would suggest an interaction that isn't there. Currently
|
|
just the Sign-up page's queue (signup_list.html), whose rows open the detail
|
|
drawer on click. --color-subhead, not --color-row-focus: that token is also
|
|
used as signup_list.html's persistent "oldest pending" row background, and
|
|
sharing it made that row look permanently hovered. */
|
|
.table tbody tr.cursor-pointer:hover {
|
|
background: var(--color-subhead);
|
|
}
|
|
|
|
.table tbody td {
|
|
padding: 0.75rem 1rem;
|
|
color: var(--color-ink);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.alert {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 0.75rem;
|
|
padding: 0.875rem 1rem;
|
|
border-radius: var(--radius-box);
|
|
border: 1px solid var(--color-line);
|
|
background: #fff;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.alert-error {
|
|
background: var(--color-danger-bg);
|
|
border-color: var(--color-danger-border);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.alert-warning {
|
|
background: var(--color-warn-bg);
|
|
border-color: var(--color-warn-border);
|
|
color: var(--color-warn-deep);
|
|
}
|
|
|
|
.alert-success {
|
|
background: var(--color-ok-bg);
|
|
border-color: var(--color-ok-border);
|
|
color: var(--color-ok-text);
|
|
}
|
|
|
|
.alert-info {
|
|
background: var(--color-info-bg);
|
|
border-color: var(--color-info-border);
|
|
color: var(--color-info-text);
|
|
}
|
|
|
|
.avatar > div {
|
|
border-radius: 999px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.avatar-placeholder > div {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: var(--color-steel);
|
|
color: #fff;
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
}
|
|
|
|
progress.progress {
|
|
appearance: none;
|
|
width: 100%;
|
|
height: 0.375rem;
|
|
border-radius: 999px;
|
|
overflow: hidden;
|
|
background: var(--color-rule);
|
|
border: none;
|
|
}
|
|
|
|
progress.progress::-webkit-progress-bar {
|
|
background: var(--color-rule);
|
|
}
|
|
|
|
progress.progress::-webkit-progress-value {
|
|
background: var(--color-ink);
|
|
}
|
|
|
|
progress.progress::-moz-progress-bar {
|
|
background: var(--color-ink);
|
|
}
|
|
|
|
progress.progress-success::-webkit-progress-value {
|
|
background: var(--color-ok);
|
|
}
|
|
|
|
progress.progress-success::-moz-progress-bar {
|
|
background: var(--color-ok);
|
|
}
|
|
|
|
progress.progress-warning::-webkit-progress-value {
|
|
background: var(--color-warn);
|
|
}
|
|
|
|
progress.progress-warning::-moz-progress-bar {
|
|
background: var(--color-warn);
|
|
}
|
|
|
|
progress.progress-error::-webkit-progress-value {
|
|
background: var(--color-club);
|
|
}
|
|
|
|
progress.progress-error::-moz-progress-bar {
|
|
background: var(--color-club);
|
|
}
|
|
|
|
.input,
|
|
.select,
|
|
.textarea,
|
|
.file-input {
|
|
width: 100%;
|
|
border: 1px solid var(--color-edge);
|
|
border-radius: 0.5rem;
|
|
background: #fff;
|
|
color: var(--color-ink);
|
|
font-family: var(--font-sans);
|
|
font-size: 0.875rem;
|
|
padding: 0.5rem 0.75rem;
|
|
height: 2.25rem;
|
|
}
|
|
|
|
.select {
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236C7787' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 0.6rem center;
|
|
background-size: 1rem;
|
|
padding-right: 2rem;
|
|
}
|
|
|
|
/* The browser's own "Choose File" control has no author styling at all, so it
|
|
renders as a second, differently-chromed box nested inside .file-input's own
|
|
border -- restyle the button itself as a small pill so there's one field
|
|
boundary, not two. The trailing "no file chosen" text is UA shadow content
|
|
(can't be restyled beyond color, which it inherits from .file-input). */
|
|
.file-input {
|
|
/* display:flex/align-items:center alone don't reliably center a file
|
|
input's native button+label in every browser -- Safari lays that out
|
|
as shadow content that ignores the host's flex alignment. Centering it
|
|
through the box model instead (top/bottom padding sized to leave equal
|
|
space above and below the button below) works regardless: 2.25rem box
|
|
- 2 * 1px border - 1.5rem button, split evenly. */
|
|
display: flex;
|
|
align-items: center;
|
|
padding-block: 0.3125rem;
|
|
color: var(--color-dim);
|
|
}
|
|
|
|
.file-input::file-selector-button,
|
|
.file-input::-webkit-file-upload-button {
|
|
/* Safari ignores author background/border-radius on this pseudo-element
|
|
and keeps drawing its own native bezeled button unless appearance is
|
|
reset first -- everything below was silently a no-op in Safari without
|
|
this line (same family of "Safari overrides author styling on a native
|
|
control" issue as the sign-up drawer's <dialog> corners). */
|
|
appearance: none;
|
|
-webkit-appearance: none;
|
|
height: 1.5rem;
|
|
padding-inline: 0.75rem;
|
|
margin-right: 0.75rem;
|
|
border: none;
|
|
/* Not 999px: that pill radius is reserved elsewhere (.avatar, .toggle,
|
|
.progress, .crest) for genuinely round/pill shapes -- every real .btn
|
|
uses var(--radius-box) (rounded-xl), so a pill here read as a toggle
|
|
chip rather than a button. */
|
|
border-radius: 0.375rem;
|
|
background: var(--color-ink);
|
|
color: #fff;
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
font-size: 0.6875rem;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
cursor: pointer;
|
|
transition: opacity 0.15s ease;
|
|
}
|
|
|
|
.file-input:hover::file-selector-button,
|
|
.file-input:hover::-webkit-file-upload-button {
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.input:focus,
|
|
.select:focus,
|
|
.textarea:focus,
|
|
.file-input:focus-within {
|
|
outline: 2px solid var(--color-club);
|
|
outline-offset: -1px;
|
|
border-color: var(--color-club);
|
|
}
|
|
|
|
.textarea {
|
|
height: auto;
|
|
min-height: 6rem;
|
|
}
|
|
|
|
.input-error,
|
|
.select-error,
|
|
.textarea-error {
|
|
border-color: var(--color-club);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
/* Taller variant for a code-entry input that has fallen back out of the boxed
|
|
.otp layout below (a recovery code is longer than the boxes fit). Same pair as
|
|
controlpanel.css's own copy -- see that file's .otp comment for why the real
|
|
input stays invisible-but-focusable rather than trying to align its own glyphs
|
|
with the box pitch via CSS alone. */
|
|
.input-lg {
|
|
height: 3rem;
|
|
font-family: var(--font-mono);
|
|
font-size: 1.125rem;
|
|
letter-spacing: 0.2em;
|
|
text-align: center;
|
|
}
|
|
|
|
.otp {
|
|
position: relative;
|
|
display: inline-flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.otp span {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 2.75rem;
|
|
height: 3rem;
|
|
border: 1px solid var(--color-edge);
|
|
border-radius: 0.5rem;
|
|
background: #fff;
|
|
font-family: var(--font-mono);
|
|
font-size: 1.25rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.otp:focus-within span {
|
|
border-color: var(--color-club);
|
|
}
|
|
|
|
.otp input {
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
padding: 0;
|
|
border: none;
|
|
outline: none;
|
|
background: transparent;
|
|
color: transparent;
|
|
caret-color: var(--color-ink);
|
|
}
|
|
|
|
.otp-lg span {
|
|
width: 3.25rem;
|
|
height: 3.5rem;
|
|
font-size: 1.375rem;
|
|
}
|
|
|
|
.checkbox {
|
|
width: 1.125rem;
|
|
height: 1.125rem;
|
|
border-radius: 0.25rem;
|
|
border: 1.5px solid var(--color-stroke);
|
|
accent-color: var(--color-club);
|
|
}
|
|
|
|
.toggle {
|
|
width: 2.5rem;
|
|
height: 1.375rem;
|
|
border-radius: 999px;
|
|
accent-color: var(--color-ok);
|
|
}
|
|
|
|
.form-control {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.label-text {
|
|
font-size: 0.8125rem;
|
|
font-weight: 600;
|
|
color: var(--color-slate);
|
|
}
|
|
|
|
.label-text-alt {
|
|
font-size: 0.75rem;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.link {
|
|
color: var(--color-club-dark);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.link-hover:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.divide-y > * + * {
|
|
border-top: 1px solid var(--color-rule);
|
|
}
|
|
|
|
/* Native <dialog>-based modals -- see management/templates/management/_modal_form.html
|
|
and _confirm_modal.html (forked from controlpanel's, same reasoning). */
|
|
dialog.modal {
|
|
margin: auto;
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: var(--radius-box);
|
|
background: transparent;
|
|
max-width: none;
|
|
max-height: none;
|
|
}
|
|
|
|
dialog.modal::backdrop {
|
|
background: rgba(11, 18, 32, 0.55);
|
|
}
|
|
|
|
dialog.modal .modal-box {
|
|
background: #fff;
|
|
border: 1px solid var(--color-line);
|
|
border-radius: var(--radius-box);
|
|
padding: 1.5rem;
|
|
width: 32rem;
|
|
max-width: 91vw;
|
|
max-height: 85vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* No .modal-start variant here (unlike controlpanel.css) -- a native <dialog>
|
|
shown via showModal() gets its own corner-rounding applied by Safari
|
|
regardless of author CSS (confirmed: zeroing border-radius on both the
|
|
<dialog> itself and its .modal-box still left rounded corners), so a
|
|
right-side slide-in drawer uses the plain .drawer-backdrop/.drawer classes
|
|
below instead -- see signup_list.html. */
|
|
|
|
.modal-action {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 0.5rem;
|
|
margin-top: 1.5rem;
|
|
}
|
|
|
|
.modal-backdrop {
|
|
display: none;
|
|
}
|
|
|
|
/* A right-side slide-in drawer (signup_list.html) -- a plain fixed-position <div>
|
|
toggled by JS (openDrawer/closeDrawer), not a native <dialog>. Safari applies its
|
|
own corner-rounding to a <dialog> shown via showModal() regardless of an author's
|
|
own border-radius: 0 (confirmed -- zeroing radius on both the <dialog> itself and
|
|
its .modal-box still left rounded corners in Safari), so a plain div sidesteps that
|
|
native top-layer rendering entirely. transform/transition also gets a real slide
|
|
animation for free, which @starting-style-based <dialog> entry animations can't
|
|
do reliably across browsers yet. */
|
|
.drawer-backdrop {
|
|
display: none;
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 50;
|
|
background: rgba(11, 18, 32, 0);
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
/* Split from .open on purpose -- display can't itself transition, so JS adds
|
|
.visible (display:block) and forces a reflow *before* adding .open (the
|
|
background/transform change), otherwise the browser never renders the
|
|
"just-appeared, still off-screen" frame to animate away from and the drawer
|
|
would just snap into place instead of sliding. */
|
|
.drawer-backdrop.visible {
|
|
display: block;
|
|
}
|
|
|
|
.drawer-backdrop.open {
|
|
background: rgba(11, 18, 32, 0.55);
|
|
}
|
|
|
|
.drawer {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
height: 100%;
|
|
width: 420px;
|
|
max-width: 91vw;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: #fff;
|
|
border-left: 1px solid var(--color-line);
|
|
transform: translateX(100%);
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.drawer-backdrop.open .drawer {
|
|
transform: translateX(0);
|
|
}
|
|
|
|
/* The club crest mark -- a circle fallback for a club with no logo uploaded (see
|
|
controlpanel.css's own .crest, which settled on a circle over the design's original
|
|
hexagon after it read as a "5-pointed" shape rather than a shield in practice). */
|
|
.crest {
|
|
border-radius: 999px;
|
|
}
|
|
|
|
/* "Place in" big team buttons on the Sign-up page (signup_list.html) -- a plain
|
|
CSS state class rather than juggling several Tailwind utilities via classList
|
|
in JS (see the page's own fetch handler), so toggling "placed" on click can't
|
|
drift out of sync with what the template renders server-side on a full reload. */
|
|
.team-chip {
|
|
border-radius: 0.5rem;
|
|
padding: 0.5rem 0.875rem;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: 0.875rem;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
border: 1px solid var(--color-line);
|
|
background: var(--color-paper);
|
|
color: var(--color-muted);
|
|
cursor: pointer;
|
|
transition:
|
|
background-color 0.15s ease,
|
|
color 0.15s ease,
|
|
border-color 0.15s ease;
|
|
}
|
|
|
|
.team-chip:hover:not(:disabled) {
|
|
border-color: var(--color-club);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.team-chip.placed,
|
|
.team-chip:disabled {
|
|
background: var(--color-ink);
|
|
color: #fff;
|
|
border-color: var(--color-ink);
|
|
cursor: default;
|
|
}
|
|
|
|
/* Sidebar nav (management/templates/management/_nav_items.html). */
|
|
.nav-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.625rem;
|
|
height: 2.5rem;
|
|
padding-inline: 0.75rem;
|
|
border-radius: 0.5rem;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: 1rem;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-sidebar-fg-dim);
|
|
}
|
|
|
|
.nav-item:hover {
|
|
color: var(--color-sidebar-fg);
|
|
}
|
|
|
|
.nav-item.active {
|
|
background: var(--color-club);
|
|
color: var(--color-club-content);
|
|
}
|
|
|
|
.nav-subitem {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
height: 1.875rem;
|
|
padding-left: 1.375rem;
|
|
font-size: 0.875rem;
|
|
color: var(--color-sidebar-fg-faint);
|
|
}
|
|
|
|
.nav-subitem:hover,
|
|
.nav-subitem.active {
|
|
color: var(--color-sidebar-fg);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* static/js/searchable-select.js's dropdown -- the script is shared with controlpanel.css
|
|
(see that file's own copy of this block) and hardcodes these daisyUI-era class names as
|
|
its public API rather than importing a stylesheet, so each app supplies its own visual
|
|
treatment under the same selectors instead of the script picking a look. */
|
|
.bg-base-100 {
|
|
background: #fff;
|
|
}
|
|
|
|
.menu {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0.375rem;
|
|
}
|
|
|
|
.menu li a {
|
|
display: block;
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 0.375rem;
|
|
font-family: var(--font-sans);
|
|
font-size: 0.875rem;
|
|
color: var(--color-ink);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.menu li a:hover {
|
|
background: var(--color-rule);
|
|
}
|
|
|
|
.menu li a.menu-active {
|
|
background: var(--color-club);
|
|
color: #fff;
|
|
}
|
|
}
|
|
|
|
/* --- Events calendar grid ---
|
|
Week/Month/Season views for management/templates/management/event_list.html
|
|
(EventListView, events/services/calendar.py). Kind -> colour follows the same
|
|
mapping as the table's own badges (see that template's inline badge classes),
|
|
just built from the underlying tokens instead of the badge component -- these
|
|
are big rectangles/chips, not small pills, so a tinted fill + solid left edge
|
|
reads better than a bordered badge blown up to size.
|
|
|
|
Percentage math: week_grid() (events/services/calendar.py) hands each block
|
|
top_pct/height_pct/left_pct/width_pct as floats relative to (a) the visible
|
|
hour span for top/height and (b) same-day overlap columns for left/width.
|
|
Percentage heights only resolve against a containing block with a *definite*
|
|
height, so .cal-week-body gets an explicit inline height (hours_span * the
|
|
fixed per-hour row height below) from the template -- everything inside it
|
|
is then free to size purely off the server-computed percentages. */
|
|
@layer components {
|
|
.cal-week-inner {
|
|
min-width: 55rem;
|
|
}
|
|
|
|
.cal-week-header {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--color-line);
|
|
}
|
|
|
|
.cal-week-gutter-spacer {
|
|
width: 3.5rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.cal-week-daycol-header {
|
|
flex: 1 1 0;
|
|
min-width: 7.5rem;
|
|
padding: 0.5rem 0.25rem;
|
|
text-align: center;
|
|
border-left: 1px solid var(--color-rule);
|
|
}
|
|
|
|
.cal-week-daycol-header.is-today {
|
|
background: var(--color-row-focus);
|
|
}
|
|
|
|
.cal-daycol-dow {
|
|
display: block;
|
|
font-family: var(--font-display);
|
|
font-size: 0.6875rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.cal-week-daycol-header.is-today .cal-daycol-dow {
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.cal-daycol-num {
|
|
display: block;
|
|
font-family: var(--font-display);
|
|
font-size: 1.25rem;
|
|
font-weight: 800;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
/* Explicit height set inline by the template (hours_span * row height) --
|
|
this is what makes the children's percentage top/height resolve at all.
|
|
display:flex is just as load-bearing here as that inline height: the
|
|
gutter and day columns are meant to sit side by side, each stretched
|
|
(flex's default align-items) to the row's full height -- without it
|
|
they're plain block children, which stack vertically instead of
|
|
side-by-side and, since their real content is all position:absolute
|
|
(contributing nothing to auto-height), each collapses to near-zero
|
|
height too. */
|
|
.cal-week-body {
|
|
position: relative;
|
|
display: flex;
|
|
}
|
|
|
|
.cal-week-gridlines {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cal-hour-line {
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
background: var(--color-rule);
|
|
}
|
|
|
|
.cal-week-gutter {
|
|
position: relative;
|
|
width: 3.5rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.cal-hour-label {
|
|
position: absolute;
|
|
right: 0.625rem;
|
|
transform: translateY(-50%);
|
|
font-family: var(--font-mono);
|
|
font-size: 0.6875rem;
|
|
color: var(--color-dim);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.cal-week-daycol {
|
|
position: relative;
|
|
flex: 1 1 0;
|
|
min-width: 7.5rem;
|
|
border-left: 1px solid var(--color-rule);
|
|
}
|
|
|
|
.cal-week-daycol.is-today {
|
|
background: var(--color-row-focus);
|
|
}
|
|
|
|
/* Positioned by the template's inline style (top/height/left/width, straight
|
|
from the block dict) -- this element owns the percentage box, a plain
|
|
inset+margin child owns the visual pill, so the 1px gap between
|
|
side-by-side overlapping blocks doesn't have to come out of the
|
|
server-computed width itself. */
|
|
.cal-block-slot {
|
|
position: absolute;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.cal-block {
|
|
position: absolute;
|
|
inset: 0;
|
|
margin: 1px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.125rem;
|
|
overflow: hidden;
|
|
border-radius: 0.375rem;
|
|
border-left: 3px solid;
|
|
padding: 0.25rem 0.375rem;
|
|
text-decoration: none;
|
|
transition: opacity 0.15s ease;
|
|
}
|
|
|
|
.cal-block:hover {
|
|
opacity: 0.82;
|
|
}
|
|
|
|
.cal-block-time {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.625rem;
|
|
font-weight: 600;
|
|
opacity: 0.85;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.cal-block-title {
|
|
font-size: 0.6875rem;
|
|
font-weight: 700;
|
|
line-height: 1.15;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Kind -> colour, same source palette as the table's badges (event_list.html):
|
|
game=club-dark/error, training=info, tournament=warn, meeting=ink/neutral,
|
|
social=violet, other=neutral outline. Solid tint + left edge, not a badge --
|
|
these blocks are far bigger than a pill. */
|
|
.cal-block-game {
|
|
background: var(--color-danger-bg);
|
|
border-color: var(--color-club-dark);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.cal-block-training {
|
|
background: var(--color-info-bg);
|
|
border-color: var(--color-info);
|
|
color: var(--color-info-text);
|
|
}
|
|
|
|
.cal-block-tournament {
|
|
background: var(--color-warn-bg);
|
|
border-color: var(--color-warn);
|
|
color: var(--color-warn-text);
|
|
}
|
|
|
|
.cal-block-meeting {
|
|
background: var(--color-rule);
|
|
border-color: var(--color-ink);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.cal-block-social {
|
|
background: color-mix(in srgb, var(--color-violet) 12%, white);
|
|
border-color: var(--color-violet);
|
|
color: var(--color-violet);
|
|
}
|
|
|
|
.cal-block-other {
|
|
background: #fff;
|
|
border-color: var(--color-edge);
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
/* --- Month grid --- */
|
|
.cal-month-daynames {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
border-bottom: 1px solid var(--color-line);
|
|
background: var(--color-subhead);
|
|
}
|
|
|
|
.cal-month-dayname {
|
|
padding: 0.4rem 0.25rem;
|
|
text-align: center;
|
|
font-family: var(--font-display);
|
|
font-size: 0.625rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.cal-month-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
border-top: 1px solid var(--color-line);
|
|
border-left: 1px solid var(--color-line);
|
|
}
|
|
|
|
.cal-month-cell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25rem;
|
|
min-height: 6.75rem;
|
|
padding: 0.375rem;
|
|
background: #fff;
|
|
border-right: 1px solid var(--color-line);
|
|
border-bottom: 1px solid var(--color-line);
|
|
}
|
|
|
|
.cal-month-cell.is-outside {
|
|
background: var(--color-paper);
|
|
}
|
|
|
|
.cal-month-cell.is-outside .cal-month-cell-num {
|
|
color: var(--color-dim);
|
|
}
|
|
|
|
.cal-month-cell.is-today {
|
|
background: var(--color-row-focus);
|
|
}
|
|
|
|
.cal-month-cell-num {
|
|
font-family: var(--font-display);
|
|
font-size: 0.875rem;
|
|
font-weight: 800;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.cal-month-cell.is-today .cal-month-cell-num {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 1.375rem;
|
|
height: 1.375rem;
|
|
border-radius: 999px;
|
|
background: var(--color-club);
|
|
color: var(--color-club-content);
|
|
}
|
|
|
|
.cal-month-cell-events {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.1875rem;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.cal-chip {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.3125rem;
|
|
padding: 0.0625rem 0.25rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.625rem;
|
|
font-weight: 600;
|
|
line-height: 1.4;
|
|
text-decoration: none;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.cal-chip-game {
|
|
background: var(--color-danger-bg);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.cal-chip-training {
|
|
background: var(--color-info-bg);
|
|
color: var(--color-info-text);
|
|
}
|
|
|
|
.cal-chip-tournament {
|
|
background: var(--color-warn-bg);
|
|
color: var(--color-warn-text);
|
|
}
|
|
|
|
.cal-chip-meeting {
|
|
background: var(--color-rule);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.cal-chip-social {
|
|
background: color-mix(in srgb, var(--color-violet) 12%, white);
|
|
color: var(--color-violet);
|
|
}
|
|
|
|
.cal-chip-other {
|
|
background: var(--color-paper);
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
.cal-dot {
|
|
width: 0.375rem;
|
|
height: 0.375rem;
|
|
border-radius: 999px;
|
|
flex-shrink: 0;
|
|
background: currentColor;
|
|
}
|
|
|
|
.cal-chip-more {
|
|
padding: 0.0625rem 0.25rem;
|
|
font-size: 0.625rem;
|
|
font-weight: 600;
|
|
color: var(--color-muted);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.cal-chip-more:hover {
|
|
color: var(--color-ink);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* --- Season grid: one mini month-calendar per month, counts only (no titles --
|
|
there's no room at this scale, see events/services/calendar.py's season_grid
|
|
docstring). --- */
|
|
.cal-season-daynames {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.cal-season-dayname {
|
|
text-align: center;
|
|
font-family: var(--font-mono);
|
|
font-size: 0.5625rem;
|
|
color: var(--color-dim);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.cal-season-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
gap: 2px;
|
|
}
|
|
|
|
.cal-season-cell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.0625rem;
|
|
aspect-ratio: 1;
|
|
border-radius: 0.25rem;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.cal-season-daynum {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.625rem;
|
|
color: var(--color-slate);
|
|
}
|
|
|
|
.cal-season-cell.is-outside .cal-season-daynum {
|
|
color: var(--color-dim);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.cal-season-cell.is-today {
|
|
background: var(--color-row-focus);
|
|
}
|
|
|
|
.cal-season-cell.is-today .cal-season-daynum {
|
|
font-weight: 700;
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.cal-season-cell.has-events {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cal-season-cell.has-events:hover {
|
|
background: var(--color-subhead);
|
|
}
|
|
|
|
.cal-season-count {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 0.875rem;
|
|
height: 0.875rem;
|
|
padding: 0 0.1875rem;
|
|
border-radius: 999px;
|
|
background: var(--color-club);
|
|
color: var(--color-club-content);
|
|
font-family: var(--font-mono);
|
|
font-size: 0.5rem;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
}
|
|
}
|
|
|
|
/* --- Event form ---
|
|
management/templates/management/event_form.html and event_series_form.html
|
|
(EventForm/EventSeriesForm) -- both share the exact same treatment: a
|
|
prominent kind picker up top (a row of clickable "kind cards" layered over
|
|
the real, always-visible <select id="id_kind"> -- the select stays the
|
|
single source of truth so it's still fully keyboard/screen-reader operable;
|
|
see each template's own inline <script> for how the two stay in sync), then
|
|
the rest of the form broken into titled .card sections instead of one long
|
|
flat form. Kind -> colour on a selected card reuses the exact same tokens
|
|
as the event list's own badges and the calendar grid just above (game =
|
|
club-dark/danger, training = info, tournament = warn, meeting = ink/
|
|
neutral, social = violet), so this reads as part of the same system rather
|
|
than a fourth palette. .game-only itself carries no rule here -- same as
|
|
before this section existed, it's a plain marker class the template's own
|
|
script toggles Tailwind's `hidden` utility on/off. */
|
|
@layer components {
|
|
.event-section-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.event-section-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 2.25rem;
|
|
height: 2.25rem;
|
|
flex-shrink: 0;
|
|
border-radius: 0.625rem;
|
|
background: var(--color-rule);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
/* Game details' own section icon -- a small accent so the one card that's
|
|
conditionally shown/hidden also reads as "special" at a glance. */
|
|
.event-section-icon-accent {
|
|
background: var(--color-danger-bg);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.event-section-title {
|
|
font-family: var(--font-display);
|
|
font-weight: 800;
|
|
font-size: 0.9375rem;
|
|
letter-spacing: 0.03em;
|
|
color: var(--color-ink);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.event-section-hint {
|
|
margin-top: 0.125rem;
|
|
font-size: 0.8125rem;
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
/* The kind-card row -- 2 columns on mobile, up to 6 (one per EventKind) on
|
|
desktop, so all of them are glanceable in a single row on a normal-width
|
|
screen without ever needing to scroll the picker itself. */
|
|
.kind-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 0.625rem;
|
|
}
|
|
|
|
@media (min-width: 640px) {
|
|
.kind-grid {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.kind-grid {
|
|
grid-template-columns: repeat(6, 1fr);
|
|
}
|
|
}
|
|
|
|
.kind-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.375rem;
|
|
padding: 0.875rem 0.5rem;
|
|
border: 1.5px solid var(--color-line);
|
|
border-radius: var(--radius-box);
|
|
background: #fff;
|
|
color: var(--color-muted);
|
|
cursor: pointer;
|
|
text-align: center;
|
|
transition:
|
|
border-color 0.15s ease,
|
|
background-color 0.15s ease,
|
|
color 0.15s ease;
|
|
}
|
|
|
|
.kind-card:hover {
|
|
border-color: var(--color-stroke);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
/* The card's own radio is visually sr-only (see event_form.html/
|
|
event_series_form.html) -- :has() reads its checked/focus state back
|
|
onto the label so there's a visible focus ring for keyboard users even
|
|
though the input itself is off-screen. */
|
|
.kind-card:has(input:focus-visible) {
|
|
outline: 2px solid var(--color-club);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.kind-card-label {
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: 0.6875rem;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/* Default (also covers "meeting" and "other", which share the app's own
|
|
ink/neutral and muted/outline treatment elsewhere) -- the per-kind
|
|
overrides below only replace it for the four kinds with their own
|
|
colour in the badge/calendar system. */
|
|
.kind-card:has(input:checked) {
|
|
border-color: var(--color-ink);
|
|
background: var(--color-subhead);
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.kind-card:has(input:checked)[data-kind="game"] {
|
|
border-color: var(--color-club-dark);
|
|
background: var(--color-danger-bg);
|
|
color: var(--color-club-dark);
|
|
}
|
|
|
|
.kind-card:has(input:checked)[data-kind="training"] {
|
|
border-color: var(--color-info);
|
|
background: var(--color-info-bg);
|
|
color: var(--color-info-text);
|
|
}
|
|
|
|
.kind-card:has(input:checked)[data-kind="tournament"] {
|
|
border-color: var(--color-warn);
|
|
background: var(--color-warn-bg);
|
|
color: var(--color-warn-text);
|
|
}
|
|
|
|
.kind-card:has(input:checked)[data-kind="social"] {
|
|
border-color: var(--color-violet);
|
|
background: color-mix(in srgb, var(--color-violet) 12%, white);
|
|
color: var(--color-violet);
|
|
}
|
|
|
|
/* club_wide's own toggle, pulled out of the plain field grid into its own
|
|
framed row -- a whole-club event is a bigger decision than any other
|
|
audience field here, so it gets to look like one. */
|
|
.event-clubwide-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
padding: 0.75rem 1rem;
|
|
border: 1px solid var(--color-line);
|
|
border-radius: 0.625rem;
|
|
background: var(--color-paper);
|
|
}
|
|
|
|
/* The live "what you're scheduling" recap -- a dashed border marks it as a
|
|
read-only, generated-for-you strip rather than another input card. */
|
|
.event-summary {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
padding: 0.875rem 1.125rem;
|
|
border-style: dashed;
|
|
color: var(--color-slate);
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.event-summary-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
width: 2rem;
|
|
height: 2rem;
|
|
border-radius: 999px;
|
|
background: var(--color-club);
|
|
color: var(--color-club-content);
|
|
}
|
|
}
|
|
|
|
/* --- In-page content-swap toggle (bg-steel pill shell) ---
|
|
Same bg-steel pill shell as member_list.html's Members/Guardians/Both
|
|
selector, but a JS-toggled pair (or more) of <button>s -- an in-page
|
|
content swap, not a page navigation with its own querystring state -- so a
|
|
dedicated small class pair is simpler than juggling several Tailwind
|
|
utilities via classList from the script.
|
|
|
|
.view-toggle-btn is the generic name (email_previews.html's Email/Plain
|
|
text toggle); .news-lang-btn is kept as an alias so _news_preview.html's
|
|
NL/EN toggle (and its own JS, which reads that exact class) needs no
|
|
change. */
|
|
@layer components {
|
|
.news-lang-btn,
|
|
.view-toggle-btn {
|
|
border-radius: 999px;
|
|
padding: 0.375rem 0.75rem;
|
|
font-family: var(--font-display);
|
|
font-size: 0.75rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
color: var(--color-on-dark);
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.news-lang-btn:hover,
|
|
.view-toggle-btn:hover {
|
|
color: #fff;
|
|
}
|
|
|
|
.news-lang-btn.active,
|
|
.view-toggle-btn.active {
|
|
background: #fff;
|
|
color: var(--color-ink);
|
|
}
|
|
}
|
|
|
|
/* --- Member attendance sparkline (management/templates/management/member_detail.html) ---
|
|
D7's 12-bar strip: uniform-height blocks, not a value chart -- each bar is
|
|
just one event's outcome (ok present, club absent, edge upcoming), not a
|
|
magnitude, so there's nothing for a bar's height to encode. */
|
|
@layer components {
|
|
.attendance-sparkline {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
}
|
|
|
|
.attendance-bar {
|
|
width: 0.5rem;
|
|
height: 2rem;
|
|
border-radius: 2px;
|
|
background: var(--color-edge);
|
|
}
|
|
|
|
.attendance-bar-present {
|
|
background: var(--color-ok);
|
|
}
|
|
|
|
.attendance-bar-absent {
|
|
background: var(--color-club);
|
|
}
|
|
}
|
|
|
|
/* --- Club identity page (management/templates/management/club_settings.html) ---
|
|
Colours: swatch + mono hex merged into one bordered row (D9's own look),
|
|
not a labelled field with a decorative swatch floating below it. Live
|
|
preview: a mini mock of this app's own sidebar/button (the real, live
|
|
surface primary_color/secondary_color affect today, via base.html's
|
|
--tenant-* custom properties) plus a mobile app mock (the same colours
|
|
applied to the surface that's built next) -- not D9's fabricated App/
|
|
Website/Email tabs. Colours are set inline by that template's own script
|
|
as the form fields change; only layout/typography lives here. */
|
|
@layer components {
|
|
.club-color-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.625rem;
|
|
border: 1px solid var(--color-edge);
|
|
border-radius: 0.5rem;
|
|
padding: 0.5rem 0.625rem;
|
|
}
|
|
|
|
.club-color-swatch {
|
|
width: 1.625rem;
|
|
height: 1.625rem;
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
border: none;
|
|
border-radius: 0.375rem;
|
|
background: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.club-color-hex-input {
|
|
flex: 1;
|
|
min-width: 0;
|
|
border: none;
|
|
background: none;
|
|
outline: none;
|
|
padding: 0;
|
|
font-family: var(--font-mono);
|
|
font-size: 0.875rem;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.club-contrast-box {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 0.5rem;
|
|
border-radius: 0.5rem;
|
|
padding: 0.625rem 0.75rem;
|
|
font-size: 0.8125rem;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.club-logo-dropzone {
|
|
display: flex;
|
|
width: 4.75rem;
|
|
height: 4.75rem;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
border: 1.5px dashed var(--color-stroke);
|
|
border-radius: 0.5rem;
|
|
background: var(--color-paper);
|
|
}
|
|
|
|
.preview-crest {
|
|
display: flex;
|
|
width: 1.5rem;
|
|
height: 1.5rem;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 0.25rem;
|
|
background: rgba(255, 255, 255, 0.15);
|
|
font-family: var(--font-display);
|
|
font-size: 0.625rem;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.preview-skeleton-line {
|
|
height: 0.5rem;
|
|
border-radius: 999px;
|
|
background: var(--color-line);
|
|
}
|
|
|
|
.preview-skeleton-line-short {
|
|
width: 60%;
|
|
}
|
|
|
|
/* The mobile app mock -- not built yet, but its header/role-switcher/
|
|
"Next up" card take the same primary/secondary colours a real one
|
|
would, so this preview stays accurate once it exists. Sized closer to
|
|
an actual phone aspect ratio (tall, mostly-empty screen below the
|
|
first couple of cards) rather than a cropped sliver. */
|
|
.preview-phone-lg {
|
|
width: 12.5rem;
|
|
flex-shrink: 0;
|
|
overflow: hidden;
|
|
border: 5px solid var(--color-ink);
|
|
border-radius: 1.375rem;
|
|
background: var(--color-paper);
|
|
}
|
|
|
|
.preview-phone-lg .preview-phone-body {
|
|
min-height: 15rem;
|
|
}
|
|
|
|
.preview-phone-header {
|
|
padding: 0.75rem 0.625rem 0.625rem;
|
|
background: var(--color-ink);
|
|
color: #fff;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.preview-phone-header-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.375rem;
|
|
}
|
|
|
|
.preview-crest-sm {
|
|
width: 1.125rem;
|
|
height: 1.125rem;
|
|
font-size: 0.5rem;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
.preview-phone-name {
|
|
font-family: var(--font-display);
|
|
font-size: 0.6875rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.preview-phone-roles {
|
|
display: flex;
|
|
gap: 2px;
|
|
margin-top: 0.5rem;
|
|
padding: 2px;
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
}
|
|
|
|
.preview-phone-role {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 1.25rem;
|
|
border-radius: 999px;
|
|
font-family: var(--font-display);
|
|
font-size: 0.5625rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-on-dark);
|
|
}
|
|
|
|
.preview-phone-role-active {
|
|
background: #fff;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.preview-phone-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
padding: 0.625rem;
|
|
}
|
|
|
|
.preview-phone-card {
|
|
border-radius: 0.5rem;
|
|
padding: 0.5rem;
|
|
background: var(--color-ink);
|
|
color: #fff;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.preview-phone-eyebrow {
|
|
font-family: var(--font-display);
|
|
font-size: 0.5625rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--color-info);
|
|
}
|
|
|
|
.preview-phone-title {
|
|
margin-top: 0.125rem;
|
|
font-family: var(--font-display);
|
|
font-size: 0.75rem;
|
|
line-height: 1.05;
|
|
font-weight: 800;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.preview-phone-bar {
|
|
height: 1rem;
|
|
margin-top: 0.5rem;
|
|
border-radius: 0.25rem;
|
|
background: var(--color-ok);
|
|
}
|
|
|
|
.preview-phone-skeleton-card {
|
|
border: 1px solid var(--color-line);
|
|
border-radius: 0.5rem;
|
|
padding: 0.5rem;
|
|
background: #fff;
|
|
}
|
|
|
|
/* The public-site mock -- same "not built yet, but coloured accurately"
|
|
reasoning as the phone mock above. */
|
|
.preview-website {
|
|
overflow: hidden;
|
|
border: 1px solid var(--color-line);
|
|
border-radius: 0.625rem;
|
|
}
|
|
|
|
.preview-website-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.625rem 0.75rem;
|
|
background: var(--color-ink);
|
|
color: #fff;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.preview-website-name {
|
|
font-family: var(--font-display);
|
|
font-size: 0.8125rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.preview-website-nav {
|
|
margin-left: auto;
|
|
font-family: var(--font-display);
|
|
font-size: 0.625rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
color: var(--color-on-dark);
|
|
}
|
|
|
|
.preview-website-join {
|
|
border-radius: 0.25rem;
|
|
padding: 0.1875rem 0.4375rem;
|
|
background: var(--color-club);
|
|
color: #fff;
|
|
font-family: var(--font-display);
|
|
font-size: 0.625rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
}
|
|
|
|
.preview-website-hero {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
padding: 0.875rem 0.75rem;
|
|
background: var(--color-subhead);
|
|
}
|
|
|
|
.preview-website-headline {
|
|
font-family: var(--font-display);
|
|
font-size: 1.375rem;
|
|
line-height: 0.98;
|
|
font-weight: 800;
|
|
text-transform: uppercase;
|
|
color: var(--color-ink);
|
|
}
|
|
|
|
.preview-brand-dot {
|
|
width: 0.5rem;
|
|
height: 0.5rem;
|
|
flex-shrink: 0;
|
|
border-radius: 0.125rem;
|
|
background: var(--color-club);
|
|
}
|
|
|
|
.preview-brand-dot-neutral {
|
|
background: var(--color-dim);
|
|
}
|
|
}
|