/* ==========================================================================
   KidSwaps — site header
   Every visual rule for .site-header lives in this file.
   Markup is authored in Webflow; nothing here creates or removes an element.

   DRAWER MECHANISM: CSS :target. The hamburger links to #header-drawer,
   the close button and the scrim link to #. No JavaScript in this path —
   if this file 404s, every link is still on the page as ordinary markup.

   DO NOT put transform, filter or will-change on .site-header. It is
   position:sticky, and any of those would make it the containing block
   for fixed children, which breaks the scrim.
   ========================================================================== */

.site-header {
  --hdr-ink:          #1E1A19;
  --hdr-muted:        #75736E;
  --hdr-cream:        #EDECE0;
  --hdr-line:         #C9C7BC;
  --hdr-coral:        #E54F25;
  --hdr-coral-hover:  #B23D22;

  --hdr-main-h:       72px;
  --hdr-main-h-small: 56px;
  --hdr-util-h:       36px;
  --hdr-drawer-w:     284px;
  --hdr-pad:          24px;

  /* THE CART ICON. A classic shopping cart — handle, tapered basket, two
     wheels — REPLACING the shipping mailer that shipped at S228. The mailer
     was rejected on the render: with a flap line and a label rectangle it
     reads as a washing machine, and five drawn candidates failed the same
     way. Drawn as a mask so the Designer needs no Embed and no second
     element, and so background-color:currentColor carries the colour. */
  --hdr-cart-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.6 3.8h1.9l2 10.8h9.9l2-7.2H6.2'/%3E%3Ccircle cx='9.7' cy='18.6' r='1.4'/%3E%3Ccircle cx='15.6' cy='18.6' r='1.4'/%3E%3C/svg%3E");

  position: sticky;
  top: 0;
  z-index: 1000;
  width: 100%;
  background: var(--hdr-cream);
}

/* --------------------------------------------------------------------------
   ROWS AND CONTAINERS
   -------------------------------------------------------------------------- */

.header-utility-row,
.header-main-row {
  position: relative;
  z-index: 960;                     /* load-bearing: the scrim is a CHILD of
                                       .site-header at z-index 900, so without a
                                       higher z-index here it paints OVER the logo
                                       and the hamburger whenever the drawer opens */
  width: 100%;
  border-bottom: 1px solid var(--hdr-line);
}

.header-utility-row {
  overflow: hidden;                 /* load-bearing: the shrink collapses max-height */
  max-height: var(--hdr-util-h);
  transition: max-height .22s ease, opacity .18s ease;
}

.header-utility-container,
.header-main-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--hdr-pad);
}

.header-utility-container { min-height: var(--hdr-util-h); }

.header-main-container {
  min-height: var(--hdr-main-h);
  gap: 16px;
  transition: min-height .22s ease;
}

/* --------------------------------------------------------------------------
   UTILITY ROW
   -------------------------------------------------------------------------- */

.header-utility-nav {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-left: -8px;                /* pulls the first label onto the logo's edge */
}

.header-utility-account {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 20px;
  flex-shrink: 0;
}

.header-utility-link {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 12px;
  line-height: 20px;
  color: var(--hdr-muted);
  text-decoration: none;
  padding: 6px 8px;
  flex-shrink: 0;                   /* stops "Log Out" wrapping to two lines */
  transition: color .15s ease;
}

.header-utility-link:hover { color: var(--hdr-ink); }

.header-utility-social {
  display: flex;
  align-items: center;
  color: var(--hdr-muted);          /* the SVG is stroke:currentColor */
  text-decoration: none;
  padding: 4px;
  transition: color .15s ease;
}

.header-utility-social:hover { color: var(--hdr-coral); }
.header-utility-social svg   { display: block; }

/* --------------------------------------------------------------------------
   MAIN ROW — LOGO, NAV, ACTIONS
   -------------------------------------------------------------------------- */

/* THE LOGO SWAP. A single Y-axis flip on hover — the logo turns front to back
   and comes round to front again, which is the product's own gesture. Desktop
   only by nature, since a phone has no hover state. The perspective lives on
   the link and the rotation on the logo, so the box never moves and nothing
   around it reflows. Reduced motion kills it via the block at the foot. */
.header-logo-link {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  perspective: 700px;
}

.header-logo {
  display: block;
  transform-style: preserve-3d;
  backface-visibility: visible;
  transition: transform .75s cubic-bezier(.45, .05, .25, 1);
}

.header-logo-link:hover .header-logo { transform: rotateY(360deg); }

