/* SAINT BONES — GLOBAL HEADER COMPONENT
 *
 * Authority: component contract 1 (GLOBAL HEADER); approved artifacts
 * `Saint Bones Global Header States.dc.html` (desktop bar and states) and
 * `Saint Bones Mobile Navigation.dc.html` state 01 (compact bar).
 *
 * WHAT THIS FILE DELIBERATELY DOES NOT CONTAIN
 * --------------------------------------------
 * The frozen Design System already owns most of this component. sb-layout.css
 * defines `.sb-header` itself — sticky, flex, space-between, gap, 78px height,
 * page gutter, inverse ground, hairline border, `--over-media`, `--fluid` — and
 * owns the 1040px switch, including hiding `.sb-header__nav` and revealing
 * `.sb-header__drawer-toggle`. sb-foundation.css owns `.sb-wordmark`,
 * `.sb-nav-text` (and its automatic 10px/.16em compaction below 768px),
 * `a:hover` → metal, the `:focus-visible` ring, and `.sb-visually-hidden`.
 *
 * None of that is restated here. This file adds only what the system leaves to
 * the component, and it introduces no colour, no type scale, no breakpoint and
 * no spacing value that is not already a token.
 *
 * TWO RULES THAT MUST NOT BE BROKEN BY A LATER EDIT
 * -------------------------------------------------
 * 1. Never set `display` on `.sb-header__nav` or `.sb-header__drawer-toggle`
 *    outside the mirrored breakpoint blocks at the end of this file. This
 *    stylesheet loads *after* sb-layout.css, so an unconditional `display`
 *    declaration would silently defeat the frozen 1040px behaviour at equal
 *    specificity — the header would keep its desktop nav all the way down.
 * 2. Never give `.sb-header__brand` a horizontal margin. Contract 1's measured
 *    content-fit (left ≈401 + brand ≈266 + right ≈286 + inter-group ≈32 +
 *    gutters ≈40 ≈ 1025px) only clears 1040px because the inter-group space is
 *    the frozen `gap` on `.sb-header`. The approved prototype's `margin:0 44px`
 *    is prototype CSS, not authority (DEC-009); copying it would add ~88px and
 *    make the desktop nav collide *above* its own breakpoint.
 *
 * @package SaintBones
 */

/* ---------- CLUSTERS -------------------------------------------------
 * Left and right both grow, so the brand stays optically centred while the
 * two clusters absorb the remaining width. `nowrap` is what makes a collision
 * visible as an overflow rather than hiding it as a silent second line.
 */
.sb-header__nav,
.sb-header__utils {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--sb-color-text-inverse-secondary);
}

.sb-header__utils {
  display: flex;
  justify-content: flex-end;
}

.sb-header__list {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.sb-header__nav .sb-header__list {
  gap: var(--sb-space-14);
}

.sb-header__utils .sb-header__list {
  gap: var(--sb-space-11);
}

/* ---------- CENTRE IDENTITY ------------------------------------------
 * Combination mark: monogram + wordmark. `flex: none` keeps it at its natural
 * width so the two clusters, not the brand, absorb the slack.
 */
.sb-header__brand {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--sb-space-6);
  white-space: nowrap;
  color: var(--sb-color-text-inverse);
}

/* The monogram ships as a square JPEG on a black ground. `screen` is what
 * dissolves that ground against Vienna Black — the approved artifact composites
 * it the same way. It is the one blend mode in the theme; it is not a style
 * anything else may borrow.
 */
.sb-header__monogram {
  width: var(--sb-icon-md);
  height: var(--sb-icon-md);
  object-fit: contain;
  mix-blend-mode: screen;
}

/* The brand must not pick up the metal link hover — the wordmark is the
 * constant in the header, and the system's identity colour is where it stays.
 */
.sb-header__brand:hover {
  color: var(--sb-color-text-inverse);
}

/* ---------- ITEMS AND STATES -----------------------------------------
 * Rest is the secondary inverse tone; hover to metal is inherited from
 * sb-foundation.css and is not restated. Active is a hairline underline at the
 * full inverse text colour — no fill, no pill, no colour block (contract 1).
 *
 * The transparent resting border reserves the underline's space, so becoming
 * current shifts nothing.
 */
.sb-header__link {
  display: inline-block;
  padding-block: var(--sb-space-4);
  border-bottom: var(--sb-border-hairline) solid transparent;
}

.sb-header__link.is-current {
  color: var(--sb-color-text-inverse);
  border-bottom-color: var(--sb-color-text-inverse);
}

/* A span is what an unresolved route renders as (see inc/navigation.php). It
 * must not pretend to be actionable.
 */
span.sb-header__link {
  cursor: default;
}

.sb-header__bag-count {
  font-variant-numeric: tabular-nums;
}

/* ---------- 44px TARGET FLOOR ----------------------------------------
 * The system's 44px minimum is a floor, not a suggestion — but the approved
 * header sets its items at 12px text with 8px padding (≈28px), and the active
 * underline sits on that box. Growing the boxes to 44px would move the approved
 * underline and change the approved geometry.
 *
 * So the hit area is extended instead of the box: a centred, invisible
 * pseudo-element gives every control a true 44px target while the rendered
 * design is untouched. Clusters are 20–30px apart horizontally, so these areas
 * never overlap each other.
 */
