:root {
    /* =======================================================
       CentreMove 2026 brand tokens — the single source of all
       colour in the product. Every Tailwind token, Bootstrap
       override and component rule below reads from these custom
       properties, which is also the tenant-override seam: the
       Tenant Branding page re-declares only the overridden
       --cm-* vars in a per-tenant <style> block and the whole
       app recolours, including .btn-accent and the gradient.
       ======================================================= */
    --cm-white:      #FFFFFF;  /* Pure White — backgrounds only */
    --cm-dark:       #192620;  /* Dark Green — titles on white, dark surfaces, text on gold CTAs */
    --cm-mid:        #5C7A65;  /* Mid Green — all body text on white, title keyword highlight on white */
    --cm-light:      #B2BDB7;  /* Light Green — body text on dark green, borders, gradient end */
    --cm-gold:       #C8A96E;  /* Gold — CTA buttons, title keyword highlight on green */
    --cm-gold-hover: #B49863;  /* Gold −10% — .btn-accent hover */
    --cm-offwhite:   #F7F5F0;  /* Off White — text on green surfaces; soft card/section surface */
    --cm-border:     #E0E5E2;  /* Hairline borders / dividers (not tenant-editable) */
    --cm-gradient-angle: 90deg; /* Tenant-overridable gradient direction */
    --cm-font-title: 'Cal Sans';
    --cm-font-body:  'Quicksand';

    /* Override Bootstrap's theme colours so every Bootstrap utility class
       (.text-primary, .bg-secondary, .btn-info, …) — which uses
       !important and beats Tailwind + element selectors — resolves to the
       CentreMove palette instead of the Bootstrap defaults.
       Status colours (success/info/warning/danger) are FUNCTIONAL, not
       brand — they keep their v1 values pending separate guidance. */
    --bs-primary-rgb:   25,  38,  32;    /* Dark Green */
    --bs-secondary-rgb: 247, 245, 240;   /* Off White */
    --bs-success-rgb:   66,  204, 128;   /* #42CC80 mint */
    --bs-info-rgb:      28,  206, 244;   /* #1CCEF4 cyan */
    --bs-warning-rgb:   255, 191, 0;     /* #FFBF00 amber */
    --bs-danger-rgb:    216, 56,  91;    /* #D8385B functional danger red */
    --bs-bg-opacity: 1;

    /* Bootstrap link colour — Mid Green (links on white must pass AA;
       gold is ~2.1:1 there). The -rgb triple can't read a var; it
       stays the default-brand mid and does not follow tenant
       overrides — acceptable: it only feeds rarely-used Bootstrap
       text-opacity utilities. */
    --bs-link-color:       var(--cm-mid);
    --bs-link-color-rgb:   92, 122, 101;
    --bs-link-hover-color: var(--cm-dark);
}

html, body {
    font-family: var(--cm-font-body), ui-sans-serif, system-ui, sans-serif;
    font-feature-settings: "rlig" 1, "calt" 1;
    color: var(--cm-mid);
    background: var(--cm-white);
}

/* Titles — Cal Sans ships a SINGLE style (display-weight by design):
   never add font-bold / italic expecting a weight change. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--cm-font-title), sans-serif;
    color: var(--cm-dark);
    letter-spacing: -0.015em;
    font-weight: 400;
}

/* Links on white are MID GREEN (the on-white accent role) — gold text
   on white sits at ~2.1:1 and fails WCAG AA (axe-enforced). Gold
   remains the colour of CTAs (.btn-accent, dark text), icons and
   highlights on green surfaces. */
a, .btn-link {
    color: var(--cm-mid);
}

a:hover, .btn-link:hover {
    color: var(--cm-dark);
}

/* Links in body text get an underline so they pass WCAG 2.2 AA
   link-in-text-block (colour alone isn't enough for colour-blind
   users). Navigation, CTAs and chrome links sit outside <p>/<li>
   so they keep their cleaner look. */
