/* ==========================================================================
   elios-essential.css  —  DO NOT EDIT site.css TO FIX THESE
   --------------------------------------------------------------------------
   Loaded AFTER site.css on every page, so these rules always win.

   WHY THIS FILE EXISTS
   --------------------
   The homepage product rails (.home-row-track) and the mobile header fit
   (.header-social) lived inside site.css. That file is hand-edited, and on
   2026-11-05 (and again earlier the same day) both rule sets were removed
   during routine edits. With .home-row-track gone, every product card in a
   rail falls back to display:block and stacks vertically, turning a ~6,000px
   mobile homepage into ~12,595px. It is invisible on desktop.

   site.css is now free to be edited without ever touching these rules again.
   Only add things here — never remove.

   Guarded by: /root/css_guard.sh  (cron every 30 min)
   ========================================================================== */

/* ---- Homepage rails: horizontal scroll + snap. NOTHING in site.css needed. */
.home-row { padding-top: 34px; padding-bottom: 8px; }

.home-row-track {
  display: grid !important;
  grid-auto-flow: column !important;
  grid-auto-columns: minmax(215px, 1fr) !important;
  gap: 16px;
  overflow-x: auto !important;
  overflow-y: hidden;
  padding: 4px 0 18px;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.home-row-item { scroll-snap-align: start; }
.home-row-item[hidden] { display: none !important; }

@media (max-width: 700px) {
  .home-row-track { grid-auto-columns: 78% !important; gap: 12px; }
}

/* ---- Device tabs above each rail */
.row-tabs { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.row-tab {
  appearance: none; background: none; border: 0;
  padding: 6px 11px; font: inherit; font-size: 11.5px;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-muted); cursor: pointer; border-radius: 999px;
  transition: color 160ms, background 160ms;
}
.row-tab:hover { color: var(--text); }
.row-tab.is-active { color: var(--text); background: var(--bg-alt); font-weight: 600; }
.row-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- Mobile header: 5 icons + logo do not fit in 390px. The TikTok icon
   lives in the hamburger drawer and the footer, so it yields here. */
@media (max-width: 480px) {
  .header-social { display: none !important; }
}

/* ---- Wrist-size field: the one input that blocks add-to-cart on Fitbit and
   Garmin. Thumb-sized, 16px text so iOS does not auto-zoom on focus. */
.wrist-input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  height: 52px; padding: 0 14px;
  font-size: 16px; font-weight: 600;
  border-radius: 10px; border: 1.5px solid var(--border);
  background: #fff; text-align: center; letter-spacing: .02em;
  -moz-appearance: textfield;
}
.wrist-input::-webkit-outer-spin-button,
.wrist-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.wrist-input:focus {
  outline: none; border-color: var(--text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--text) 12%, transparent);
}
.wrist-input-row { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.wrist-unit {
  flex: 0 0 auto; font-size: 13px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-muted); min-width: 26px;
}

/* ---- Trust badges: 2 per row on phones so the block stays short. */
.trust-badge-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.trust-badge-body strong { font-size: 12.5px; line-height: 1.3; }
.trust-badge-body em {
  font-style: normal; font-size: 11.5px; line-height: 1.4;
  color: var(--text-muted);
}
@media (max-width: 480px) {
  .trust-badges {
    grid-template-columns: 1fr 1fr !important;
    gap: 10px !important;
  }
  .trust-badge { align-items: flex-start !important; }
}
/* ==========================================================================
   HERITAGE ("EDITORIAL") RAIL — same card size as every other row
   ==========================================================================
   The homepage rails use:
       grid-auto-columns: minmax(215px, 1fr)
   On a rail with 8 products the 1fr never bites (the row overflows and every
   column sits at its 215px minimum). But the Heritage row only has TWO
   products, so each 1fr column stretched to fill the whole 1216px track —
   600px per card, 2.8x larger than every other product on the page. It read as
   a deliberate "editorial" hero, but it was just the grid filling spare space.

   Pinning this rail to a fixed 215px column keeps the card identical to the
   rest of the homepage. The rail still scrolls sideways when more Heritage
   products are added.
   ========================================================================== */

.home-row[data-row="heritage"] .home-row-track {
  grid-auto-columns: 215px !important;
}

