/* ==========================================================================
   Pro Auction — Header, navigation, mega-menu, footer (build order step 4)
   ========================================================================== */

/* --- Header --------------------------------------------------------------
   Sticky on scroll-up only, never on scroll-down (§3). */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  transition: transform var(--dur-micro) var(--ease-out);
}
.site-header[data-hidden="true"] { transform: translateY(-100%); }

/* Compact bar once scrolled: logo mark + both CTAs (§3). */
.site-header[data-compact="true"] { --header-pad: var(--s-2); }

/* Mobile-first header (§14).
   At 375px the logo, phone, toggle and BOTH CTAs cannot share one row, and
   §13 requires both CTAs visible at every breakpoint. So the bar wraps into
   two rows: identity and navigation on top, the two funnels beneath. Nothing
   is hidden, nothing is truncated. */
.site-header__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "brand phone toggle"
    "actions actions actions";
  align-items: center;
  gap: var(--s-2) var(--s-3);
  padding-block: var(--header-pad, var(--s-3));
  transition: padding-block var(--dur-micro) var(--ease-out);
}

.site-header__brand { grid-area: brand; display: flex; align-items: center;
                      min-height: 44px; }
.site-logo { display: block; height: auto; max-width: 150px; }
.site-logo--text {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  letter-spacing: -.01em;
  white-space: nowrap;
}

.site-nav { grid-area: toggle; justify-self: end; position: relative; }

.site-header__actions {
  grid-area: actions;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
/* Both CTAs share the second row evenly. At 375px each gets ~165px, so the
   font drops a step and the padding tightens to keep "Register to bid" and
   "Book a valuation" on a single line — wrapped button labels read as broken. */
.site-header__actions .btn {
  flex: 1 1 0;
  min-width: 0;
  padding-inline: var(--s-2);
  font-size: var(--fs-xs);
  white-space: nowrap;
}

/* Sign in — for people who already have an account, so it reads as a link
   rather than competing with the two conversion CTAs. */
.site-header__signin {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--s-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.site-header__signin:hover { color: var(--brand-deep); text-decoration: underline; }

/* Signed-in state. Both variants ship in the markup; JS reveals the right one
   because BidSpirit auth is client-side (see auctionforge-modal.js). */
.site-header__account,
.site-header__signout {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--s-2);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  background: none;
  border: 0;
  cursor: pointer;
}
.site-header__account { font-weight: var(--fw-semibold); }
.site-header__account:hover,
.site-header__signout:hover { color: var(--brand-deep); text-decoration: underline; }
.site-header__signout { color: var(--muted); }
[hidden] { display: none !important; }

/* At 320px the top row is logo + phone + sign-in + toggle, which ran 11px
   over. The logo gives up the space rather than the sign-in link — a
   returning bidder needs the way back in more than the wordmark needs to be
   full size, and the mark is still legible at 120px. */
@media (max-width: 400px) {
  .site-logo { max-width: 120px; }
  .site-header__signin { padding-inline: var(--s-1); }
}

/* Below 480px the two CTAs cannot share a row: half of 320px leaves ~124px of
   content box for a label that needs ~151px, so the text rendered outside the
   button rather than wrapping (white-space: nowrap) and the two collided.
   The document never scrolled, so the breakpoint sweep read this as clean —
   see fit.py, which compares scrollWidth to clientWidth instead.
   §13 requires both CTAs visible at every breakpoint, so neither can be
   dropped; they stack and each gets the full width. */
@media (max-width: 479px) {
  .site-header__actions { flex-direction: column; align-items: stretch; }
  .site-header__actions .btn { flex: 0 0 auto; font-size: var(--fs-sm); }
}

/* The phone number and Sign in live inside .site-header__actions, so the
   column above stacked them too: logo, phone, Sign in, then both buttons —
   five rows, ~200px of a phone screen before any content. Phone and Sign in
   share a row; the buttons sit side by side wherever both labels fit at
   their smaller size (from 360px — measured, see fit check), and only stack
   on the narrowest phones. Three rows instead of five. */
@media (max-width: 479px) {
  .site-header__actions { flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: var(--s-2); row-gap: var(--s-2); }
  .site-header__actions .site-header__phone { margin-right: auto; }
  .site-header__actions .btn { flex: 1 1 100%; order: 2; }
  /* Zero-height full-width item: forces the buttons onto the next line. */
  .site-header__actions::before { content: ""; flex-basis: 100%; height: 0; order: 1; }
}
@media (min-width: 360px) and (max-width: 479px) {
  .site-header__actions .btn { flex: 1 1 0; font-size: var(--fs-xs); padding-inline: var(--s-2); }
}

.site-header__phone {
  grid-area: phone;
  justify-self: end;
  order: -1;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  padding: var(--s-2);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* --- Primary nav ---------------------------------------------------------
   Mobile-first: the list is a disclosure panel until 1280px (§14). */
.site-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.site-nav__list > li > a {
  display: block;
  padding: var(--s-3) 0;
  /* Nav labels must not break across lines — "Sell With Us" wrapped and
     collided with the row beneath it on narrower desktop widths. */
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  min-height: 44px;
  display: flex;
  align-items: center;
}

/* --- Sub-menus -----------------------------------------------------------
   Adding children under Auctions rendered them as a bare <ul> stacked over
   the logo, because only top-level items were styled. Below the horizontal
   breakpoint they indent inside the disclosure panel; above it they become a
   dropdown on hover or focus. */
.site-nav__list .sub-menu {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--s-2) var(--s-4);
  display: flex;
  flex-direction: column;
}
.site-nav__list .sub-menu > li > a {
  display: flex;
  align-items: center;
  min-height: 40px;
  white-space: nowrap;
  font-size: var(--fs-sm);
  color: var(--muted);
  text-decoration: none;
}
.site-nav__list .sub-menu > li > a:hover { color: var(--ink); }

.site-nav__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: var(--s-2) var(--s-3);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--ink);
  cursor: pointer;
}

