/* ─────────────────────────────────────────────────────────────────────────
   PAGE HEADER — the shared banner every list page wears.

   One component, colour-coded by whichever app owns the page: a soft diagonal
   wash off the app's accent, the app's mark straight on that wash, its name as
   an eyebrow, the page's noun as the heading, the applied filters as chips you
   can clear, and the filtered count as a figure.

   Before this, `.page-header` was named in four source comments and defined in
   no stylesheet: what existed was `.list-header`, five lines of pure layout.
   Every page that wanted a header built one by hand, and nine of eleven simply
   did without — which is also why nine list pages had no <h1> at all.

   Ground rules (specs/design-system.md §3, §4):
   - No literal colour, size, radius, shadow or duration here. Everything is a
     token, and every accent-derived token is declared on `*` in
     tokens/components.css so an app theme can actually reach it.
   - The motif never passes under the title — it is masked to a wedge on the
     trailing edge. Decorative art does not go behind body text.

   Markup: crm/partials/_page_header.html
   ───────────────────────────────────────────────────────────────────────── */

@layer components {
  .page-header {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-6);
    /* Isolates the motif's blend and its negative z-index to this element, so
       neither reaches the page behind the header. */
    isolation: isolate;
    background: var(--page-header-bg);
    border-bottom: 1px solid var(--page-header-border);
    transition: padding var(--dur-fast) var(--ease-out);
  }

  /* The app's registered motif, bled off the trailing edge. Same multiply
     treatment as the page motif in base.css and for the same reason: the
     motifs are ink on paper, so multiply drops the paper and keeps the ink.
     Masked to a wedge that fades out well before the title. Apps with no
     registered motif get the plain wash — the element is not rendered. */
  .page-header__motif {
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: 40%;
    z-index: -1;
    background-image: var(--page-header-motif, none);
    background-size: cover;
    background-position: center right;
    mix-blend-mode: multiply;
    opacity: 0.12;
    mask-image: linear-gradient(to right, transparent, var(--color-text) 70%);
    pointer-events: none;
  }

  /* The mark sits on the wash itself — no plate. A surface behind it reads as
     a second object on the header rather than as the app's identity. */
  .page-header__mark {
    display: grid;
    place-items: center;
    flex-shrink: 0;
  }

  .page-header__mark img {
    /* Height-driven so every app's mark keeps its own aspect ratio. */
    height: var(--space-8);
    width: auto;
    display: block;
    transition: height var(--dur-fast) var(--ease-out);
  }

  .page-header__mark a {
    display: block;
    line-height: 0;
    transition: opacity var(--dur-fast) var(--ease-out);
  }

  .page-header__mark a:hover { opacity: 0.75; }

  .page-header__text { min-width: 0; }

  .page-header__eyebrow {
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }

  .page-header__title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 600;
    line-height: 1.2;
    color: var(--color-text);
    margin-top: var(--space-1);
  }

  /* The clauses are chips rather than prose because each one is the filter
     that produced it: the header is where you undo a filter, not a label that
     describes one. Each chip's href is the current URL minus its own query
     param, so clearing a filter goes through the URL like every other filter
     change (CLAUDE.md — filter state lives in the URL). */
  .page-header__clauses {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-wrap: wrap;
    margin-top: var(--space-2);
  }

  a.page-header__clause {
    text-decoration: none;
    color: var(--chip-fg);
  }

  a.page-header__clause:hover {
    border-color: var(--color-accent);
    color: var(--color-text);
  }

  .page-header__count {
    margin-left: auto;
    text-align: right;
    flex-shrink: 0;
  }

  .page-header__count-n {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    line-height: 1;
    color: var(--page-header-count-fg);
    display: block;
  }

  .page-header__count-unit {
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }

  /* On a list page the header is the top of the content area, not a card in
     it: it bleeds through `.main`'s padding to the edges on three sides, so the
     wash meets the rail, the top of the viewport and the right edge. The
     negative margins mirror `.main`'s own padding — keep them in step.
     Scoped to `.list-header` so the styleguide specimen, which has no page
     padding to cancel, is unaffected. */
  .list-header > .page-header {
    margin: calc(-1 * var(--space-md)) calc(-1 * var(--space-md)) var(--space-3);
  }

  /* Compact state — set by crm/js/page_header.js once the page's own scroll
     container has moved. The wash is a background rather than a layout, so
     collapsing costs nothing structural: the header loses its vertical
     padding, the mark shrinks, and the eyebrow and clauses step out of the
     way. The heading and the count never leave. */
  .page-header[data-compact] {
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  .page-header[data-compact] .page-header__mark img { height: var(--space-6); }
  .page-header[data-compact] .page-header__eyebrow,
  .page-header[data-compact] .page-header__clauses { display: none; }
}