.sb-header__link,
.sb-header__brand,
.sb-header__drawer-toggle {
  position: relative;
}

.sb-header__link::after,
.sb-header__brand::after,
.sb-header__drawer-toggle::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 50%;
  height: var(--sb-control-height-md);
  transform: translateY(-50%);
}

/* ---------- DRAWER TOGGLE --------------------------------------------
 * Visibility belongs to sb-layout.css. This is geometry only.
 *
 * SB-IMP-003 renders it disabled: the drawer is SB-IMP-005 and does not exist
 * yet. It is styled at full strength rather than dimmed, because it is not
 * conceptually unavailable to the visitor — it is unbuilt, and a greyed control
 * would be a design statement the approved artifact does not make.
 */
/* The bars align to the page gutter, so the button starts there and its 44px
 * target extends inward. Centring the burger inside the button instead would
 * push the mark off the gutter by half the difference, and correcting that with
 * a negative margin would need an 11px value the spacing ladder does not have.
 */
.sb-header__drawer-toggle {
  align-items: center;
  justify-content: flex-start;
  min-width: var(--sb-control-height-md);
  min-height: var(--sb-control-height-md);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
}

/* Three hairlines, 22px wide. FLAG: the 5px inter-bar gap is the one value in
 * this component with no token behind it — the spacing ladder is 2px-based and
 * has no 5px step. It is taken from the approved mobile bar
 * (`.sb-burger{gap:5px}`) and is recorded in docs/TASK_QUEUE.md rather than
 * being quietly rounded to 4px or 6px, which would visibly alter the mark.
 */
.sb-header__burger {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: var(--sb-space-11);
}

.sb-header__burger i {
  display: block;
  height: var(--sb-border-hairline);
  background: var(--sb-color-text-inverse);
}

/* ---------- SKIP LINK ------------------------------------------------
 * Not a Design System component — it has no visual presence until focused, and
 * the frozen system contains no contract for it. Built from tokens only.
 */
.sb-skip-link {
  position: absolute;
  left: -9999px;
  z-index: var(--sb-layer-header);
  padding: var(--sb-space-4) var(--sb-space-8);
  background: var(--sb-color-bg-inverse);
  color: var(--sb-color-text-inverse);
  font-size: var(--sb-type-nav);
  letter-spacing: var(--sb-ls-ui);
  text-transform: uppercase;
}

.sb-skip-link:focus-visible {
  left: var(--sb-page-inline);
  top: var(--sb-space-4);
}

/* ---------- BEHAVIOURAL BOUNDARY -------------------------------------
 * The literals below mirror --sb-bp-nav (1040px) exactly, for the reason
 * sb-layout.css states: CSS media queries cannot consume custom properties.
 * They must be changed together with the token, never independently, and no
 * fourth boundary may be introduced here.
 *
 * Above the boundary the desktop nav lays out. `display` is set *only* here so
 * the frozen `display: none` below 1040px keeps winning.
 */
@media (min-width: 1040px) {
  .sb-header__nav { display: flex; }
}

/* Below it the contract reduces the right cluster to SEARCH · BAG. The left
 * cluster and the drawer toggle are already handled by sb-layout.css.
 *
 * The utility cluster stops growing here. Contract 1 says the wordmark "stays
 * centred" in the compact bar, which means it stays the bar's centre element —
 * not that it is centred on the viewport. Two approved artifacts render this
 * bar, `Saint Bones Mobile Navigation` state 01 and the homepage authority
 * `Saint Bones Mobile Homepage V4 Unified`, and both use plain
 * `space-between` with three non-growing children. Viewport-centring was
 * measured against that evidence and rejected: at the 390px reference width it
 * drives the wordmark 18.8px into the SEARCH · BAG cluster, because a 44px
 * toggle cannot balance a ~121px utility group. See docs/TASK_QUEUE.md
 * SB-IMP-003 for the note raised on that wording.
 */
@media (max-width: 1039px) {
  .sb-header__util--desktop { display: none; }

  .sb-header__utils { flex: 0 0 auto; }

  /* The compact bar is wordmark-only — neither approved mobile artifact
   * carries the monogram, and contract 1 names only the wordmark here.
   */
  .sb-header__monogram { display: none; }
}

/* 767px mirrors --sb-bp-grid, the boundary sb-foundation.css already uses to
 * compact .sb-nav-text to 10px/.16em and the wordmark to 13px. The approved
 * mobile bar tightens the utility gap to 14px and drops the parentheses from
 * the bag count at this size; both are carried here rather than invented.
 */
@media (max-width: 767px) {
  .sb-header__utils .sb-header__list { gap: var(--sb-space-7); }

  .sb-header__bag-paren { display: none; }
}

/* The compact reference is 390px wide. At the explicit 320px floor the
 * 18px gutters plus the desktop-sized flex gap exceed the available width by
 * 34px, despite each individual header item already using its smallest
 * approved type. Retain the same elements and tokens, but remove inter-item
 * gap and use the next fitting token gutter so there is no horizontal scroll
 * or overlap at the minimum supported viewport. */
@media (max-width: 359px) {
  .sb-header {
    gap: 0;
    padding-inline: var(--sb-space-5);
  }

  .sb-header__utils .sb-header__list { gap: 0; }
}