@media (max-width: 1279px) {
  /* The panel spans the full header, not just the toggle, so 6 items are
     comfortably tappable rather than crammed under a narrow trigger. */
  .site-nav__list {
    position: absolute;
    right: 0;
    top: calc(100% + var(--s-2));
    min-width: min(88vw, 20rem);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    padding: var(--s-2) var(--s-4);
    box-shadow: var(--shadow-overlay);
    z-index: var(--z-dropdown);
  }
  .site-nav__list > li + li { border-top: 1px solid var(--line); }
  .site-nav__toggle[aria-expanded="false"] + .site-nav__list { display: none; }
}

/* The two-row header holds until 1280px, where the toggle disappears and the
   nav becomes a horizontal bar. 1180 is where logo + six nav items + phone +
   both CTAs genuinely fit; at 1024 they overflowed by 148px.

   An earlier 640px breakpoint tried to fit logo + phone + both CTAs + toggle
   on one row. That worked while the logo was a text wordmark, but once the
   real 283px logo shipped it pushed the toggle 22px off-screen at 768px and
   the page scrolled sideways. Five items do not fit a tablet row; four do. */
@media (min-width: 640px) {
  .site-header__actions .btn { flex: 0 1 auto; padding-inline: var(--s-6);
                               font-size: var(--fs-sm); }
  .site-header__actions { justify-content: flex-end; }
  .site-logo { max-width: 200px; }
}

