/* CCP.CustomerPortal.Shell's own chrome stylesheet (02-customer-account-management.draft.md §C, "SPECIFIED
   2026-09-16"). Every colour is a --brand-* token NAME (D-0286, light theme only) -- no prefers-color-scheme,
   no raw hex except where a value is deliberately reused as chrome, not theme (the utility bar's #181818,
   which is why it is written here as the SAME token the staff sidebar uses, --brand-surface-sidebar-bg, rather
   than a second literal). .portal-landing (Routes.razor's NotAuthorized/Authorizing fallback) predates this
   file and is left unchanged below. */

body {
    font-family: var(--brand-font-family);
    margin: 0;
}

.portal-landing {
    max-width: 32rem;
    margin: var(--brand-space-6) auto;
    padding: 0 var(--brand-space-4);
}

/* Skip-to-content link (§C.6 B-1, WCAG 2.4.1) -- the first focusable element on every page, invisible until
   it receives keyboard focus. */
.portal-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1000;
    padding: var(--brand-space-2) var(--brand-space-4);
    background: var(--brand-primary);
    color: var(--brand-on-primary);
    border-radius: var(--brand-radius-sm);
}

.portal-skip-link:focus {
    left: var(--brand-space-2);
    top: var(--brand-space-2);
}

/* F-5 (Will, 2026-09-16): ONE shared container every band's content sits inside, so the header/utility
   bar/nav/footer all line up on the same edges instead of two different content widths. The band itself
   (.portal-header etc.) stays a full-width background; this class only constrains its CONTENT. */
.portal-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 var(--brand-space-6);
}

/* F-5: "Ready to Elevate…" is a Headline, not body-weight text (EXTERNAL §5.4). */
.portal-headline {
    font-size: var(--brand-font-size-xl);
    font-weight: var(--brand-font-weight-bold);
    color: var(--brand-text);
    margin: var(--brand-space-3) 0 var(--brand-space-1);
}

/* O-3 (Will, Register): Bootstrap's default .form-check-input border is too faint against
   --brand-surface-page-bg for an unselected radio/checkbox to read as a control at all. */
.form-check-input {
    border-color: var(--brand-border-strong);
}

/* A customer brand's light tints follow that brand's own primary (Reorder finding C3). BrandColourScope's wrapper
   is the only div carrying data-brand-id on the portal, so brand.css's :root tints (CCC's blue) are re-derived
   there from the scope's --brand-primary: 22% / 11% over white lands on CCC's own #CFDFE7 / #E7EFF3. Pages with
   no brand have no such wrapper and keep the :root values untouched. */
div[data-brand-id] {
    --brand-primary-light: color-mix(in srgb, var(--brand-primary) 22%, white);
    --brand-primary-lighter: color-mix(in srgb, var(--brand-primary) 11%, white);
}

/* F-3 (Will, 2026-09-16): "Sign in" and the signed-in Account link are both a Primary-25 tinted SOFT button
   -- theme.css only re-skins .btn-primary/.btn-outline-primary, so a bare .btn-outline-secondary renders
   Bootstrap's raw grey (a non-token colour) and a bare text link has no tint at all. This chrome-local class
   is the fix for both (D-0286: tokens only). */
.portal-btn-soft {
    display: inline-flex;
    align-items: center;
    gap: var(--brand-space-1);
    background: var(--brand-primary-lighter);
    color: var(--brand-primary);
    border: 1px solid transparent;
    border-radius: var(--brand-radius-md);
    padding: var(--brand-space-2) var(--brand-space-3);
    font-size: var(--brand-font-size-sm);
    font-weight: var(--brand-font-weight-medium);
    text-decoration: none;
    line-height: 1;
}

.portal-btn-soft:hover,
.portal-btn-soft:focus-visible {
    background: var(--brand-primary-light);
    color: var(--brand-primary-hover);
}

/* ---------- Utility bar (#C.3 -- the "#181818 strip", the same fixed dark CHROME band the staff sidebar uses,
   not a theme -- §C.2) ---------- */

.portal-utility-bar {
    background: var(--brand-surface-sidebar-bg);
    color: var(--brand-text-on-brand);
    font-size: var(--brand-font-size-sm);
}

.portal-utility-bar .portal-container {
    padding-top: var(--brand-space-2);
    padding-bottom: var(--brand-space-2);
    display: flex;
    align-items: center;
    gap: var(--brand-space-4);
}

.portal-utility-bar a {
    color: var(--brand-text-on-brand);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: var(--brand-space-1);
}

.portal-utility-bar a:hover,
.portal-utility-bar a:focus-visible {
    text-decoration: underline;
}

