﻿/* =========================================================
   HERO SECTION
   Ported from design/jewelry-hero-section.html. Every value below
   comes from assets/css/base/tokens.css  see BRAND-IDENTITY.md
   for the token reference.

   Scoping: every rule is anchored to .hero-wrap so generic class
   names (.sidebar, .headline, .portraitâ€¦) cannot leak into
   WordPress markup or plugin output. The global `*` reset and the
   `body` rule from the source file live in style.css instead.
   ========================================================= */

.hero-wrap, .hero-wrap * { box-sizing: border-box; margin: 0; padding: 0; }

.hero-wrap {
  position: relative;
  width: 100%;
  /* A bit taller than before (was clamp(460px,60vh,580px))  every
     .hero-slide fills this height exactly (position:absolute; inset:0
     below, under "slides"), so extra content (an admin-authored headline
     running 3 lines instead of 2, say) can't grow this container to fit
     it the way normal in-flow content would; it just overflows the fixed
     height instead. This floor gives real breathing room for that. */
  min-height: clamp(500px, 62vh, 620px);
  display: flex;
  /* Matches the video/poster's own light cream tone (not --fm-black)
     now that the hero text is dark-on-light (see .headline etc. below)
      the video's poster attribute (hero.php) paints almost instantly,
     but this is what would show through in the brief gap before that if
     it were ever slow, and a dark fallback behind now-dark text would be
     unreadable rather than just briefly plain. */
  background: var(--fm-surface-page);
  box-shadow: inset 0 -60px 80px -60px rgba(var(--fm-rgb-black), 0.45);
}

/* ---------------- sidebar ---------------- */
/* display:flex/column so .sidebar-title takes its own natural height and
   the list fills the rest (flex:1 below) instead of the list's old
   height:100% trick, which assumed it was the sidebar's only child and
   would now overflow past the title's own height. */
.hero-wrap .sidebar {
  position: relative;
  z-index: 3;
  width: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: #C9A236;
  box-shadow: 4px 0 30px rgba(var(--fm-rgb-black), 0.4);
}
.hero-wrap .sidebar-title {
  flex: 0 0 auto;
  padding: 20px 18px 14px;
  font-family: var(--fm-font-sans);
  font-size: var(--fm-text-12);
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #000000;
  border-bottom: 1px solid rgba(0, 0, 0, 0.25);
}
/* Rows are sized to their own (now-slim) padding rather than stretched to
   evenly fill the sidebar's height  with slim rows and a real category
   count this reliably fills most of the hero's height on its own; any
   sliver left under the last row just stays the sidebar's own gold fill,
   which was always there underneath the list anyway. */
.hero-wrap .sidebar ul { list-style: none; display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.hero-wrap .sidebar li { position: relative; flex: 0 0 auto; display: flex; }

.hero-wrap .cat-link {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 12px;
  padding: 7px 18px;
  font-family: var(--fm-font-sans);
  font-size: var(--fm-text-14);
  font-weight: 500;
  letter-spacing: 0.3px;
  color: #000000;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
  position: relative;
  transition: background var(--fm-duration-base) var(--fm-ease), padding-left var(--fm-duration-base) var(--fm-ease), color var(--fm-duration-base) var(--fm-ease);
}
.hero-wrap .cat-link::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 2px;
  background: #000000;
  transform: scaleY(0);
  transition: transform var(--fm-duration-base) var(--fm-ease);
}
/* Sized to just barely clear the icon itself (was a much bigger circle
   with a lot of dead space around a smaller glyph)  the circle now only
   reads as a shape at all once its dark hover fill kicks in below. */