p a, li a {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* AA: Mid Green sits at ~4.3:1 on the Off White surface (the brand's
   flagged borderline pair) — secondary text INSIDE bg-secondary
   surfaces renders Dark Green instead, axe-enforced. The Mud label /
   helper rules carry !important because MudBlazor's variant-specific
   selectors (.mud-input-label-outlined…) out-specify any reasonable
   override — this is an accessibility floor, not theming. */
.bg-secondary .text-muted-foreground,
.bg-secondary.text-muted-foreground,
.bg-secondary th,
thead.bg-secondary {
    color: var(--cm-dark);
}

.bg-secondary .mud-input-label,
.bg-secondary .mud-input-helper-text {
    color: var(--cm-dark) !important;
}

/* Soft, brand-tinted lift for content panels/cards (dashboard property
   tiles etc.). A resting shadow seats the white card on the Off-White
   page; it deepens on hover. Dark-Green-tinted rather than neutral grey
   so it reads as part of the brand, not a default Material drop-shadow. */
.card-lift {
    box-shadow: 0 1px 2px rgba(25, 38, 32, 0.04), 0 6px 18px rgba(25, 38, 32, 0.08);
    transition: box-shadow 180ms ease, transform 180ms ease;
}
.card-lift:hover {
    box-shadow: 0 2px 6px rgba(25, 38, 32, 0.06), 0 14px 32px rgba(25, 38, 32, 0.13);
    transform: translateY(-2px);
}

/* Static (non-clickable) content panels — same resting lift as
   .card-lift but no hover movement, so info cards don't jiggle on
   hover. Use .panel for static panels; .card-lift for clickable cards. */
.panel {
    box-shadow: 0 1px 2px rgba(25, 38, 32, 0.04), 0 6px 18px rgba(25, 38, 32, 0.08);
}

/* Data-table header bar. A solid Mid-Green fill with WHITE text — clearly
   visible on both white panels and the Off-White page, and distinct from
   the gold CTAs elsewhere on these pages. White (not Off-White) text gives
   ~4.7:1 on Mid Green (AA); Off-White would sit just under at ~4.4:1. The
   `.table-head th` rule beats the .bg-secondary th darkening (which would
   otherwise force dark text onto the green bar). */
.table-head {
    background-color: var(--cm-mid);
}
.table-head,
.table-head th {
    color: var(--cm-white);
}

/* Property-workspace active tab pill — solid Mid-Green fill, white text.
   A dedicated class rather than the bg-body utility: the Tailwind Play CDN
   proved unreliable at emitting the custom bg-body utility for the
   dynamically-applied active-tab class, leaving the button white-on-white.
   var(--cm-mid) resolves fine (the same token .table-head uses), so this is
   bulletproof. Hover is pinned so the active pill doesn't change on hover. */
.tab-active,
.tab-active:hover {
    background-color: var(--cm-mid);
    color: var(--cm-white);
}

/* Unified data-table look — every product table carries .cm-table so they
   are visually identical (the green header bar comes from .table-head on
   the <thead>). This standardises cell padding and row separators,
   overriding the per-table differences that crept in; text alignment is
   left to inline text-left/right classes on individual cells. */
.cm-table {
    width: 100%;
    font-size: 0.875rem;
    line-height: 1.25rem;
}
.cm-table th {
    padding: 0.75rem 1rem;
    font-weight: 500;
    vertical-align: middle;
}
.cm-table td {
    padding: 0.75rem 1rem;
    vertical-align: middle;
}
.cm-table tbody tr {
    border: 0;
    border-top: 1px solid var(--cm-border);
}

/* MudDataGrid (Dashboard + Feedback list views) — green header to match
   .table-head. Targets thead th so it's robust to MudBlazor's internal
   classes; the filter/sort popovers render in an overlay outside thead, so
   they're unaffected. `!important` on the background beats MudBlazor's
   sticky-header background (which is more specific under FixedHeader). */
.cm-grid thead th {
    background-color: var(--cm-mid) !important;
}
.cm-grid thead th,
.cm-grid thead th * {
    color: var(--cm-white) !important;
}

/* Make the grid fill its (bounded) flex parent so the header stays pinned at
   the top, the body scrolls inside, and the pager stays pinned at the bottom —
   instead of the whole grid scrolling away. The page markup gives the grid a
   bounded-height flex-column wrapper; these rules turn the grid into a flex
   column whose table-container is the only scroller. Requires FixedHeader on
   the grid for the sticky thead. */
.cm-grid.mud-table {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}
.cm-grid .mud-table-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}
.cm-grid .mud-table-pagination {
    flex: 0 0 auto;
}