/* ---------- Storefront content slots (Sprint 9, 02-customer-account-management.draft.md, Storefront "Behaviour inventory") ----------
   A stored block supplies text and one image, never layout: the sanitiser removes every class and style, so these
   three rules are the whole of how a block sits on the page. */

/* S2 -- the promotion is one line after the phone; its sanitised paragraph is flattened so it cannot wrap the bar. */
.portal-utility-bar__promo {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.portal-utility-bar__promo .portal-rich-text,
.portal-utility-bar__promo .portal-rich-text > * {
    display: inline;
    margin: 0;
}

/* Every block body: its elements inherit the surrounding portal typography; only the trailing margin is trimmed. */
.portal-rich-text > :last-child {
    margin-bottom: 0;
}

/* S1 and S3 -- the optional block image, after the body. */
.portal-block-image {
    display: block;
    max-width: 100%;
    height: auto;
    margin-top: var(--brand-space-3);
    border-radius: var(--brand-radius-lg);
}

/* ---------- Header (white band -- §C.3) ---------- */

.portal-header {
    background: var(--brand-surface);
    border-bottom: 1px solid var(--brand-border);
}

.portal-header-inner {
    padding-top: var(--brand-space-3);
    padding-bottom: var(--brand-space-3);
    display: flex;
    align-items: center;
    gap: var(--brand-space-4);
    flex-wrap: wrap;
}

.portal-logo-link {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.portal-logo {
    height: 36px;
    width: auto;
    max-width: 320px;
    object-fit: contain;
}

/* O-5 (Will, loop 2, 2026-09-16): flex: 1 with no ceiling let the pill grow to ~820px on a wide header
   (logo -> heart) against the mockup's ~350px compact pill. max-width caps it the same way .portal-container
   already caps its own width in raw px (no size TOKEN exists for this in the design system; D-0286 governs
   colour tokens). */
.portal-header-search {
    flex: 1 1 320px;
    min-width: 200px;
    max-width: 400px;
    position: relative;
}

/* F-1 (Will, 2026-09-16): the <form> itself carries .portal-header-search (PortalSearch.razor's root element)
   -- it is not a wrapper AROUND a form, so "form" here as a descendant selector never matched anything and the
   flex layout fusing the input to the Search button never applied. */
.portal-header-search {
    display: flex;
}

.portal-header-search .list-search {
    flex: 1;
}

.portal-header-search .btn-search {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

.portal-search-panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    background: var(--brand-surface);
    border: 1px solid var(--brand-border);
    border-radius: var(--brand-radius-md);
    box-shadow: var(--brand-shadow-md);
    margin-top: var(--brand-space-1);
    padding: var(--brand-space-3);
}

.portal-header-actions {
    display: flex;
    align-items: center;
    gap: var(--brand-space-3);
    flex-shrink: 0;
}

/* F-2 (Will, 2026-09-16): "icon button (--brand-text icon, white bg, hairline border, radius md)" -- was a
   bare icon with no container at all. */
.portal-heart-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    background: var(--brand-surface);
    border: 1px solid var(--brand-border);
    border-radius: var(--brand-radius-md);
    font-size: var(--brand-font-size-lg);
    color: var(--brand-text);
    cursor: pointer;
    line-height: 1;
    text-decoration: none;
}

.portal-heart-button:hover,
.portal-heart-button:focus-visible {
    color: var(--brand-primary);
    border-color: var(--brand-primary);
}

.portal-account-link {
    display: inline-flex;
    align-items: center;
    gap: var(--brand-space-1);
    color: var(--brand-text);
    text-decoration: none;
    font-weight: var(--brand-font-weight-medium);
}

.portal-account-link:hover,
.portal-account-link:focus-visible {
    color: var(--brand-primary);
}

/* ---------- Category nav (tinted band -- §C.3) ---------- */

/* The menu inside the band is StorefrontMenuView, which ships its own stylesheet (_content/CCP.UI.Components/storefront-menu.css, linked by PortalNav.razor); this band only supplies the ground, the
   992px collapse toggle and the wrapper (.portal-nav-list) the toggle shows and hides. The menu's text is --brand-text, which clears 4.5:1 on this tint (DESIGN-SYSTEM.md §4.38). */
.portal-nav-band {
    background: var(--brand-primary-lighter);
    border-bottom: 1px solid var(--brand-border);
}

.portal-nav-toggle {
    display: none;
}

/* §C.5 criterion 9 -- collapse at 992px (Bootstrap's lg breakpoint, U-2's named candidate: navbar-toggler). */
@media (max-width: 991.98px) {
    .portal-nav-list {
        display: none;
    }

    .portal-nav-list--expanded {
        display: block;
        padding: var(--brand-space-2) 0 var(--brand-space-3);
    }

    /* O-4 (Will, 2026-09-16): a bare icon+text with no border/tint read as inert, not a control. */
    .portal-nav-toggle {
        display: inline-flex;
        align-items: center;
        gap: var(--brand-space-1);
        background: var(--brand-surface);
        border: 1px solid var(--brand-border);
        border-radius: var(--brand-radius-md);
        margin: var(--brand-space-2) 0;
        padding: var(--brand-space-2) var(--brand-space-3);
        font-weight: var(--brand-font-weight-medium);
        color: var(--brand-text);
        cursor: pointer;
    }

    .portal-nav-toggle:hover,
    .portal-nav-toggle:focus-visible {
        color: var(--brand-primary);
        border-color: var(--brand-primary);
    }

    .portal-header-search {
        flex-basis: 100%;
        max-width: none;
        order: 3;
    }
}

/* ---------- Footer (Primary-25 band -- §C.3) ---------- */

/* F-7 (Francie, 2026-09-17): horizontal padding here stacked with .portal-container's own horizontal padding
   (F-5, layout.css above), so the footer's content sat 16px further in than every other band at 960px.
   Vertical padding is this band's own spacing; horizontal spacing is .portal-container's job alone. */
.portal-footer {
    background: var(--brand-primary-lighter);
    padding: var(--brand-space-6) 0 var(--brand-space-4);
    margin-top: var(--brand-space-8);
}

.portal-footer-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--brand-space-6);
}

