/* ==========================================================================
   Navigation — reference bar → glass pill, plus the full-screen red overlay.
   Mechanics: floating pill, dot-grid menu button, letter scramble on hover,
   oversized giant-item list scrubbed by pointer Y (js/menu.js — untouched by
   the re-skin), and a client-side piece search (js/search.js).
   All motion is disabled under prefers-reduced-motion.
   ========================================================================== */

/* ---- The pill bar --------------------------------------------------------
   THREE states now, where there used to be two:

   • AT REST on a light page (default): an opaque paper bar with a bottom
     hairline. Dark type.
   • AT REST over a dark hero (body[data-nav="over-dark"]): fully transparent,
     white type, white hairline — the reference's bar, sitting on the artwork
     rather than on a band of its own.
   • FLOATING (.is-floating, scrolled > 24px): the glass pill, inset 15px.
     Unchanged behaviour; js/shell.js toggles the class at 24px exactly as
     before, so no JS state machine was added.

   At-rest is the CSS default, so a no-JS visit still gets a working bar. */
:root { --dock-h: 72px; }
@media (max-width: 900px) { :root { --dock-h: 64px; } }

.pill-head {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  /* Explicit height = the reserved --dock-h, so the bar can never be taller
     than the space the page leaves for it (no hero overlap, ever). */
  height: var(--dock-h);
  padding: 0 clamp(18px, 3vw, 34px);
  box-sizing: border-box;
  background: var(--paper);
  border-bottom: var(--edge-dk);
  color: var(--on-light);
  border-radius: 0;
  pointer-events: none;            /* only children are clickable */
  transition: top .4s cubic-bezier(.645,.045,.355,1),
              left .4s cubic-bezier(.645,.045,.355,1),
              right .4s cubic-bezier(.645,.045,.355,1),
              padding .4s cubic-bezier(.645,.045,.355,1),
              border-radius .4s cubic-bezier(.645,.045,.355,1),
              color .4s cubic-bezier(.645,.045,.355,1),
              background-color .4s cubic-bezier(.645,.045,.355,1);
  animation: pill-in .7s cubic-bezier(.645,.045,.355,1) both;
}
.pill-head > * { pointer-events: auto; }
@keyframes pill-in { from { transform: translateY(-200%); } to { transform: translateY(0); } }

/* At rest over a dark hero: no surface at all. */
body[data-nav="over-dark"] .pill-head:not(.is-floating) {
  background: transparent;
  border-bottom: var(--edge);
  color: var(--on-dark);
}
/* Same treatment while the red overlay is open, on every page. Without this a
   light page keeps its opaque paper bar, which then sits as a white slab on
   top of the full-bleed red — the one state where the bar's own surface
   fights the thing it opened. The overlay is z-index 80 and the bar 90, so
   the bar stays visible and its white type reads 5.29:1 on --primary-deep. */
body.menu-locked .pill-head:not(.is-floating) {
  background: transparent;
  border-bottom-color: transparent;
  color: var(--on-dark);
}
/* ...and the CTA's outline goes white there too: a --primary border on the
   --primary-deep overlay is red-on-red, so the one outlined control in the
   bar would lose its box entirely on the one surface that is already red. */
body.menu-locked .pill-head:not(.is-floating) .pill-cta { border-color: var(--on-dark); }

/* Floating pill once scrolled — dark glass on every page, so the component
   the user already had is preserved rather than forked into a light twin.

   The ink share is 82%, not the old 55%. That mattered less when everything
   behind the pill was already #170000; now it scrolls over WHITE content, and
   at 55% the glass composited to ~#7C7D83, where white .72rem links land at
   4.13:1 and fail. At 82% it composites to ~#3C3C40 over paper (10.4:1) and
   simply reads darker over the hero. Still glass: 18% transparency + blur. */
.pill-head.is-floating {
  top: 15px; left: 15px; right: 15px;
  height: auto;
  padding: 12px 20px;
  background: color-mix(in srgb, #111219 82%, transparent);
  border-bottom: 0;
  color: var(--on-dark);
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
  border-radius: 10px;
}
/* No color-mix (pre-Safari 16.2 / Chrome 111): fall back to a flat translucent
   ink rather than losing the pill's surface entirely. */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .pill-head.is-floating { background: rgba(17, 18, 25, .85); }
}