/* The single sanctioned gradient in the product. Stops derive from
   the three brand greens, so a tenant override of --cm-dark/-mid/
   -light re-tints it by construction. No other gradient may exist
   anywhere (the global Hypercolor design standards do not apply —
   CLAUDE.md §Override clauses). */
.bg-brand-gradient {
    background-image: linear-gradient(var(--cm-gradient-angle), var(--cm-dark) 0%, var(--cm-mid) 50%, var(--cm-light) 100%);
}

.btn-primary {
    color: var(--cm-dark);
    background-color: var(--cm-gold);
    border-color: var(--cm-gold);
}

.btn-primary:hover, .btn-primary:active, .btn-primary:focus {
    background-color: var(--cm-gold-hover);
    border-color: var(--cm-gold-hover);
    color: var(--cm-dark);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem var(--cm-white), 0 0 0 0.25rem color-mix(in srgb, var(--cm-gold) 40%, transparent);
}

/* ===========================================================
   .btn-accent — canonical CentreMove gold CTA (2026 brand).
   Apply on <a>, <button>, or pass through MudButton's Class=.
   On hover the BACKGROUND darkens (gold → gold −10%); the text
   stays solid Dark Green in ALL states — never white. Matches
   the .btn-primary behaviour used by the scaffolded Identity
   buttons (Log in, Register, etc).
   The element-tagged hover selectors exist to outrank the global
   `a:hover` rule above so anchor-based CTAs don't pick up the
   gold link colour on the text.

   USAGE: <a class="btn-accent rounded-md px-4 py-2 text-sm font-medium">
   The .btn-accent class is colour + hover + transition only; the
   caller composes geometry (size, padding, radius) via Tailwind
   utilities. This way the small header CTA and the larger hero
   CTA share one canonical look-and-feel without duplicating any
   colour values.
   =========================================================== */
.btn-accent {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background-color: var(--cm-gold);
    color: var(--cm-dark);
    border: 1px solid var(--cm-gold);
    font-family: inherit;
    font-weight: 600;
    line-height: 1.5;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 180ms ease, border-color 180ms ease;
}

a.btn-accent:hover, a.btn-accent:focus, a.btn-accent:active,
button.btn-accent:hover, button.btn-accent:focus, button.btn-accent:active,
.mud-button.btn-accent:hover, .mud-button.btn-accent:focus, .mud-button.btn-accent:active,
.btn-accent:hover, .btn-accent:focus, .btn-accent:active {
    background-color: var(--cm-gold-hover);
    border-color: var(--cm-gold-hover);
    color: var(--cm-dark);
    text-decoration: none;
    opacity: 1;
}

.btn-accent:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--cm-gold) 25%, transparent);
}

.btn-accent:disabled,
.btn-accent[disabled],
.btn-accent.mud-button-disabled {
    background-color: var(--cm-gold);
    border-color: var(--cm-gold);
    color: var(--cm-dark);
    opacity: 0.5;
    cursor: not-allowed;
}

/* CentreMove-flavoured Bootstrap form-floating inputs used by /Account/** pages.
   Scoped under .auth-panel so the rules don't leak into other Bootstrap
   contexts in the future. */