.portal-footer-column h2 {
    font-size: var(--brand-font-size-sm);
    font-weight: var(--brand-font-weight-semibold);
    color: var(--brand-primary);
    margin-bottom: var(--brand-space-2);
}

.portal-footer-column ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.portal-footer-column li {
    margin-bottom: var(--brand-space-1);
}

.portal-footer-column a {
    color: var(--brand-text);
    text-decoration: none;
    font-size: var(--brand-font-size-sm);
}

.portal-footer-column a:hover,
.portal-footer-column a:focus-visible {
    color: var(--brand-primary);
    text-decoration: underline;
}

/* DESIGN-SYSTEM.md §4.38 / WCAG 2.1 AA (Francie, 2026-09-18): same --brand-text-muted-on-tint failure as .portal-footer-legal
   above -- the footer tagline (Bootstrap .text-muted) inherits the shared muted colour, which fails only
   against this band's tinted background.
   .portal-footer-column .text-muted needs !important: shared-page.css's own .text-muted { ... !important }
   (its "retuned" comment) can only be beaten by a MORE SPECIFIC !important rule, never a plain one. */
.portal-footer-column .text-muted {
    color: var(--brand-text) !important;
}

/* DESIGN-SYSTEM.md §4.38 / WCAG 2.1 AA (Francie, 2026-09-18): --brand-text-muted (#667178) measures 4.29:1 against this
   band's --brand-primary-lighter tint (#E7EFF3) -- below the 4.5:1 floor (axe color-contrast, serious). Passes
   easily against the plain white page background elsewhere, so this is scoped to the tinted footer/nav bands,
   not a global token change (DESIGN-SYSTEM.md §6 governs the token TABLE, not a per-surface override).
   --brand-text already reads correctly here -- .portal-footer-contact dd (below) made the same choice for the
   same reason. */
.portal-footer-legal {
    margin-top: var(--brand-space-6);
    padding-top: var(--brand-space-4);
    border-top: 1px solid var(--brand-border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--brand-space-4);
    align-items: center;
    justify-content: space-between;
    font-size: var(--brand-font-size-xs);
    color: var(--brand-text);
}

.portal-footer-legal a {
    color: var(--brand-text);
}

/* F-4 (Will, 2026-09-16): Email / Phone / Timing / Location as right-aligned label:value pairs, ONE text scale
   (both were previously mixed -- the two <a> values had --brand-font-size-sm, the two plain values had none,
   so they rendered visibly larger). Grid auto-flows dt,dd,dt,dd in DOM order with no wrapper element needed. */
.portal-footer-contact {
    display: grid;
    grid-template-columns: max-content max-content;
    justify-content: end;
    gap: var(--brand-space-1) var(--brand-space-2);
    margin: 0;
}

.portal-footer-contact dt {
    text-align: right;
    color: var(--brand-primary);
    font-weight: var(--brand-font-weight-semibold);
    font-size: var(--brand-font-size-sm);
}

.portal-footer-contact dd {
    margin: 0;
    color: var(--brand-text);
    font-size: var(--brand-font-size-sm);
}

.portal-footer-contact a {
    color: var(--brand-text);
    text-decoration: none;
    font-size: var(--brand-font-size-sm);
}

.portal-footer-contact a:hover,
.portal-footer-contact a:focus-visible {
    text-decoration: underline;
}

/* ---------- Account hub (§C.4) ---------- */