/* Reserve the docked bar's height so content starts below it. :has covers
   the homepage's static header and chrome.js-injected ones alike; chrome.js
   also sets body.has-pill for browsers without :has. */
body:has(.pill-head) { padding-top: var(--dock-h); }
body.has-pill { padding-top: var(--dock-h); }
/* ...except when the bar is transparent over a dark hero, where reserving
   height would open a paper-coloured gap above the artwork. #hero carries
   the same --dock-h in its own padding-block-start, so the headline still
   clears the bar. */
body[data-nav="over-dark"]:has(.pill-head),
body[data-nav="over-dark"].has-pill { padding-top: 0; }

.pill-brand {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: .95rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: currentColor;
  text-decoration: none;
  white-space: nowrap;
  padding: 4px 6px;
  border-radius: 5px;
  position: relative;
}

/* Wordmark → monogram on narrow screens.
   The full wordmark is 250.6px at 375: twenty-one nowrap characters carrying
   .16em of tracking, which alone contributes ~51px. Because the line cannot
   wrap, its min-content width equals its full width, and min-width:auto stops
   flex-shrink from touching it — so the header's flex line measured 250.6 + 16
   gap + 80 utilities = 346.6 inside a 324px content box. justify-content:
   space-between cannot manufacture negative space, so the 22.6px overrun spilled
   rightward and put #dots-btn at 364.5 in a 360px viewport: a 44px tap target
   with its right edge clipped off the screen.

   Shrinking the type instead would need ~13.8px to fit, which is smaller than
   the 15.2px nav links it sits beside. The monogram is what the reference bar
   uses anyway, and it is the form the design sketch specified.

   420px, not the 900px breakpoint that hides .plink/.pill-cta/.pill-lang: with
   those gone the utilities are only 80px wide, so the full wordmark still fits
   comfortably from ~383px up. Swapping at 900 would drop the name on tablets
   that have ample room for it.

   The a11y name lives on the anchor's aria-label, so it stays "Heaven Furniture
   Mart" at every width — display:none would otherwise take the words out of the
   accessibility tree along with the pixels. */
.pill-brand .pb-mono { display: none; }
@media (max-width: 420px) {
  .pill-brand .pb-long { display: none; }
  .pill-brand .pb-mono { display: inline; }
}
.pill-nav { display: flex; align-items: center; gap: .35rem; }

.plink a {
  position: relative;
  display: inline-block;
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: currentColor;
  text-decoration: none;
  padding: 9px 11px;
  border-radius: 5px;
  transition: opacity .2s cubic-bezier(.645,.045,.355,1);
  opacity: .78;
}
.plink a::before {
  content: "";
  position: absolute; inset: 0;
  background: currentColor;
  opacity: 0;
  border-radius: 5px;
  transform: scale(.9);
  transition: opacity .2s cubic-bezier(.645,.045,.355,1), transform .2s cubic-bezier(.645,.045,.355,1);
}
.plink a:hover, .plink a:focus-visible { opacity: 1; }
.plink a:hover::before { opacity: .1; transform: scale(1); }

/* Current page: full-opacity label plus a red rule beneath it.
   The old skin coloured the label itself with --brass; at .72rem that is
   body-copy size, and red-on-dark only reaches 4.33:1. Keeping the label at
   the surface's own text colour and moving the signal into a rule passes
   contrast and matches the reference's own indicator. */
.plink a[aria-current="page"] { opacity: 1; }
.plink a[aria-current="page"]::after {
  content: "";
  position: absolute; left: 11px; right: 11px; bottom: 2px;
  height: 2px; background: var(--primary);
}

/* AR CTA — outlined at rest, filled on hover. The label is white/ink rather
   than red because .72rem red text fails 4.5:1 on both surfaces; the red
   lives in the 1.5px border, which only has to clear the 3:1 UI bar. */