@media (min-width: 1280px) {
  .site-nav__toggle { display: none; }
  /* Nav takes its own column once it is a horizontal bar. */
  .site-header__inner {
    /* Equal side columns are what centre the nav — plain 1fr has
       min-width:auto, so the wider actions column pushed the nav off centre by
       up to 158px.
       But minmax(0, 1fr) alone forces both sides to the same width even when
       the actions genuinely need more: at 1440 the equal share was 433px
       against 493px of content, and the block overflowed its column leftwards
       until the phone number sat on top of "Contact".
       minmax(max-content, 1fr) keeps the two sides equal — and the nav exactly
       centred — whenever there is room, and lets the actions column claim what
       it needs when there is not. The nav drifts off centre instead of the
       header overlapping itself, which is the right thing to lose first. */
    grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr);
    grid-template-areas: "brand nav actions";
  }
  /* Nav centred between the logo and the actions. */
  .site-nav { grid-area: nav; justify-self: center; margin-inline: var(--s-6); }
  /* Undo the mobile "share the row evenly" rule. On the second row of the
     mobile header, flex:1 1 0 is right — each CTA gets half the viewport. Here
     the actions live in a minmax(0, 1fr) column that can shrink below its
     content, so a flex-basis of 0 sized the buttons to an equal share of a
     narrow column instead of to their labels, and the nowrap text spilled out
     of both boxes. Size to content and let the column be the thing that gives. */
  .site-header__actions { justify-self: end; }
  .site-header__actions .btn {
    flex: 0 0 auto;
    padding-inline: var(--s-4);
    font-size: var(--fs-sm);
  }
  .site-nav__list {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: var(--s-6);
    position: static;
    padding: 0;
    border: 0;
    box-shadow: none;
    background: transparent;
  }
  /* Dropdown once the nav is a horizontal bar. */
  .site-nav__list > li { position: relative; }
  .site-nav__list .sub-menu {
    position: absolute;
    top: 100%;
    left: 0;
    /* Bricks' 10px root makes 13rem only 130px — the same trap as the type
       scale. Sized through --rem so it is a real 13 x 16px. */
    min-width: calc(13 * var(--rem));
    white-space: nowrap;
    padding: var(--s-2) var(--s-3);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    box-shadow: var(--shadow-overlay);
    z-index: var(--z-dropdown);
    opacity: 0;
    visibility: hidden;
    transform: translateY(calc(var(--s-1) * -1));
    /* Closing waits before it fades. The parent items are only 40-60px wide
       and the menus up to 255px, so heading for the right of a menu cuts the
       corner outside both — and with no delay the menu had faded to nothing
       before the pointer arrived, while a 250ms overshoot past the edge lost
       it entirely. Getting back inside within the delay cancels the close. */
    --nav-close-delay: 400ms;
    transition: opacity var(--dur-micro) var(--ease-out) var(--nav-close-delay),
                transform var(--dur-micro) var(--ease-out) var(--nav-close-delay),
                visibility 0s linear calc(var(--nav-close-delay) + var(--dur-micro));
  }
  .site-nav__list:not([data-hover-intent]) > li:hover > .sub-menu,
  .site-nav__list > li:focus-within > .sub-menu,
  .site-nav__list > li.is-open > .sub-menu {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }
  /* ...but moving onto another top-level item switches menus at once, so two
     never sit on top of each other. */
  .site-nav__list:not([data-hover-intent]):has(> li:hover) > li:not(:hover):not(:focus-within) > .sub-menu {
    transition-delay: 0s;
  }
  /* With a mouse, site.js takes over the timing (data-hover-intent): it holds
     the menu itself and also stops a pass over the neighbouring label from
     swapping menus, which the delay above cannot — the Auctions menu reaches
     under Services, 24px away. So the CSS delay must not stack on top. */
  .site-nav__list[data-hover-intent] .sub-menu { --nav-close-delay: 0s; }

  /* Underline draw on nav links (§4.5). */
  .site-nav__list > li > a { position: relative; padding: var(--s-2) 0; }
  .site-nav__list > li > a::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 100%;
    background: var(--brand);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--dur-micro) var(--ease-out);
  }
  .site-nav__list > li > a:hover::after,
  .site-nav__list > li.current-menu-item > a::after { transform: scaleX(1); }
}

/* --- Mega-menu -----------------------------------------------------------
   The calendar is the marketing (§3): next 3 sales with thumbnail, date,
   location and status badge. */
.mega-menu {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--white);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-overlay);
  z-index: var(--z-dropdown);
  padding-block: var(--s-8);
}
.site-nav__item--has-mega:hover .mega-menu,
.site-nav__item--has-mega:focus-within .mega-menu { display: block; }
.mega-menu__grid { display: grid; gap: var(--s-4);
                   grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.mega-menu__footer { margin-top: var(--s-6); padding-top: var(--s-4);
                     border-top: 1px solid var(--line); }

@media (max-width: 1279px) {
  .mega-menu { position: static; display: block; box-shadow: none;
               border: 0; padding-block: var(--s-4); }
}

/* --- Main ---------------------------------------------------------------- */
.site-main { display: block; }

/* --- Footer -------------------------------------------------------------- */
.site-footer { background: var(--ink); color: var(--paper);
               padding-top: var(--s-16); }
.site-footer__inner {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  padding-bottom: var(--s-12);
}
.site-footer__heading {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--steel);
  margin: 0 0 var(--s-4);
}
.site-footer__logo { margin-bottom: var(--s-4); }
.site-footer__logo .site-logo { max-width: 180px; height: auto; }

.site-footer address { font-style: normal; line-height: var(--lh-body);
                       font-size: var(--fs-sm); }
/* Phone and email are the two things people tap in a footer, so they get
   real targets rather than inline text height (WCAG 2.2 SC 2.5.8). */
.site-footer address a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.site-footer__list { list-style: none; margin: 0; padding: 0;
                     display: flex; flex-direction: column; }