/* THE TAP HALF. A phone has no hover, so :active is the only way the gesture
   exists there at all. Same value, same curve, no second animation. */
.header-logo-link:active .header-logo { transform: rotateY(360deg); }

.header-nav {
  display: flex;
  align-items: center;
  gap: 28px;
}

.header-nav-link {
  position: relative;               /* the underline is ::after on this element */
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 14px;
  color: var(--hdr-ink);
  text-decoration: none;
  padding: 8px 0;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Hover underline, and the current-page indicator. Both are the same mark:
   a coral rule that wipes in from the left. TRANSFORM, NOT A BORDER —
   a border appearing on hover would shift the whole row by 2px. */
.header-nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--hdr-coral);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .18s ease;
}

.header-nav-link:hover::after,
.header-nav-link:focus-visible::after { transform: scaleX(1); }

/* w--current is Webflow's own class on a link pointing at the current page.
   Nothing to build and nothing to maintain — it follows the page. */
.header-nav-link.w--current::after { transform: scaleX(1); }
.header-nav-link.w--current        { color: var(--hdr-ink); }

.header-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}

/* CART AND JOIN NO LONGER SHARE A SHAPE, AND THAT IS DELIBERATE.
   They are still a conditional pair — only one ever renders live — but the
   cart is now a 44px icon at EVERY width and Join is still a coral pill, so
   the right-hand slot does change size between a logged-out and a logged-in
   visitor. HER RULING. The comment that used to sit here said the opposite;
   it was true until this commit and is not being left behind to argue with
   a future session. */
.header-join-button {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 14px;
  text-decoration: none;
  border-radius: 40px;
  padding: 12px 22px;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

/* THE CART IS AN ICON AT BOTH WIDTHS — hoisted out of the 767 block, which
   held these exact declarations until this commit. One control instead of two
   that drift.

   font-size:0 COLLAPSES THE LABEL, IT DOES NOT REMOVE IT. The word "Cart"
   stays in the DOM, so the link keeps its accessible name on every page.
   browse-tool.js sets an aria-label on /browse, /clothing and /toys; nothing
   sets one anywhere else, and this text is the only name a screen reader has
   there. DO NOT DELETE THE LABEL ELEMENT IN THE DESIGNER.

   position:relative is load-bearing — the count badge is absolutely
   positioned against this box. */
.header-cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: none;
  border-radius: 0;
  font-size: 0;
  line-height: 0;
  color: var(--hdr-ink);
  text-decoration: none;
  flex-shrink: 0;
  transition: color .15s ease;
}

.header-cart-link::before {
  content: "";
  display: block;
  width: 22px;
  height: 22px;
  background-color: currentColor;
  -webkit-mask: var(--hdr-cart-icon) center / contain no-repeat;
          mask: var(--hdr-cart-icon) center / contain no-repeat;
  transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}

.header-cart-link:hover,
.header-cart-link:active { color: var(--hdr-coral); }

/* THE LIFT AND TILT ARE ON THE ICON, NEVER ON THE LINK. A transform on the
   link would carry the count badge with it, and a tilted numeral reads as a
   fault. The cart tips as though it is rolling; the number stays upright. */
.header-cart-link:hover::before,
.header-cart-link:focus-visible::before {
  transform: translateY(-2px) rotate(-8deg);
}

/* THE COUNT BADGE.
   The element is created and shown by browse-tool.js, which injects its own
   CSS at ONE class. Every rule here is written at TWO classes, so it wins on
   SPECIFICITY and never on source order — the injected block is appended to
   <head> at runtime and would beat a one-class rule of ours every time.

   NO display DECLARATION HERE, ON PURPOSE. browse-tool.js flips the badge
   between none and inline-flex as the count crosses zero, and it does that
   with an inline style, which beats any stylesheet rule. Writing display
   here would be inert at best and would read as the control it is not.
   EMPTY THEREFORE SHOWS NO BADGE — a permanent coral dot reading 0 on every
   page reads as "you have something". Claude's call, one line to reverse.

   font-size IS SET EXPLICITLY because the parent is font-size:0. The number
   renders full size today by some mechanism nobody has read; this stops the
   badge depending on it.

   THE BADGE EXISTS ONLY ON /browse, /clothing AND /toys. Everywhere else
   these rules match nothing — that is the known gap, not a fault here. */