.pill-cta {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-left: .6rem;
  padding: 9px 15px;
  border: 1.5px solid var(--primary);
  border-radius: 0;
  color: currentColor;
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background .2s cubic-bezier(.645,.045,.355,1), color .2s cubic-bezier(.645,.045,.355,1),
              border-color .2s cubic-bezier(.645,.045,.355,1);
}
.pill-cta:hover, .pill-cta:focus-visible {
  background: var(--primary-deep);
  border-color: var(--primary-deep);
  color: var(--primary-ink);
}
.pill-cta svg { width: 15px; height: 15px; }

/* ---- Right-hand utility cluster ------------------------------------------
   The reference's bar ends with small utility affordances. Search is real
   (js/search.js filters data/pieces.js); "EN" is an indicator, not a control
   — the site ships in one language, and a switcher that switches nothing is
   worse than none. ------------------------------------------------------- */
.pill-util {
  position: relative;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: none; border: 0; border-radius: 5px;
  color: currentColor; cursor: pointer;
}
.pill-util::before {
  content: "";
  position: absolute; inset: 0;
  background: currentColor; opacity: 0;
  border-radius: 5px; transform: scale(.9);
  transition: opacity .2s cubic-bezier(.645,.045,.355,1), transform .2s cubic-bezier(.645,.045,.355,1);
}
.pill-util:hover::before { opacity: .1; transform: scale(1); }
.pill-util svg { width: 17px; height: 17px; }
.pill-lang {
  font-family: var(--font-body);
  font-size: .68rem; font-weight: 700; letter-spacing: .1em;
  opacity: .7; padding-left: .3rem; white-space: nowrap;
}

/* ---- The 2x2 dot menu button --------------------------------------------- */
.dots-btn {
  position: relative;
  width: 34px; height: 34px;
  margin-left: .4rem;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  cursor: pointer;
  border-radius: 5px;
  color: currentColor;
}
.dots-btn::before {               /* hover pill, same as links */
  content: "";
  position: absolute; inset: 0;
  background: currentColor;
  opacity: 0;
  border-radius: 5px;
  transform: scale(.9);
  transition: opacity .2s cubic-bezier(.645,.045,.355,1), transform .2s cubic-bezier(.645,.045,.355,1);
}
.dots-btn:hover::before { opacity: .1; transform: scale(1); }
.dots-inner {
  position: relative;
  width: 13px; height: 13px;
  transition: transform .2s cubic-bezier(.645,.045,.355,1);
}
.dots-inner i {
  position: absolute;
  width: 5px; height: 5px;
  background: currentColor;
  border-radius: 1px;
  transition: transform .2s cubic-bezier(.645,.045,.355,1), background .2s;
}
.dots-inner i:nth-child(1) { top: 0;    left: 0; }
.dots-inner i:nth-child(2) { top: 0;    right: 0; }
.dots-inner i:nth-child(3) { bottom: 0; left: 0; }
.dots-inner i:nth-child(4) { bottom: 0; right: 0; }
.dots-btn:hover .dots-inner i:nth-child(1) { transform: translate3d(-25%, -25%, 0); }
.dots-btn:hover .dots-inner i:nth-child(2) { transform: translate3d(25%, -25%, 0); }
.dots-btn:hover .dots-inner i:nth-child(3) { transform: translate3d(-25%, 25%, 0); }
.dots-btn:hover .dots-inner i:nth-child(4) { transform: translate3d(25%, 25%, 0); }
/* Open: grid rotates 90deg and dots collapse to an X in the centre. The
   overlay is red underneath, so the dots go white regardless of which bar
   state they were in. */
.dots-btn[aria-expanded="true"] { color: var(--on-dark); }
.dots-btn[aria-expanded="true"] .dots-inner { transform: rotate(90deg); }
.dots-btn[aria-expanded="true"] .dots-inner i:nth-child(1) { transform: translate3d(4px, 4px, 0) rotate(45deg); }
.dots-btn[aria-expanded="true"] .dots-inner i:nth-child(2) { transform: translate3d(-4px, 4px, 0) rotate(-45deg); }
.dots-btn[aria-expanded="true"] .dots-inner i:nth-child(3) { transform: translate3d(4px, -4px, 0) rotate(-45deg); }
.dots-btn[aria-expanded="true"] .dots-inner i:nth-child(4) { transform: translate3d(-4px, -4px, 0) rotate(45deg); }