.hero-wrap .cat-link .icon-wrap {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--fm-radius-circle);
  transition: background var(--fm-duration-base) var(--fm-ease);
}
.hero-wrap .cat-link .icon { width: 24px; height: 24px; flex-shrink: 0; stroke: #000000; fill: none; stroke-width: 1.3; transition: stroke var(--fm-duration-base) var(--fm-ease); }
.hero-wrap .cat-link .label { flex: 1; }
.hero-wrap .cat-link .chev { width: 14px; height: 14px; stroke: rgba(0, 0, 0, 0.7); fill: none; stroke-width: 1.6; opacity: 0.6; transition: transform var(--fm-duration-base) var(--fm-ease), opacity var(--fm-duration-base) var(--fm-ease); }
.hero-wrap li:hover .cat-link { background: rgba(0, 0, 0, 0.14); padding-left: 25px; color: var(--fm-white); }
.hero-wrap li:hover .cat-link::before { transform: scaleY(1); }
.hero-wrap li:hover .cat-link .icon-wrap { background: #1a1712; }
.hero-wrap li:hover .cat-link .icon { stroke: var(--fm-cream); }
.hero-wrap li:hover .cat-link .chev { transform: translateX(3px); opacity: 1; stroke: var(--fm-cream); }

/* ---------------- megamenu ---------------- */
.hero-wrap .megamenu {
  position: absolute;
  top: 0;
  left: 280px;
  width: 290px;
  background: var(--fm-surface);
  border-top: 2px solid var(--fm-gold);
  box-shadow: var(--fm-shadow-sidebar-mega);
  padding: 20px 20px 22px;
  opacity: 0;
  visibility: hidden;
  transform: translateX(-8px);
  transition: opacity var(--fm-duration-fast) var(--fm-ease), transform var(--fm-duration-fast) var(--fm-ease), visibility var(--fm-duration-fast);
  z-index: 4;
}
/* Scoped to the same 900px this sidebar collapses to icon-only at (see
   that @media block further down): below it the megamenu switches to
   position:fixed with its `top` set only by JS at tap-open time (the
   comment on that block explains why), never by this rule  a real mouse
   can still technically :hover a <li> on a narrowed desktop window even
   though that layout assumes touch/tap, and without this guard, hovering
   there opened the flyout with no `top` ever set, leaving it at this
   rule's implicit top:0 and pinning it to the very top of the screen
   instead of beside the sidebar. */
@media (min-width: 901px) {
  .hero-wrap li:hover .megamenu { opacity: 1; visibility: visible; transform: translateX(0); }
}
/* .sidebar's own z-index (3) makes it a stacking context, which caps
   EVERY descendant  including the open .megamenu flyout  at rank 3
   in the page's root stacking order, no matter how high the flyout's
   own z-index is set. The sticky header (.ph-sticky-wrap, header.css)
   sits at var(--fm-z-header) = 100, well above that cap, so the flyout
   was rendering underneath it. Promote just the open .sidebar's own
   rank above the header while a flyout is actually showing (hover, or
   .megamenu-open on tap/mobile)  not permanently, or the sidebar
   column would wrongly paint over the sticky header the rest of the
   time, e.g. while scrolling past the hero. */
.hero-wrap .sidebar:has(li:hover),
.hero-wrap .sidebar:has(li.megamenu-open) {
  z-index: calc(var(--fm-z-header) + 1);
}
/* Sidebar items near the bottom of the list (see assets/js/hero.js,
   attachMegamenuPositioning()) open their flyout upward instead of
   downward, so it doesn't spill past the bottom of the viewport. */
.hero-wrap li.megamenu-flip-up .megamenu { top: auto; bottom: 0; }

.hero-wrap .megamenu-title {
  font-family: var(--fm-font-serif);
  font-style: italic;
  font-size: var(--fm-text-14);
  font-weight: 600;
  color: var(--fm-ink);
  margin-bottom: 12px;
  padding-bottom: 11px;
  border-bottom: 1px solid var(--fm-divider-strong);
}
.hero-wrap .megamenu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.hero-wrap .megamenu-item {
  display: block;
  border-radius: var(--fm-radius-lg);
  overflow: hidden;
  border: 1px solid var(--fm-divider-card);
  text-decoration: none;
  color: inherit;
  transition: transform var(--fm-duration-base) var(--fm-ease), box-shadow var(--fm-duration-base) var(--fm-ease), border-color var(--fm-duration-base) var(--fm-ease);
}
.hero-wrap .megamenu-item:hover {
  transform: translateY(-3px);
  box-shadow: var(--fm-shadow-card-hover);
  border-color: var(--fm-gold-icon);
}
.hero-wrap .megamenu-thumb {
  /* Roughly matches each grid column's own width (~120px, from the
     290px-wide megamenu minus padding/gap), so a product photo crops
     close to square instead of the old 58px-tall sliver, which squashed
     wider shots (a pair of rings side by side, etc.) into an
     unrecognizable strip. */
  height: 104px;
  background: linear-gradient(135deg, var(--fm-grad-thumb-1) 0%, var(--fm-grad-thumb-2) 55%, var(--fm-grad-thumb-3) 100%);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.hero-wrap .megamenu-thumb svg { width: 30px; height: 30px; stroke: var(--fm-gold-deep); fill: none; stroke-width: 1.4; }
.hero-wrap .megamenu-thumb img { width: 100%; height: 100%; object-fit: cover; }
.hero-wrap .megamenu-item-label {
  font-family: var(--fm-font-sans); font-size: var(--fm-text-10); letter-spacing: 0.2px; color: var(--fm-ink-mute); text-align: center; padding: 8px 4px 9px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* "Shop <category>" button inside the megamenu  the only way to reach
   the category page once tablet/mobile turns the flyout into a tap-to-open
   modal (see .megamenu-open below), and a convenience on desktop too. */
.hero-wrap .megamenu-viewall {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
  padding: 11px 18px;
  border: 1px solid var(--fm-gold);
  border-radius: var(--fm-radius-lg);
  font-family: var(--fm-font-sans);
  font-size: var(--fm-text-11);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fm-gold-deep);
  transition: background var(--fm-duration-base) var(--fm-ease), color var(--fm-duration-base) var(--fm-ease);
}
.hero-wrap .megamenu-viewall:hover { background: #000000; border-color: #000000; color: #ffffff; }
.hero-wrap .megamenu-viewall .arrow { transition: transform var(--fm-duration-base) var(--fm-ease); }
.hero-wrap .megamenu-viewall:hover .arrow { transform: translateX(3px); }

/* Close (X) button for the tablet/mobile modal  hidden on desktop where
   the flyout just follows :hover. */
.hero-wrap .megamenu-close { display: none; }

/* Backdrop behind the tablet/mobile modal. Inert (and untoggled by JS)
   above the 900px breakpoint, so it never affects desktop. */
.hero-wrap .megamenu-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(var(--fm-rgb-black), 0.55);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fm-duration-base) var(--fm-ease), visibility var(--fm-duration-base);
  z-index: 15;
}
.hero-wrap .megamenu-backdrop.active { opacity: 1; visibility: visible; }

/* ---------------- background video ---------------- */
.hero-wrap .bg-video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
}
.hero-wrap .bg-video-overlay {
  /* Removed on purpose: the site no longer wants any dark scrim over the
     hero background video  see .hero-content's own text-shadow rules
     further down for how the eyebrow/subline/headline/button stay
     readable over it instead. Element kept (rather than removing it from
     template-parts/sections/hero.php) since it carries no other role now;
     deleting it here is enough. */
  display: none;
}

/* ---------------- slides ----------------
   .hero-slides is the flex item taking the row's remaining width (after
   the sidebar)  exactly what .hero-content + .portrait used to occupy
   directly, before slides existed. EVERY .hero-slide, active or not, is
   absolutely positioned to the same spot: none of them contributes to
   .hero-slides' own height, which is what keeps the hero a fixed height
   regardless of which slide (shorter copy, no portrait image, etc.) is
   currently showing  the height comes only from .hero-wrap's own
   min-height below (and its mobile-breakpoint override), never from a
   slide's content. */
.hero-wrap .hero-slides {
  position: relative;
  z-index: 2;
  flex: 1;
  min-width: 0;
}
.hero-wrap .hero-slide {
  position: absolute;
  inset: 0;
  display: flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fm-duration-slow) var(--fm-ease), visibility var(--fm-duration-slow);
  pointer-events: none;
}
.hero-wrap .hero-slide.is-active { opacity: 1; visibility: visible; pointer-events: auto; }