.header-cart-link .ks-cart-badge {
  position: absolute;
  top: 5px;
  right: 4px;
  left: auto;
  bottom: auto;
  margin: 0;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  border-radius: 40px;
  background: var(--hdr-coral);
  color: #FFFFFF;
  font-family: Quicksand, sans-serif;
  font-weight: 600;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0;
  text-align: center;
  pointer-events: none;              /* never eats the tap meant for the link */
  box-shadow: 0 0 0 2px var(--hdr-cream);   /* separates it from the drawing */
  transform-origin: 60% 40%;
  animation: ks-hdr-badge-pop .34s cubic-bezier(.34, 1.56, .64, 1) both;
}

/* THE FIRST-ADD POP, AND ONLY THE FIRST. An animation restarts when an
   element goes from display:none to shown, so the badge pops as it appears
   at 0 -> 1. It does NOT re-fire on 1 -> 2, because updateBagCount only
   rewrites textContent and a CSS animation cannot restart on a text change.
   A pop on EVERY add is a browse-tool.js change, i.e. a x3 pin bump across
   three pages, and is deliberately not in this commit.

   A KEYFRAMES NAME IS GLOBAL TO THE PAGE — it is not namespaced by any
   selector, and this file is site-wide. ks-hdr- prefix, always. */
@keyframes ks-hdr-badge-pop {
  from { transform: scale(.4); opacity: 0; }
  to   { transform: scale(1);  opacity: 1; }
}

.header-join-button {
  color: #FFFFFF;
  background: var(--hdr-coral);
  border: 1px solid var(--hdr-coral);
}

.header-join-button:hover {
  background: var(--hdr-coral-hover);
  border-color: var(--hdr-coral-hover);
}

/* --------------------------------------------------------------------------
   HAMBURGER — off above 767px, see the breakpoint block
   -------------------------------------------------------------------------- */

.header-menu-button {
  display: none;                    /* the breakpoint turns it on */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  flex-shrink: 0;
  text-decoration: none;
}

.header-menu-bar {
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: var(--hdr-ink);
  transition: transform .22s ease, opacity .14s ease;
}

/* The morph. The drawer opens BELOW the header rather than over it, which is
   what keeps this control visible and lets one button both open and close.

   TWO SELECTORS ON PURPOSE, EVERYWHERE THE DRAWER OPENS:
     .drawer-open  — set by header.js, the normal path
     :target       — the no-script fallback
   WEBFLOW'S OWN SCRIPT INTERCEPTS IN-PAGE ANCHOR CLICKS and sets the hash
   through the history API, which does NOT re-evaluate :target. So :target
   fires on a real navigation and never on a click. Proven on the live page.
   Do not delete either selector: the class is what works, the target is what
   keeps the menu reachable if header.js never arrives. */