/* On mobile the other rails use 78% so one card sits comfortably in view.
   Match that instead of letting a 215px card look tiny on a phone. */
@media (max-width: 700px) {
  .home-row[data-row="heritage"] .home-row-track {
    grid-auto-columns: 78% !important;
  }
}
/* ==========================================================================
   WELCOME MESSAGE — arrival animation + typing indicator
   Appended to elios-essential.css (loads after site.css, so these win).
   Everything is opt-out under prefers-reduced-motion.
   ========================================================================== */

/* A message sliding in, as if it just arrived. */
@keyframes eliosMsgIn {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.chat-msg.is-new {
  animation: eliosMsgIn 320ms cubic-bezier(.22, 1, .36, 1) both;
}

/* Typing indicator: three dots in an admin bubble. */
.chat-typing {
  align-self: flex-start;
  background: var(--bg-alt, #f2f2f2);
  border-radius: 14px;
  border-bottom-left-radius: 4px;
  padding: 12px 14px;
  display: inline-flex;
  gap: 5px;
  align-items: center;
}
.chat-typing span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-muted, #8a8780);
  opacity: .45;
  animation: eliosTyping 1.25s infinite ease-in-out;
}
.chat-typing span:nth-child(2) { animation-delay: .18s; }
.chat-typing span:nth-child(3) { animation-delay: .36s; }

@keyframes eliosTyping {
  0%, 60%, 100% { transform: translateY(0);    opacity: .35; }
  30%           { transform: translateY(-4px); opacity: .95; }
}

/* The launcher pulses once when a message arrives while the panel is closed. */
@keyframes eliosFabPulse {
  0%   { box-shadow: 0 0 0 0 rgba(225, 29, 72, .55); }
  70%  { box-shadow: 0 0 0 14px rgba(225, 29, 72, 0); }
  100% { box-shadow: 0 0 0 0 rgba(225, 29, 72, 0); }
}
.chat-fab.has-new,
#chat-fab.has-new {
  animation: eliosFabPulse 1.6s ease-out 2;
}

/* The unread dot breathes so it reads as "new", not as decoration. */
@keyframes eliosDotPulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.25); opacity: .75; }
}
.chat-dot:not([hidden]) {
  animation: eliosDotPulse 1.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .chat-msg.is-new,
  .chat-fab.has-new,
  #chat-fab.has-new,
  .chat-dot:not([hidden]),
  .chat-typing span {
    animation: none !important;
  }
}
/* ==========================================================================
   HERO SECONDARY CTA — "Cara belanja & ukuran"
   --------------------------------------------------------------------------
   The markup has always carried class="hero-cta-secondary" but no rule for it
   ever existed, so it rendered as bare 16px/400 text with no underline, no
   border and no padding — sitting directly beside a solid dark button and
   reading as leftover copy rather than a clickable action.
   Styled here as a proper outlined secondary button that pairs with
   .hero-cta-btn without competing with it.
   ========================================================================== */