.site-footer__list a,
.site-footer address a { color: var(--paper); text-decoration: none;
                         font-size: var(--fs-sm); }
/* Stacked footer links render ~17px high and sit too close to tap reliably.
   WCAG 2.2 SC 2.5.8 wants 44px; on a phone this is also just usable. */
.site-footer__list a {
  display: flex;
  align-items: center;
  min-height: 44px;
}
.site-footer__list a:hover,
.site-footer address a:hover { text-decoration: underline; }
.site-footer__note { font-size: var(--fs-sm); opacity: .85; }

.site-footer__legal {
  border-top: 1px solid rgba(var(--paper-rgb), .15);
  padding-block: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-xs);
}
.site-footer__legal-list { list-style: none; margin: 0; padding: 0;
                           display: flex; flex-wrap: wrap; gap: 0 var(--s-4); }
.site-footer__legal-list a { color: var(--paper); text-decoration: none;
                             display: inline-flex; align-items: center;
                             min-height: 44px; }
.site-footer__legal-list a:hover { text-decoration: underline; }
.site-footer__copyright,
.site-footer__registration { margin: 0; opacity: .8; max-width: none; }

/* --- Page furniture ------------------------------------------------------ */
.page-header { padding-block: var(--s-12) var(--s-8); }
.page-header .breadcrumb { margin-bottom: var(--s-4); }
.page-header__title { margin: 0 0 var(--s-4); }
.page-header__standfirst { font-size: var(--fs-lg); color: var(--slate); }

/* Answer-first opening paragraph (§7.1) — 40-60 words, extractable. */
.answer-first {
  font-size: var(--fs-lg);
  line-height: 1.5;
  color: var(--ink);
  border-left: 2px solid var(--steel);
  padding-left: var(--s-6);
  margin-bottom: var(--s-8);
}

/* --- Auction announcement bar -------------------------------------------
   Above the sticky header, so it scrolls away and the header stays put.
   Brand blue for a newly published sale, ink with a pulsing live dot while
   a sale is running. Text first, buttons after; on a phone they wrap onto
   their own row. The close button keeps a 44px target in the corner. */
.sale-banner {
  background: var(--brand-deep);
  color: var(--white);
}
.sale-banner--live { background: var(--ink); }
.sale-banner[hidden] { display: none; }

.sale-banner__inner {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-6);
  padding-block: var(--s-2);
  padding-right: calc(44px + var(--s-2));
}

.sale-banner__text {
  flex: 1 1 calc(24 * var(--rem));
  min-width: 0;
  max-width: none; /* base.css caps paragraphs at a reading measure */
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-1) var(--s-3);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
.sale-banner__label {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  white-space: nowrap;
}
.sale-banner--live .sale-banner__label::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--live);
  animation: sale-banner-pulse 1.6s var(--ease-out) infinite;
}
@keyframes sale-banner-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--live) 70%, transparent); }
  70%  { box-shadow: 0 0 0 8px color-mix(in srgb, var(--live) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--live) 0%, transparent); }
}
/* Sale names run to 150 characters; two lines, then an ellipsis. */
.sale-banner__title {
  flex: 1 1 calc(16 * var(--rem));
  min-width: 0;
  color: inherit;
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.sale-banner__title:hover { text-decoration-thickness: 2px; }
.sale-banner__when {
  white-space: nowrap;
  opacity: .85;
  font-variant-numeric: tabular-nums lining-nums;
}

.sale-banner__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.sale-banner__actions .btn { padding-inline: var(--s-4); }
.sale-banner .btn--primary { background: var(--white); border-color: var(--white); color: var(--ink); }
.sale-banner .btn--primary:hover { background: var(--paper); border-color: var(--paper); color: var(--ink); }

.sale-banner__close {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  color: inherit;
  font-size: calc(1.5 * var(--rem));
  line-height: 1;
  cursor: pointer;
  opacity: .85;
}
.sale-banner__close:hover { opacity: 1; }

/* Phone: the text spans the row beside the close button and the buttons
   share the row below it equally. */
@media (max-width: 639px) {
  .sale-banner__close { top: var(--s-1); transform: none; }
  .sale-banner__text { flex-basis: 100%; }
  .sale-banner__actions { flex-basis: 100%; }
  .sale-banner__actions .btn { flex: 1 1 0; white-space: nowrap; }
}
/* Wrapped button labels read as broken; under 360px they stack instead. */
@media (max-width: 359px) {
  .sale-banner__actions .btn { flex-basis: 100%; }
}