.site-header:has(#header-drawer:target) .header-menu-bar:nth-child(1),
.site-header.drawer-open .header-menu-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.site-header:has(#header-drawer:target) .header-menu-bar:nth-child(2),
.site-header.drawer-open .header-menu-bar:nth-child(2) {
  opacity: 0;
}
.site-header:has(#header-drawer:target) .header-menu-bar:nth-child(3),
.site-header.drawer-open .header-menu-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* --------------------------------------------------------------------------
   SCRIM AND DRAWER
   -------------------------------------------------------------------------- */

.header-scrim {
  display: none;                    /* the breakpoint turns it on */
  position: fixed;
  inset: 0;
  background: rgba(30, 26, 25, .45);
  opacity: 0;
  visibility: hidden;
  z-index: 900;
  transition: opacity .22s ease, visibility .22s ease;
}

.site-header:has(#header-drawer:target) .header-scrim,
.site-header.drawer-open .header-scrim {
  opacity: 1;
  visibility: visible;
}

.header-drawer {
  display: none;                    /* the breakpoint turns it on */
  position: absolute;
  top: 100%;                        /* directly under the header, not over it */
  left: 0;
  width: var(--hdr-drawer-w);
  max-width: 86vw;
  max-height: calc(100dvh - var(--hdr-main-h));
  overflow-y: auto;
  overscroll-behavior: contain;     /* the page behind must not scroll with it */
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;      /* no long-press link preview on iOS */
  -webkit-user-select: none;
  user-select: none;                /* a drag on a label scrolls, never selects */
  z-index: 950;
  background: var(--hdr-cream);
  border-right: 1px solid var(--hdr-line);
  box-shadow: 0 12px 28px rgba(30, 26, 25, .14);
  padding: 18px 22px 28px;
  transform: translateX(-100%);     /* opens from the LEFT, her ruling */
  transition: transform .26s ease;
}

#header-drawer:target,
.site-header.drawer-open .header-drawer { transform: translateX(0); }

/* The X. Drawn in CSS so the element can stay empty in Webflow. */
.header-drawer-close {
  position: relative;
  display: block;
  width: 32px;
  height: 32px;
  margin: 0 0 8px auto;
  text-decoration: none;
}

.header-drawer-close::before,
.header-drawer-close::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 15px;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: var(--hdr-ink);
}

.header-drawer-close::before { transform: rotate(45deg); }
.header-drawer-close::after  { transform: rotate(-45deg); }

/* Drawer groups */
.header-drawer-nav,
.header-drawer-utility,
.header-drawer-social,
.header-drawer-legal {
  display: flex;
  flex-direction: column;
  align-items: flex-start;          /* load-bearing: without this every link
                                       stretches the full drawer width and there
                                       is nowhere neutral to start a scroll */
}

.header-drawer-nav     { gap: 2px; padding-bottom: 14px; }

.header-drawer-utility { gap: 2px; padding: 14px 0;
                         border-top: 1px solid var(--hdr-line); }

.header-drawer-social  { padding: 4px 0 14px; }

.header-drawer-legal   { flex-direction: row; gap: 16px; padding-top: 14px;
                         border-top: 1px solid var(--hdr-line); }

.header-drawer-link {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 17px;
  line-height: 20px;
  color: var(--hdr-ink);
  text-decoration: none;
  padding: 11px 0;                  /* keeps the tap target at 44px */
}

.header-drawer-sublink {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 18px;
  color: var(--hdr-muted);
  text-decoration: none;
  padding: 10px 0;
}

.header-drawer-social-link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  color: var(--hdr-muted);
  text-decoration: none;
  padding: 8px 0;
}

.header-drawer-social-link svg { display: block; }

.header-drawer-legal-link {
  font-family: Quicksand, sans-serif;
  font-weight: 500;
  font-size: 12px;
  line-height: 16px;
  color: var(--hdr-muted);
  text-decoration: none;
  padding: 4px 0;
}

.header-drawer-link:hover,
.header-drawer-sublink:hover,
.header-drawer-legal-link:hover,
.header-drawer-social-link:hover { color: var(--hdr-coral); }

/* --------------------------------------------------------------------------
   SHRINK ON SCROLL
   Driven by an .is-scrolled class added to .site-header by a small script.
   If that script never runs the header simply does not shrink — the failure
   lands on "no animation", never on "no navigation".
   -------------------------------------------------------------------------- */

.site-header.is-scrolled .header-utility-row {
  max-height: 0;
  opacity: 0;
  border-bottom-color: transparent;
}

.site-header.is-scrolled .header-main-container {
  min-height: var(--hdr-main-h-small);
}

.site-header.is-scrolled .header-drawer {
  max-height: calc(100dvh - var(--hdr-main-h-small));
}

/* --------------------------------------------------------------------------
   BREAKPOINT — phone
   Hiding here is display:none, so the elements STAY in the published HTML.
   That is a different thing from hiding an element in the Designer, which
   strips it out of the published page entirely.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .site-header { --hdr-main-h: 60px; --hdr-pad: 16px; }

  .header-utility-row { display: none; }
  .header-nav         { display: none; }

  .header-menu-button { display: flex; }
  .header-scrim       { display: block; }
  .header-drawer      { display: flex; flex-direction: column; }

  .header-main-container { justify-content: space-between; gap: 10px; }

  /* the right-hand slot only ever holds one of Cart or Join */
  .header-join-button { padding: 10px 18px; font-size: 13px; }

  /* THE CART RULES THAT SAT HERE ARE GONE, NOT DUPLICATED. They were hoisted
     into the base rule so the icon renders at every width; leaving a copy
     behind is how two halves of one control start disagreeing. */

  /* THE SCROLL HALF OF THE LOGO FLIP, AND THE 767 SCOPE IS LOAD-BEARING.
     Unscoped, .is-scrolled parks the logo at 360deg and :hover sets the same
     value, so THE DESKTOP FLIP WOULD SILENTLY DIE BELOW THE FOLD with
     nothing erroring. It sits inside this block, after the base :hover and
     :active rules, so it wins on the phone by source order at equal
     specificity and cannot reach the desktop at all.

     NAMED COST, HERS: 360deg equals 0deg, so scrolling back to the top turns
     the logo backwards. */
  .site-header.is-scrolled .header-logo { transform: rotateY(360deg); }
}

/* --------------------------------------------------------------------------
   ACCESSIBILITY
   -------------------------------------------------------------------------- */

.site-header a:focus-visible {
  outline: 2px solid var(--hdr-coral);
  outline-offset: 3px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .site-header *,
  .site-header *::before,
  .site-header *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}