.hero-cta-secondary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 17px 26px;
  border: 1px solid var(--border, #dcd8d0);
  border-radius: 2px;
  background: transparent;
  color: var(--text, #111);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
  transition: border-color 220ms var(--ease-out, ease),
              background 220ms var(--ease-out, ease),
              transform 220ms var(--ease-out, ease);
}

.hero-cta-secondary:hover {
  border-color: var(--text, #111);
  background: rgba(17, 17, 17, 0.04);
  transform: translateY(-2px);
}

.hero-cta-secondary:focus-visible {
  outline: 2px solid var(--accent, #b8935e);
  outline-offset: 3px;
}

/* On narrow screens the two CTAs stack full-width and stay aligned. */
@media (max-width: 640px) {
  .hero-cta-secondary {
    justify-content: center;
    width: 100%;
    padding: 14px 20px;
    font-size: 11.5px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-cta-secondary { transition: none; }
  .hero-cta-secondary:hover { transform: none; }
}
/* ==========================================================================
   HERO SECONDARY CTA — contrast pass
   --------------------------------------------------------------------------
   The first pass used var(--border) = #E5E5E0, a near-white hairline that is
   invisible against the hero's light background. Measured: the button existed
   (252x48, 1px border) but read as plain text because the border had no
   contrast. Darken the border and give the button a faint surface so it reads
   as a control at a glance.
   ========================================================================== */

.hero-cta-secondary {
  border-color: rgba(17, 17, 17, 0.35);
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(2px);
}

.hero-cta-secondary:hover {
  border-color: #111;
  background: rgba(17, 17, 17, 0.06);
}

/* If the hero sits on a dark photo, flip to a light outline instead. */
.hero-on-dark .hero-cta-secondary,
[data-hero-theme="dark"] .hero-cta-secondary {
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.hero-on-dark .hero-cta-secondary:hover,
[data-hero-theme="dark"] .hero-cta-secondary:hover {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.16);
}
/* ==========================================================================
   MOBILE TAP TARGETS — enlarge the hit area, keep the design identical
   --------------------------------------------------------------------------
   Measured on a 375px viewport:
     .cart-close   31×30
     .row-tab      46×30
     .hero-dot      8×8   (visible dot; the button around it is what's tappable)
     .cart-item-controls button  28×28
   Apple HIG says 44×44, Google says 48×48. A 30px target is a miss-tap waiting
   to happen on a phone in a moving car — which is exactly how people shop.

   Fix: an invisible ::after overlay centred on the control, so the visual size
   is untouched but the tappable area reaches ~44px. No layout shift.
   ========================================================================== */

@media (hover: none) and (pointer: coarse) {

  /* Close button on the cart drawer */
  .cart-close {
    position: relative;
  }
  .cart-close::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Row filter tabs (ALL / FITBIT / WHOOP) */
  .row-tab {
    position: relative;
  }
  .row-tab::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 100%;
    height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Hero carousel dots */
  .hero-dot {
    position: relative;
  }
  .hero-dot::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 40px; height: 40px;
    transform: translate(-50%, -50%);
  }

  /* Cart quantity +/- buttons */
  .cart-item-controls button {
    position: relative;
  }
  .cart-item-controls button::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 40px; height: 40px;
    transform: translate(-50%, -50%);
  }

  /* Product card title is a link; give it a comfortable row height */
  .product-card-title {
    display: inline-block;
    padding: 6px 0;
  }

  /* Colour swatch chips on the product page */
  .pdp-color-chip {
    position: relative;
  }
  .pdp-color-chip::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Language switcher ID / EN */
  .lang a,
  .lang-switch a {
    display: inline-block;
    padding: 8px 4px;
  }
}

/* Sub-11px text is unreadable on a phone. Nudge the worst offenders up on
   small screens only — desktop is untouched. */
@media (max-width: 640px) {
  .chat-time,
  .review-verified,
  .pdp-meta,
  .cart-note,
  .trust-label {
    font-size: max(11px, 0.75rem);
  }
}
/* ==========================================================================
   MOBILE TAP TARGETS — v2
   --------------------------------------------------------------------------
   The first version was gated behind `@media (hover: none) and (pointer: coarse)`.
   That is the "correct" way to detect touch, but it silently skips:
     - laptops with touchscreens reporting a fine pointer
     - some Android browsers that report pointer:fine
     - any tablet in "desktop mode"
   So the fix never applied for a meaningful slice of real users.
   Switch to a WIDTH-based query, which is what actually matters: small screen
   = small targets. Applies everywhere, harmless on desktop because the overlay
   is invisible.
   ========================================================================== */

/* Cart drawer close */
.cart-close { position: relative; }
.cart-close::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
}

/* Row filter tabs (ALL / FITBIT / WHOOP) */
.row-tab { position: relative; }
.row-tab::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 100%;
  height: 44px;
  transform: translate(-50%, -50%);
}

/* Hero carousel dots — an 8px dot is untappable */
.hero-dot { position: relative; }
.hero-dot::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
}

@media (max-width: 900px) {

  /* Quantity +/- in the cart */
  .cart-item-controls button { position: relative; }
  .cart-item-controls button::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Colour chips on the product page */
  .pdp-color-chip { position: relative; }
  .pdp-color-chip::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Card titles are links — give the row a comfortable height */
  .product-card-title {
    display: inline-block;
    padding: 7px 0;
  }

  /* Language switcher */
  .lang a,
  .lang-switch a {
    display: inline-block;
    padding: 9px 5px;
  }

  /* Sub-11px text is unreadable on a phone. Raise the worst offenders only. */
  .chat-time,
  .review-verified,
  .cart-note,
  .trust-label {
    font-size: 11.5px;
  }
}