.auth-panel .form-control {
    border: 1px solid var(--cm-border);
    border-radius: 0.5rem;
    color: var(--cm-dark);
    background-color: var(--cm-white);
}

.auth-panel .form-control:focus {
    border-color: var(--cm-gold);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--cm-gold) 15%, transparent);
}

.auth-panel .form-floating > label {
    color: var(--cm-mid);
}

.auth-panel .form-floating > .form-control:focus ~ label,
.auth-panel .form-floating > .form-control:not(:placeholder-shown) ~ label {
    color: var(--cm-mid);
}

.auth-panel .form-check-input:checked {
    background-color: var(--cm-gold);
    border-color: var(--cm-gold);
}

.auth-panel hr {
    border-color: var(--cm-border);
    opacity: 1;
}

.auth-panel h1, .auth-panel h2 {
    color: var(--cm-dark);
}

/* Validation errors are FUNCTIONAL red — not brand. Stays raspberry-dark. */
.auth-panel .text-danger {
    color: #B82A4A !important;
}

/* Brand panel behind the /Account/** forms. Reproduces the public waitlist
   page background (wwwroot/waitlist.html body) verbatim so login and waitlist
   read as one surface: a subtle top-left white radial highlight over the
   diagonal sage-green gradient. The two mid/end greens have no --cm-* token
   (they're waitlist-specific tints of Dark Green), so they're inlined here to
   match; the start green is --cm-dark. */
.auth-brand-panel {
    /* Faded-hero treatment matching the 2026 style-sheet cover: the
       lifestyle photo sits beneath a Dark Green scrim so it reads as a
       tinted, faded backdrop. Layers paint top-first: a soft top-left
       highlight, then the green scrim (semi-transparent so the photo
       shows through), then the photo. The panel is `hidden md:flex`, so
       the image is only fetched on desktop. Fallback colour covers the
       load gap / any fetch failure. Tune the scrim alphas for a lighter
       or heavier fade. */
    background:
        radial-gradient(1200px 700px at 12% -10%, rgba(255, 255, 255, 0.06), transparent 60%),
        linear-gradient(158deg, rgba(25, 38, 32, 0.88) 0%, rgba(36, 58, 46, 0.82) 58%, rgba(44, 64, 52, 0.80) 100%),
        url('/brand/moving-hero.jpg') center center / cover no-repeat;
    background-color: var(--cm-dark);
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* Bootstrap renders form-floating placeholders transparent so only the
   floating label shows. A previous override here made them visible and
   right-aligned, which drew the placeholder ON TOP of the label in every
   Identity form field (reported on password reset, 18/07/2026). Do not
   re-add a form-floating placeholder colour override. */
/* ---------------------------------------------------------------------
   Mobile: wide data tables (08fe / mobile audit 04/06/2026)
   Every full-width data table (class "w-full") becomes a horizontal
   scroller on narrow screens instead of clipping or crushing its
   columns — the iPhone 13 Pro Max audit found the searches table
   clipping its last column and TA10/price-paid tables crushing. The
   display:block + nowrap trick turns the table into its own scroll
   container; desktop (>=768px) is untouched. MudBlazor's own grids
   don't use the w-full utility, so they're unaffected.
   --------------------------------------------------------------------- */
@media (max-width: 767px) {
    table.w-full {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
    }
    /* Let the descriptive sub-text cells (e.g. the searches "what this
       covers" blurb) keep wrapping so they don't blow the scroll width
       out — only the tabular columns need nowrap. */
    table.w-full p {
        white-space: normal;
    }
}

/* App shell: pages still use `min-h-screen` as their root wrapper, but inside
   the fixed-height shell that would force a viewport-tall block and an extra
   scroll. Scope it to "fill the scroll area" instead, so short pages don't
   over-scroll and long pages still grow + scroll within <main>. Only affects
   pages rendered in MainLayout (not the marketing / Identity layouts). */
.app-shell-main > .min-h-screen {
    min-height: 100%;
}