/* ---- Full-screen red overlay ---------------------------------------------
   --ovmenu-bg resolves to --primary-deep, not the bright --primary: the
   .ov-corner labels are .7rem at opacity .85, and white on #ED1C2E is only
   4.37:1. On #D41929 it is 5.29:1. */
.ovmenu {
  position: fixed;
  inset: 0;
  z-index: 80;                     /* below the pill bar so it stays visible */
  background: var(--ovmenu-bg);
  color: var(--on-dark);
  visibility: hidden;
  overflow: hidden;
  /* Slides up from below the viewport: slow, smooth, one continuous glide. */
  transform: translate3d(0, 100%, 0);
  transition: transform .6s cubic-bezier(.22, .61, .36, 1),
              visibility 0s linear .6s;
}
.ovmenu.-open {
  visibility: visible;
  transform: translate3d(0, 0, 0);
  transition: transform .6s cubic-bezier(.22, .61, .36, 1);
}
body.menu-locked { overflow: hidden; }

/* corner micro-labels, decoded by scramble on open */
.ov-corner {
  position: fixed;
  font-family: var(--font-body);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.7;
  opacity: 0;
  transition: opacity .5s ease .25s;
}
.ovmenu.-open .ov-corner { opacity: .85; }
.ov-tl { top: 102px;  left: 26px; }
.ov-tr { top: 102px;  right: 26px; text-align: right; }
.ov-bl { bottom: 26px; left: 26px; }
.ov-br { bottom: 26px; right: 26px; text-align: right; }
.ov-corner a { color: inherit; text-decoration-color: rgba(255, 255, 255, .45); }

/* the oversized giant-item list */
.ovlist-wrap {
  position: absolute;
  inset: 100px 0 0;
  display: flex;
  justify-content: center;
}
.ovlist {
  list-style: none;
  margin: 0; padding: 0;
  text-align: center;
  will-change: transform;
}
.ovlist li { line-height: .92; }
/* Extra vertical padding makes the list deliberately taller than the
   viewport even with few items, so pointer-scrubbing has range. */
.ovlist { padding-block: 4vh 10vh; }
.ovlist a {
  display: inline-block;
  text-decoration: none;
  padding: .5vh 2vw;
  font-family: var(--display);     /* was hardcoded 'Anton' — the one place
                                      in the codebase the token was bypassed */
  font-weight: 200;
  font-size: clamp(3.4rem, 16.5vh, 12.5rem);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--on-dark);
  transition: color .25s cubic-bezier(.645,.045,.355,1);
}
.ovlist a:hover, .ovlist a:focus-visible { color: var(--ink); }  /* 3.53:1 on
                                            #D41929 — display-size, clears 3:1 */
.ovlist .ovi { display: inline-block; will-change: transform; }

/* ---- Search overlay (js/search.js) ---------------------------------------
   Above the pill bar, because the bar would otherwise cover the input. */
