/* ============================================================ * app.css — supplemental styles only * ------------------------------------------------------------ * The member-console design system is Bootstrap-first. This file * does NOT define a parallel token layer or utility system: it only * covers the small set of things Bootstrap 5 does not. * * Contract: * - Use Bootstrap utilities/components directly in templates. * - Add a rule here only when Bootstrap genuinely cannot express it * (e.g. the HTMX loading-indicator hook, fixed toast positioning, * cross-browser styling). * - Reference Bootstrap CSS variables (var(--bs-*)) instead of * hardcoded color values so this file stays in sync if Bootstrap's * defaults change. * * See docs/design-system.md for the full Bootstrap usage guide and the * custom-primitives reference. * ============================================================ */ /* HTMX loading indicators */ .htmx-indicator { display: none; } .htmx-request .htmx-indicator { display: inline-block; } .htmx-request.htmx-indicator { display: inline-block; } /* Dashboard quota bar */ .quota-bar { height: 8px; border-radius: 4px; } /* Global toast positioning */ .toast-container { position: fixed; top: 1rem; right: 1rem; z-index: 1100; } /* Entitlement quota meter — Bootstrap doesn't style consistently * across engines, so we normalize it to the Bootstrap primary color. */ meter { height: 0.75rem; border-radius: 0.25rem; overflow: hidden; } meter::-webkit-meter-bar { background: var(--bs-border-color); border: none; border-radius: 0.25rem; } meter::-webkit-meter-optimum-value, meter::-webkit-meter-suboptimum-value, meter::-webkit-meter-even-less-good-value { background: var(--bs-primary); border-radius: 0.25rem; } meter::-moz-meter-bar { background: var(--bs-primary); } /* Application shell rail (docs/design-system.md "Application shell"; * chrome-conventions "One shell for both surfaces"). Present on every * top-level layout: the member rail (partials/shell_rail_member.html) and * the operator rail (operator.html). A fixed 15rem so labels never reflow * and no entry's content can ever widen it (maintainer 2026-08-23: the * sidebar never gets wide; long labels wrap instead). Below lg the same * element is a Bootstrap offcanvas drawer, where the fixed width also caps * the drawer. */ .app-sidebar { min-width: 15rem; max-width: 15rem; } /* At lg and up Bootstrap's responsive offcanvas (.offcanvas-lg) becomes a * static block, resets its background to transparent, and lays out * .offcanvas-body as a flex row. Restore the rail's surface and let the * entry list fill the rail's width so the active highlight spans it. */ @media (min-width: 992px) { .app-sidebar { background-color: var(--bs-light) !important; } .app-sidebar .offcanvas-body { flex-direction: column; } .app-sidebar .offcanvas-body > .nav { width: 100%; } } /* The surface switch, the rail's one non-section entry (member rail: * "Operator panel"; operator rail: "Member dashboard"), sits last and apart * from the task entries, using the border-top-plus-spacing grouping idiom * the rails have always used. */ .app-rail-switch { margin-top: 0.5rem; padding-top: 0.5rem; border-top: var(--bs-border-width) solid var(--bs-border-color); } /* The rail toggler lives in an always-expanded navbar, and Bootstrap's * .navbar-expand hides .navbar-toggler at every width; show it below lg, * where the rail is a drawer (d-lg-none hides it again at lg and up). */ @media (max-width: 991.98px) { .app-topbar .navbar-toggler { display: inline-block; } } /* The account menu's trigger is a