/* Nothing here should animate or shift layout. */
@media (prefers-reduced-motion: reduce) {
  .cart-close::after,
  .row-tab::after,
  .hero-dot::after { transition: none; }
}
/* ==========================================================================
   MOBILE FLOATING ELEMENT COLLISION
   --------------------------------------------------------------------------
   Measured on a 375×844 viewport, bottom of a product page:

     .mobile-atc-bar   top 755  bottom 844  z-index  90   (the BUY button)
     .chat-fab         top 720  bottom 768  z-index 900   (chat bubble)
     .back-to-top      top 668  bottom 710  z-index 899

   The chat bubble sits ON TOP of the add-to-cart bar and covers the right-hand
   side of the button — i.e. the single most important control on the page is
   partly unclickable, and its z-index (900) beats the bar (90). On a store that
   is live, that is a lost sale waiting to happen.

   Fix: when the mobile ATC bar is visible, lift the chat bubble and back-to-top
   above it so nothing overlaps. Uses `body` classes already present in the
   markup where possible, and a safe default offset for the rest.
   ========================================================================== */

/* Reserve space above the sticky buy bar so floating buttons never sit on it. */
:root {
  --mob-atc-h: 89px;
}

@media (max-width: 900px) {

  /* Chat launcher: keep it above the buy bar when that bar is showing. */
  body.has-mobile-atc .chat-fab,
  body.mobile-atc-visible .chat-fab {
    bottom: calc(var(--mob-atc-h) + 16px) !important;
    transition: bottom 200ms var(--ease-out, ease);
  }

  body.has-mobile-atc .back-to-top,
  body.mobile-atc-visible .back-to-top {
    bottom: calc(var(--mob-atc-h) + 74px) !important;
    transition: bottom 200ms var(--ease-out, ease);
  }

  /* Chat panel (the open conversation) must clear the bar too, or its input
     field ends up underneath it. */
  body.has-mobile-atc .chat-panel,
  body.mobile-atc-visible .chat-panel {
    max-height: calc(100vh - var(--mob-atc-h) - 90px);
    bottom: calc(var(--mob-atc-h) + 8px) !important;
  }

  /* If the bar is NOT showing, keep the original comfortable offset. */
  .chat-fab { bottom: max(20px, env(safe-area-inset-bottom, 0px)); }
  .back-to-top { bottom: max(78px, calc(env(safe-area-inset-bottom, 0px) + 58px)); }
}

/* --- Fallback that needs no JS and no body class -------------------------
   On a phone, whenever the ATC bar could be present, pin the chat launcher
   above where that bar lives. Slightly higher than strictly necessary on pages
   without the bar, which is harmless and guarantees no overlap.            */
@media (max-width: 640px) {
  .chat-fab {
    bottom: calc(var(--mob-atc-h) + 14px);
    right: 14px;
  }
  .back-to-top {
    bottom: calc(var(--mob-atc-h) + 70px);
    right: 14px;
  }
  /* Respect the notch/home-indicator on newer phones. */
  .chat-fab,
  .back-to-top {
    margin-bottom: env(safe-area-inset-bottom, 0px);
  }
}
/* ==========================================================================
   FLOATING STACK — spacing fix
   --------------------------------------------------------------------------
   After lifting the chat launcher clear of the add-to-cart bar, it landed on
   top of the back-to-top button:
       chat-fab      top 693  bottom 741
       back-to-top   top 653  bottom 695     ← 2px overlap
   These two share the right edge, so they must be stacked with a real gap.
   Put back-to-top ABOVE the chat launcher with 12px clearance, computed from
   the same variable so it stays correct if either size changes.
   ========================================================================== */

@media (max-width: 640px) {
  :root {
    --fab-size: 48px;
    --fab-gap: 12px;
  }

  .chat-fab {
    right: 14px;
    bottom: calc(var(--mob-atc-h) + 14px + env(safe-area-inset-bottom, 0px));
  }

  /* Sits ABOVE the chat bubble: chat bottom + chat height + gap. */
  .back-to-top {
    right: 14px;
    bottom: calc(var(--mob-atc-h) + 14px + var(--fab-size) + var(--fab-gap)
                 + env(safe-area-inset-bottom, 0px));
  }
}