.psearch {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column;
  padding: clamp(1.2rem, 5vh, 4rem) clamp(1.25rem, 4vw, 3rem);
  background: rgba(17, 18, 25, .96);
  color: var(--on-dark);
  visibility: hidden; opacity: 0;
  transition: opacity var(--dur) var(--ease), visibility 0s linear var(--dur);
}
@supports (backdrop-filter: blur(10px)) {
  .psearch { background: rgba(17, 18, 25, .88); backdrop-filter: blur(18px); }
}
.psearch.-open { visibility: visible; opacity: 1; transition: opacity var(--dur) var(--ease); }
.psearch-top {
  flex: none;
  display: flex; align-items: center; gap: 1rem;
  width: min(100%, 760px); margin-inline: auto;
  border-bottom: 1px solid rgba(255, 255, 255, .3);
}
.psearch input {
  flex: 1; min-width: 0;
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 0; border-radius: 0; color: var(--on-dark);
  font-family: var(--display); font-weight: 200;
  font-size: clamp(1.5rem, 5vw, 2.6rem);
  letter-spacing: .04em; text-transform: uppercase;
  padding: .4em 0;
}
.psearch input::-webkit-search-cancel-button { display: none; }
.psearch input::placeholder { color: rgba(255, 255, 255, .38); }
.psearch input:focus { outline: none; }
.psearch-top:focus-within { border-bottom-color: var(--primary); }
.psearch-close {
  flex: none; width: 44px; height: 44px;
  display: grid; place-items: center;
  background: none; border: 0; color: var(--on-dark); cursor: pointer;
}
.psearch-close svg { width: 22px; height: 22px; }
.psearch-count {
  flex: none;
  width: min(100%, 760px); margin: .9rem auto 0;
  font-size: var(--fs-eyebrow); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--on-dark-mute);
}
/* min-height:0 is what actually lets this scroll inside the flex column —
   without it a flex item refuses to shrink below its content height. */
.psearch-results {
  flex: 1; min-height: 0;
  list-style: none; margin: 1.2rem auto 0; padding: 0 0 2rem;
  width: min(100%, 760px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.psearch-results a {
  display: flex; align-items: center; gap: 1rem;
  padding: .7rem 0; text-decoration: none; color: var(--on-dark);
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.psearch-results img {
  flex: none; width: 56px; height: 56px; object-fit: contain;
  background: rgba(255, 255, 255, .06);
}
.psearch-results b {
  font-family: var(--display); font-weight: 300; font-size: 1.05rem;
  letter-spacing: .05em; text-transform: uppercase;
  transition: color var(--dur) var(--ease);
}
.psearch-results .ps-txt { min-width: 0; }
.psearch-results .ps-txt span {
  display: block; font-size: var(--fs-small); color: var(--on-dark-mute);
}
/* Both of these are 16.8px/300 red text on the dark panel, so they take
   --primary-lite (5.04:1), not --primary (4.28:1 — fails body copy). */
.psearch-results a:hover b, .psearch-results a:focus-visible b { color: var(--primary-lite); }
.psearch-results mark { background: none; color: var(--primary-lite); font: inherit; }
.psearch-empty { padding: 1.4rem 0; color: var(--on-dark-mute); }

/* mobile / short screens: items must fit, no scrubbing */
@media (max-width: 900px) {
  .pill-nav .plink, .pill-cta, .pill-lang { display: none; }
  /* The wrap clears .ov-tl, which is TWO lines of .7rem/1.7 — at the old
     92px it started at exactly the label's top edge and the giant type ran
     straight through the address. */
  .ovlist-wrap { inset: 148px 0 70px; overflow-y: auto; display: block; }
  .ovlist { padding: 1rem 0 3rem; }
  /* Sized against WIDTH, not height. 9.5vh on a 812px-tall phone resolves to
     ~77px, at which "COLLECTIONS" is ~506px wide and blows through a 375px
     viewport — clipped at both edges, with a horizontal scrollbar on the
     whole document. The longest label is 11 characters, and Jost 200 caps
     average ~0.66em including the .04em tracking, so 11 x 0.66em = 7.26em
     has to fit the ~96vw left after the item's 2vw side padding: 11.5vw is
     that limit with a little margin. */
  .ovlist a { font-size: clamp(1.9rem, 11.5vw, 5.5rem); }
  .ov-tr, .ov-bl { display: none; }
  .ov-tl { top: 92px; left: 20px; }
  .ov-br { right: 20px; bottom: 20px; }
}

/* ---- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .pill-head { animation: none; transition: none; }
  .ovmenu { transform: none !important; transition: opacity .2s linear, visibility 0s; opacity: 0; }
  .ovmenu.-open { opacity: 1; }
  .ovmenu.-open,
  .plink a::before, .dots-btn::before, .pill-util::before,
  .dots-inner, .dots-inner i,
  .ov-corner, .ovlist a { transition: none !important; }
  .ovlist { transform: none !important; }
  .ovlist-wrap { overflow-y: auto; }
}