/* ---------------- hero content ---------------- */
.hero-wrap .hero-content {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 32px 48px;
  min-width: 0;
}
/* No dark scrim here on purpose: the actual hero video/poster (see
   template-parts/sections/hero.php) is a bright cream/gold abstract
   animation, not a moody dark one  a dark overlay would fight the light,
   editorial black-on-cream look below rather than support it. The copy
   stays readable through plain color contrast + a light halo shadow
   instead (each rule below), same idea as a magazine cover headline set
   directly over a light photograph. */
.hero-wrap .eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--fm-font-sans);
  /* Bigger, bolder and solid gold instead of a faint dark-at-55%-opacity
     blend  that low-opacity dark tone read as barely-there against the
     video's own bright cream/gold tones (which shift as it plays), where
     a solid, saturated color stays visible regardless of exactly how
     bright the frame behind it is at any given moment. */
  font-size: var(--fm-text-14);
  font-weight: 600;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--fm-gold-deep);
  margin-bottom: 16px;
}
.hero-wrap .subline {
  font-family: var(--fm-font-sans);
  font-size: var(--fm-text-16);
  font-weight: 400;
  letter-spacing: 0.2px;
  color: rgba(28, 23, 18, 0.8);
  margin-bottom: 18px;
}
.hero-wrap .headline {
  font-family: var(--fm-font-serif);
  font-size: var(--fm-text-display);
  font-weight: 700;
  text-transform: uppercase;
  /* Tighter than mixed-case type would use (was 1.16, briefly 1.22)
     all-caps has no descenders, so its lines can sit closer together
     without looking cramped, and doing so here matters more than usual:
     .hero-wrap has a fixed height (see its own min-height comment above)
     that an extra line from this wrapping onto 4 lines instead of 2-3 can
     blow straight through, shoving the button toward/past the bottom edge
     instead of the section just growing to fit it. Proportional negative
     tracking (em, not px) for the same "confident display serif" reason
     as before, scaling correctly across --fm-text-display's clamp(). */
  line-height: 1.15;
  color: #1c1712;
  letter-spacing: -0.01em;
  /* A light halo instead of a dark one  dark text needs the shadow to
     push the *background* away from it (a soft glow of the page's own
     light tone), the opposite of how the old near-white-on-dark-video
     version used a dark shadow to push the background away from light
     text. Keeps the letterforms crisp over the video's own motion/texture
     without needing the scrim above back. */
  text-shadow: 0 2px 18px rgba(250, 246, 238, 0.7);
  margin-bottom: 34px;
  max-width: 620px;
}
.hero-wrap .shop-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  width: fit-content;
  padding: 14px 32px;
  border: 1px solid rgba(28, 23, 18, 0.35);
  font-family: var(--fm-font-sans);
  font-size: var(--fm-text-13);
  font-weight: 500;
  letter-spacing: 0.4px;
  color: #1c1712;
  overflow: hidden;
  transition: color var(--fm-duration-slow) var(--fm-ease), border-color var(--fm-duration-slow) var(--fm-ease);
}
.hero-wrap .shop-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: #1c1712;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--fm-duration-slow) var(--fm-ease);
  z-index: -1;
}
.hero-wrap .shop-btn .arrow { transition: transform var(--fm-duration-slow) var(--fm-ease); }
.hero-wrap .shop-btn:hover { color: #faf6ee; border-color: #1c1712; }
.hero-wrap .shop-btn:hover::before { transform: scaleX(1); }
.hero-wrap .shop-btn:hover .arrow { transform: translateX(4px); }

/* ---------------- portrait ---------------- */
.hero-wrap .portrait {
  position: relative;
  z-index: 2;
  width: clamp(280px, 24vw - 20px, 420px);
  flex-shrink: 0;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.hero-wrap .portrait-placeholder {
  width: 100%;
  height: 100%;
  min-height: 400px;
  background: linear-gradient(150deg, var(--fm-grad-portrait-1) 0%, var(--fm-grad-portrait-2) 45%, var(--fm-grad-portrait-3) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(var(--fm-rgb-white), 0.85);
  font-size: var(--fm-text-13);
  text-align: center;
  padding: 20px;
}
.hero-wrap .portrait img {
  width: 100%; height: 100%; object-fit: contain; object-position: bottom center; display: block;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 14%);
  mask-image: linear-gradient(90deg, transparent 0%, black 14%);
}

/* ---------------- slide navigation ----------------
   Only rendered at all (see hero.php) when there's more than one slide,
   so a site with just the one slide never shows these. No dots/arrows
   just one slim progress segment per slide, spanning the full width of
   the hero. The active segment's fill animates 0%->100% over the same
   AUTO_ADVANCE_MS duration as the JS timer (assets/js/hero-slides.js
   sets that animation's duration inline so the two can never drift out
   of sync), giving a clear "time left until next slide" readout instead
   of a static position indicator. */
.hero-wrap .hero-slide-nav {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* Below .sidebar's z-index (3), not above it: at z-index 4 this used to
     outrank .sidebar as a whole in the stacking order (a child's z-index,
     like the tap-to-open .megamenu's own 4, only ever competes within its
     parent's local stacking context  it can't win against a sibling
     context ranked below its parent), so the bar rendered on top of the
     open category popover instead of behind it. 2 still clears
     .hero-slides/.bg-video-overlay (z-index 1-2, and this is later in the
     DOM so it wins that tie) without ever outranking the sidebar. */
  z-index: 2;
  display: flex;
  gap: 4px;
}
.hero-wrap .hero-slide-progress {
  flex: 1 1 0;
  height: 3px;
  background: rgba(var(--fm-rgb-white), 0.22);
  overflow: hidden;
}
.hero-wrap .hero-slide-progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--fm-gold);
  transform-origin: left center;
}
.hero-wrap .hero-slide-progress.is-complete .hero-slide-progress-fill { width: 100%; }
.hero-wrap .hero-slide-progress.is-active .hero-slide-progress-fill {
  width: 100%;
  animation-name: fm-hero-progress;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
@keyframes fm-hero-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@media (max-width: 900px) {
  .hero-wrap .portrait { display: none; }

  /* Tablet & mobile: keep the same side-by-side layout as desktop, but
     collapse the sidebar down to just its icons so the animated video
     and headline text keep the full-width treatment next to it. */
  .hero-wrap .sidebar { width: 64px; }
  .hero-wrap .sidebar-title { display: none; }
  .hero-wrap .cat-link { padding: 12px 0; justify-content: center; gap: 0; }
  .hero-wrap .cat-link .label,
  .hero-wrap .cat-link .chev { display: none; }
  /* Desktop's enlarged 56px/30px icon-wrap/icon would nearly touch the
     edges of this narrowed, icon-only column  scaled back down to fit it
     comfortably instead. */
  .hero-wrap .cat-link .icon-wrap { width: 46px; height: 46px; }
  .hero-wrap .cat-link .icon { width: 26px; height: 26px; }

  /* No hover here, so the flyout only opens on tap (assets/js/hero.js
     toggles .megamenu-open) instead of :hover  but it stays the same
     small popover as desktop, anchored beside the icon column, so the
     rest of the icons stay visible and tappable to switch category.
     position:fixed (not the desktop absolute-relative-to-<li> behavior)
      absolute scrolls along with the hero's own content, same as
     everything else in normal flow, so scrolling the page (or even just
     swiping inside the popover's own item grid, when the swipe gets read
     as a page scroll instead) dragged the whole popover up and off the
     top of the screen along with it. Fixed to the viewport instead, its
     `top` is set inline by assets/js/hero.js's positionMobileMenu()
     computed once at open time and immune to scrolling after that,
     unlike a value baked into this stylesheet could be. */
  .hero-wrap .megamenu { position: fixed; left: 64px; width: min(280px, 78vw); max-height: 80vh; overflow-y: auto; }
  .hero-wrap li.megamenu-open .megamenu { opacity: 1; visibility: visible; transform: translateX(0); }
  /* Locks the background from scrolling at all while the popover is open
     (assets/js/hero.js toggles this on <body>)  belt-and-braces on top of
     the fixed positioning above, so there's no way left for the page
     underneath to move out from under an open modal. */
  body.fm-hero-modal-open { overflow: hidden; }

  .hero-wrap .megamenu-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    margin-left: auto;
    margin-bottom: 8px;
    border: 1px solid var(--fm-divider-card);
    border-radius: var(--fm-radius-circle);
    background: none;
    font-size: 18px;
    line-height: 1;
    color: var(--fm-ink-mute);
    cursor: pointer;
  }

  /* Dims the WHOLE page (inset:0, no left cutout  a partial-width dim
     used to stop at the icon column, but that left an ugly undimmed
     stripe behind it, which looked like a rendering bug rather than a
     deliberate choice). The icon column still stays visible and
     clickable underneath the dim: .sidebar's z-index (3) is higher than
     this z-index (2), so it paints on top of the backdrop regardless of
     which one is later in the DOM  tapping another icon still switches
     category instead of just closing the current one, same as before. */
  .hero-wrap .megamenu-backdrop { z-index: 2; }
}
@media (max-width: 760px) {
  /* A fixed-ish (viewport-relative, not content-driven) height, same
     reasoning as the desktop clamp above  every .hero-slide is
     absolutely positioned now (see the "slides" section), so nothing
     here can fall back on a slide's own content to establish a height;
     it has to come from .hero-wrap itself at every breakpoint, or the
     hero would silently collapse to zero. Smaller than desktop's clamp
     since the portrait image is hidden below 900px and there's
     comfortably less content to fit. */
  .hero-wrap { min-height: clamp(320px, 55vh, 420px); }
  .hero-wrap .hero-content { padding: 28px 22px; }
  .hero-wrap .headline { font-size: clamp(24px, 7vw, 32px); max-width: 100%; }
  .hero-wrap .subline { font-size: var(--fm-text-16); }
  .hero-wrap .eyebrow { letter-spacing: 3px; }
}
@media (max-width: 380px) {
  .hero-wrap .megamenu { width: calc(100vw - 60px); }
}