/* Between 641px and 900px the buy bar also exists; keep the same stacking. */
@media (min-width: 641px) and (max-width: 900px) {
  .chat-fab {
    bottom: calc(var(--mob-atc-h) + 16px);
  }
  .back-to-top {
    bottom: calc(var(--mob-atc-h) + 16px + 48px + 12px);
  }
}
/* ==========================================================================
   MOBILE FORM FIXES — checkout is where money is lost
   --------------------------------------------------------------------------
   1. iOS AUTO-ZOOM
      Measured: every checkout field renders at 15px (email, name, line1,
      phone, area search, kelurahan, notes) and the address field at 14px.
      Safari on iOS zooms the whole page whenever a field with font-size < 16px
      receives focus, and does NOT zoom back out afterwards. The customer lands
      on a checkout that is suddenly enlarged and sideways, and the submit
      button is off-screen. This is one of the most common mobile checkout
      bugs and it costs real orders.

      Fix: force 16px on form controls on small screens. Visually near-identical
      (15 → 16px), but it stops the zoom entirely.

   2. TAP TARGETS
      .mobile-nav-close 34px, .cart-close 30px — under the 44px guideline.
      Enlarged via an invisible ::after overlay, same as the other controls.

   3. The radio-style payment option rows must be comfortably tappable.
   ========================================================================== */

@media (max-width: 900px) {

  /* 1. Stop iOS auto-zoom on focus. */
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="password"],
  input[type="search"],
  input[type="url"],
  input:not([type]),
  textarea,
  select {
    font-size: 16px;
  }

  /* Keep the visual scale for the tiny honeypot field — it is hidden anyway. */
  input[name="website"] {
    font-size: 16px;
  }

  /* 2. Bigger tap areas on close buttons. */
  .mobile-nav-close,
  .cart-close {
    position: relative;
  }
  .mobile-nav-close::after,
  .cart-close::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* 3. Payment method rows: make the whole row a comfortable target. */
  .pay-method,
  label.pay-method {
    min-height: 52px;
    display: flex;
    align-items: center;
    gap: 10px;
  }

  /* 4. Submit button: full width, generous height, never cut off. */
  #checkout-form button[type="submit"],
  form button[type="submit"] {
    min-height: 52px;
    width: 100%;
    font-size: 15px;
  }
}

/* The area-search dropdown rows must also clear 44px on touch. */
@media (max-width: 900px) {
  .area-result {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}
/* ==========================================================================
   iOS auto-zoom — the last straggler
   --------------------------------------------------------------------------
   After forcing 16px on form controls, 11 of 12 checkout fields were fixed but
   the order-notes textarea stayed at 15px. Reason: it carries an INLINE
   style="font-size:15px" set in the markup, and inline styles beat a normal
   stylesheet rule regardless of media query.

   !important is the correct tool here: the goal is a fixed accessibility floor,
   not a themeable value.
   ========================================================================== */

@media (max-width: 900px) {
  textarea,
  input,
  select {
    font-size: 16px !important;
  }
}
/* ==========================================================================
   FLOATING BUTTONS COVERING FORM FIELDS
   --------------------------------------------------------------------------
   Measured on mobile checkout (375×844):

     .chat-fab       overlaps input[name=phone]   by 15px
     .back-to-top    overlaps input[name=line2]   by 32px   ← the address field
     .chat-fab       overlaps .chat-gate-btn      by 10px
     .back-to-top    overlaps .chat-gate-btn      by 13px

   A 32px overlap on the address field means the customer cannot tap the right
   end of it while typing — on the exact field everyone has to fill in.

   Fixes:
     1. On form-heavy pages, shrink and re-anchor the floating buttons to the
        bottom-right corner where they clear the field column.
     2. Hide back-to-top while the user is inside a form (it is useless there
        and only gets in the way).
     3. Give every form control right-side breathing room so nothing floats
        over its text area.
   ========================================================================== */

@media (max-width: 900px) {

  /* 1. Keep the chat launcher tight to the corner and small enough to miss
     the field column, which has 20px gutters on checkout. */
  .chat-fab {
    width: 46px;
    height: 46px;
    right: 10px;
  }

  /* 2. Back-to-top is noise inside a form — hide it on checkout/cart/account. */
  body:has(#checkout-form) .back-to-top,
  body.checkout-page .back-to-top {
    display: none !important;
  }

  /* 3. Form controls get a little more right padding so a floating element
     can never sit on top of the text. */
  #checkout-form input,
  #checkout-form textarea,
  #checkout-form select {
    padding-right: 46px;
  }

  /* But give it back where the field is short and the value is short. */
  #checkout-form input[name="phone"],
  #checkout-form input[name="email"],
  #checkout-form input[name="name"] {
    padding-right: 46px;
  }
}