.portal-account-hub-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--brand-space-3);
    margin-bottom: var(--brand-space-4);
}

.portal-account-hub-identity {
    flex: 1 1 12rem;
    min-width: 0;
}

.portal-account-hub-identity p {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.portal-account-hub-identity h1 {
    margin-bottom: 0;
}

.portal-account-hub-tile {
    padding: var(--brand-space-6) var(--brand-space-4);
    text-align: center;
    color: var(--brand-text-muted);
}

/* ---------- Per-field validation (P.2.b on 05-product-detail.draft.md; Will PD-F1, 2026-09-17) ----------
   The shared `.form-error` is the submit-level refusal BANNER (shared-forms.css). A per-field message is text
   under its control, and the invalid control itself changes -- never colour alone: aria-invalid + message.
   `.validation-message` is what <ValidationMessage> emits (Register.razor); `.form-field-error` is the same
   thing on a hand-rendered message. Portal-scoped for now; the design system decides whether it hoists. */

.form-field .validation-message,
.form-field .form-field-error {
    color: var(--brand-danger-text);
    font-size: var(--brand-font-size-base);
    margin: 0;
}

.form-field [aria-invalid="true"] {
    border-color: var(--brand-danger);
}

.form-field [aria-invalid="true"]:focus-visible {
    outline-color: var(--brand-danger);
}

/* ---------- Read-only display field (Company Profile CP.1 row 4, EXTERNAL DESIGN-SYSTEM §4.5) ----------
   A field that is never an input, even in edit -- Sign Up Date. Neutral-bg fill, muted text, no border,
   distinct from the plain <p> Profile.razor already uses for its own (editable) read-state fields. */
.form-field-readonly-value {
    background: var(--brand-neutral-bg);
    color: var(--brand-neutral-text);
    border-radius: var(--brand-radius-md);
    padding: var(--brand-space-2) var(--brand-space-3);
    margin: 0;
}

/* ---------- Blank read-state value (Company Profile CP.2: "a blank value renders '—', never an empty <p>") ---------- */
.form-field-blank {
    color: var(--brand-text-muted);
}

/* ---------- Catalogue listing pages (storefront navigation spec §3.5) ----------
   The group listing, the all-products page and a heading opened as a page share this header: the bare <h1> takes Product Detail's title scale, the description and count lines are muted, and the block
   above the grid or tiles is --brand-space-5. */
.portal-listing > h1 {
    margin-bottom: var(--brand-space-2);
    font-size: var(--brand-font-size-2xl);
    font-weight: var(--brand-font-weight-bold);
    color: var(--brand-text);
    text-wrap: balance;
}

.portal-listing--tiles > h1 {
    margin-bottom: var(--brand-space-5);
}

.portal-listing__description {
    max-width: 70ch;
    margin-bottom: var(--brand-space-2);
    font-size: var(--brand-font-size-base);
    color: var(--brand-text-muted);
}

.portal-listing__count {
    margin-bottom: var(--brand-space-5);
    font-size: var(--brand-font-size-sm);
    color: var(--brand-text-muted);
}

.portal-listing > .app-empty {
    margin-top: var(--brand-space-5);
}

.portal-multiline-text {
    white-space: pre-line;
}

/* Below 576px a portal grid keeps its columns at the widths set in VisibleColumns and scrolls inside its own region
   (theme.css's .app-grid--pinned-actions pins the last column). Cells never wrap letter by letter there, so the doubled
   class beats Syncfusion's .e-wrap cell rule, which loads after this file. */
@media (max-width: 575.98px) {
    .app-grid--pinned-actions .e-grid.e-grid .e-rowcell,
    .app-grid--pinned-actions .e-grid.e-grid .e-headercell {
        white-space: nowrap;
    }
}

/* theme.css fades the pinned last column in with a mask-image, and a mask fades the cell's own top border as well, so
   every row divider broke at the pinned cell. Here the pinned cell is fully opaque instead, so a scrolled column never
   shows through or under the Actions buttons, and it keeps the single left rule (§4f C3) that marks where the pinned
   region starts and signals the columns beside it scroll sideways. */
.app-grid--pinned-actions .e-grid.e-grid .e-headercontent tr > th:last-child,
.app-grid--pinned-actions .e-grid.e-grid tr > td.e-filterbarcell:last-child,
.app-grid--pinned-actions .e-grid.e-grid .e-content tr > td:last-child {
    -webkit-mask-image: none;
    mask-image: none;
    border-left: 1px solid var(--brand-border);
    background-color: var(--brand-surface);
    background-image: none;
}

.app-grid--pinned-actions .e-grid.e-grid .e-content tr:hover > td:last-child {
    background-color: var(--brand-primary-light);
}