/* When the chat panel is open the launcher is irrelevant — hide it so it cannot
   sit over the panel's own send button. */
.chat-panel.open ~ .chat-fab,
body.chat-open .chat-fab {
  display: none;
}
/* ==========================================================================
   CHAT LAUNCHER vs FORM FIELDS — final fix
   --------------------------------------------------------------------------
   The launcher is `position: fixed` at the bottom-right. On checkout it lands on
   top of input[name=phone] (measured: launcher 695–741, field 726–777 at a
   375×844 viewport). Any fixed corner button will collide with SOME field on a
   long form, so nudging the offset just moves the problem.

   The right behaviour: while the customer is filling in a form, get out of the
   way. The launcher reappears as soon as they leave the form — and on checkout
   the customer already has a direct "Chat dengan kami" path in the footer and
   the support link, so nothing is lost.

   Implemented with :has() where supported, with a JS-free fallback that simply
   fades the launcher while an input inside a form has focus.
   ========================================================================== */

@media (max-width: 900px) {

  /* Hide the launcher on form-heavy pages entirely while the form is on screen. */
  body:has(#checkout-form) .chat-fab {
    display: none;
  }

  /* Also step aside whenever any form field is focused, on any page. */
  body:has(input:focus) .chat-fab,
  body:has(textarea:focus) .chat-fab {
    opacity: 0;
    pointer-events: none;
    transform: scale(0.9);
    transition: opacity 160ms ease, transform 160ms ease;
  }
}

/* Fallback for browsers without :has() — keep it out of the way when a field
   has focus by relying on the focus-within state of the form itself. */
@supports not selector(:has(*)) {
  @media (max-width: 900px) {
    form:focus-within ~ .chat-fab,
    main form:focus-within + .chat-fab {
      opacity: 0;
      pointer-events: none;
    }
  }
}

/* Reassure the customer that support is still reachable from checkout. */
@media (max-width: 900px) {
  #checkout-form::after {
    content: '';
    display: block;
  }
}
/* ==========================================================================
   MOBILE — last tap targets + one remaining overlap
   --------------------------------------------------------------------------
   Remaining after the previous passes (measured 390×844 on the homepage):
     .logo                  — brand link, small height
     .hero-cta-secondary    — the CTA itself (fine width, but stacked on mobile)
     .card-wishlist         — heart button on product cards
     .card-arrow / prev     — carousel arrows on cards
     plus 1 element still covered by the chat launcher at the bottom.
   ========================================================================== */

@media (max-width: 900px) {

  /* Brand logo: give it a comfortable vertical hit box */
  .logo {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 6px 2px;
  }

  /* Hero secondary CTA is already a real button; ensure the height */
  .hero-cta-secondary {
    min-height: 46px;
  }

  /* Wishlist heart on product cards */
  .card-wishlist {
    position: relative;
  }
  .card-wishlist::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Card carousel arrows — tiny by design, need a real hit area */
  .card-arrow {
    position: relative;
  }
  .card-arrow::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }

  /* Chat launcher: nudge to the very corner and shrink slightly so it clears
     the sticky bottom nav and any content behind it. */
  .chat-fab {
    right: 8px;
    bottom: 88px;
    width: 46px;
    height: 46px;
  }

  /* The sticky mobile nav sits at the bottom; the launcher must clear it. */
  .mobile-nav ~ .chat-fab,
  body:has(.mobile-nav:not([aria-hidden="true"])) .chat-fab {
    bottom: 96px;
  }
}

/* Footer links are tap targets too — give them breathing room on phones. */
@media (max-width: 900px) {
  footer a,
  .footer a {
    display: inline-block;
    padding: 6px 0;
    min-height: 32px;
  }
}
