/* ===================================================================
   Yogen Fruz store locator
   -------------------------------------------------------------------
   Sizes, colours and spacing below are taken from the Figma frame
   "Find a Store" (Dev Use 03), not estimated from a screenshot.

   The page is embedded in a WordPress page via an iframe. The gradient
   and the "Find Your Store" heading belong to the parent page, so the
   document background here is deliberately transparent: anything opaque
   would cut a visible seam across the parent's gradient.
   =================================================================== */

:root {
  --yf-cyan:        #00a7e2;   /* rank badge */
  --yf-blue:        #0076a5;   /* search + Locate Me, outline buttons */
  --yf-blue-deep:   #004462;   /* store name */
  --yf-pink:        #f28cb4;   /* Order Now — solid, so it has no second state */
  --yf-plum:        #5a2140;   /* text on pink — the site's button colour */
  --yf-ink:         #101213;
  --yf-ink-soft:    #4a4f52;
  --yf-surface:     #faf8f5;   /* panel AND cards; cards read as separate
                                  through their shadow, not a colour change.
                                  Making cards white instead makes the panel
                                  look pink by contrast. */
  --yf-water:       #dcf3fb;
  --yf-line:        #e9e4dd;

  --yf-radius-panel: 20px;
  --yf-radius-card:  16px;
  --yf-radius-pill:  60px;

  /* Matches the site's own icon hover (color .5s ease). */
  --yf-ease: .5s ease;

  --yf-font: "Helvetica Neue YF", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* The woff2 files at yf-fonts/ carry REPAIRED vertical metrics
     (hhea/typo ascent 952 / descent 213 / lineGap 28 per 1000 upm — the
     same values as the system Helvetica Neue they fall back to). The
     original export declared ascent 714, which made every engine set
     baselines ~.15em too high: text sat visibly high in buttons, pins and
     the search input, tight line boxes shaved cap tops, and the page
     visibly jumped upward when the webfont swapped in over the fallback.

     With the metrics repaired, browsers centre this font correctly on
     their own, so the vertical nudge is zero. If these font files are
     ever replaced, verify the replacement's metrics before trusting any
     vertical alignment on this page.

     Horizontal correction still applies — it is glyph-level, not a
     metrics problem: '1' sits .049em left of its advance centre (lsb 81
     vs rsb 179); every other digit is within .016em. A half-correction
     fixes most of the '1' without visibly pushing '0' and '8' the other
     way. */
  --yf-digit-nudge-y: 0em;
  --yf-digit-nudge-x: .04em;

  /* Symmetric now that the font metrics are correct; total stays 1.46em
     so the button height does not change. */
  --yf-btn-pad-top:    .73em;
  --yf-btn-pad-bottom: .73em;
}

*, *::before, *::after { box-sizing: border-box; }

/* Visible to screen readers, not on screen.
   Not display:none and not visibility:hidden — both remove the text from
   the accessibility tree as well, which defeats the point. The clip-path
   plus 1px box is the form that survives every reader. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

html, body {
  height: 100%;
  margin: 0;
  /* See the header note: the parent page paints the background. */
  background: transparent;
}

body {
  font-family: var(--yf-font);
  color: var(--yf-ink);
  -webkit-font-smoothing: antialiased;
}

/* -------------------------------------------------------------------
   Shell
   ------------------------------------------------------------------- */

.locator {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  max-width: 1232px;
  margin: 0 auto;
  /* Top padding is not decoration: the search pill carries a shadow and
     sits at the very top of the frame, and without room for it both the
     shadow and the pill's rounded top are clipped against the edge of
     the iframe. */
  padding: 24px 16px 16px;
  gap: 30px; /* search pill to panel, per design */
}

/* Below the desktop breakpoint the frame follows the site's 5% gutters;
   the fixed 16px matched the 768 design frame but ran ~2% on real tablets. */
@media (max-width: 1024px) {
  .locator { padding-left: 5%; padding-right: 5%; }
}

@media (min-width: 768px) {
  .locator { gap: 60px; }
}

/* Desktop only: no scroll chaining past the list — it would bypass the parent
   page's Lenis. Mobile keeps chaining for natural touch scroll. */
@media (min-width: 1025px) {
  .locator-list { overscroll-behavior: contain; }
}

.locator-close {
  display: none; /* retired: the locator now lives inside the Find a Store page */
  position: absolute;
  top: 8px; right: 12px;
  z-index: 5;
  border: 0;
  background: none;
  font-size: 32px;
  line-height: 1;
  color: #fff;
  cursor: pointer;
  transition: opacity var(--yf-ease);
}

/* -------------------------------------------------------------------
   Search pill
   ------------------------------------------------------------------- */

.search-area { flex: 0 0 auto; }

.search-pill {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 750px;
  margin: 0 auto;
  padding: 6px 6px 6px 22px;
  background: #fff;
  border-radius: var(--yf-radius-pill);
  box-shadow: 0 2px 10px rgba(16, 18, 19, .10);
}

.search-pill .geocoder { flex: 1 1 auto; min-width: 0; }

.btn-search,
.btn-locate {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  cursor: pointer;
  background: var(--yf-blue);
  color: var(--yf-surface);
  font-family: var(--yf-font);
  /* No transition: these are solid buttons and solid buttons do not change
     on hover here — only :focus-visible does, and an outline must not fade
     in. See the hover-states section near the end of this file. */
}

.btn-search {
  width: 40px; height: 40px;
  border-radius: 50%;
}

.btn-locate {
  gap: 8px;
  border-radius: var(--yf-radius-pill);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1;
  white-space: nowrap;
  padding: .74em 16px;
}

/* No vertical correction on the text: the repaired font metrics centre it
   (see the --yf-digit-nudge-y note at the top of this file). */


.btn-search:focus-visible,
.btn-locate:focus-visible { outline: 3px solid var(--yf-blue-deep); outline-offset: 2px; }

/* -------------------------------------------------------------------
   Panel: map + list
   -------------------------------------------------------------------
   Source order is map-then-list (mobile). Desktop reverses it with
   `order` so the list sits on the left, matching the design, without
   moving anything in the markup.
   ------------------------------------------------------------------- */

.locator-panel {
  flex: 1 1 auto;
  min-height: 0;              /* lets the inner list scroll instead of pushing */
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: var(--yf-surface);
  border-radius: var(--yf-radius-panel);
  box-shadow: 0 4px 20px rgba(16, 18, 19, .07);
}

#map {
  flex: 0 0 320px;            /* mobile: fixed strip above the list */
  min-height: 0;
  border-radius: var(--yf-radius-card);
  background: var(--yf-water);
  overflow: hidden;
}

.locator-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* A scroll container clips horizontally as well as vertically, which cut
     the card shadows off flush at the left edge. The negative margin widens
     the scroll box into the panel's padding and the matching inner padding
     puts the cards back exactly where they were — the extra room is only
     there for the shadow to land in. */
  margin: 0 -8px;
  padding: 6px 8px 8px;
}

/* Tablet (768-1024) keeps the stacked layout: a 36% column on a 768px
   screen leaves ~260px for the cards, which wraps every store name onto
   three lines. Give it a taller map instead. */
@media (min-width: 768px) and (max-width: 1024px) {
  #map { flex: 0 0 420px; }
}

/* Desktop. 1025 rather than a round number so it lines up with the
   breakpoints the rest of the site uses (767 / 1024). */
@media (min-width: 1025px) {
  .locator-panel { flex-direction: row; gap: 32px; }
  .locator-list  { order: 0; flex: 0 0 calc(36% + 16px); }
  #map           { order: 1; flex: 1 1 auto; }
}

.list-status {
  margin: 24px 12px;
  text-align: center;
  color: var(--yf-ink-soft);
  font-size: 15px;
}

/* -------------------------------------------------------------------
   Store card
   ------------------------------------------------------------------- */

.store-card {
  display: flex;
  gap: 32px;                  /* badge to content — the design leaves a lot
                                 of air here; a tighter gap reads cramped */
  padding: 20px 16px;
  margin-bottom: 7px;
  background: var(--yf-surface);
  border-radius: var(--yf-radius-card);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .14);
  cursor: pointer;
  transition: box-shadow var(--yf-ease), transform var(--yf-ease);
}

.store-card:last-child { margin-bottom: 0; }

/* Tight blur, and raised above its neighbour. A wide shadow reaches past
   the 7px gap and reads as though the two cards were joined. */
.store-card.is-open {
  position: relative;
  z-index: 1;
  box-shadow: 0 2px 8px rgba(0, 118, 165, .38);
}

.store-rank {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--yf-cyan);
  color: var(--yf-surface);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  /* See --yf-digit-nudge-* above for where these numbers come from. */
  letter-spacing: 0;
  padding-top: var(--yf-digit-nudge-y);
  padding-left: var(--yf-digit-nudge-x);
}

.store-body { flex: 1 1 auto; min-width: 0; }

.store-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.store-toggle {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.store-toggle:focus-visible { outline: 3px solid var(--yf-blue); outline-offset: 3px; border-radius: 4px; }

.store-name {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--yf-blue-deep);
}

.store-distance {
  margin: 8px 0 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--yf-ink);
}

/* No rule above this line: the design separates it with 12px of space,
   not a border. */
.store-hours {
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--yf-ink);
}

/* -------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------
   Weight, letter-spacing and vertical padding are copied from the site's
   own Elementor buttons so the locator does not read as a different
   toolkit bolted on. That includes when they react: a solid button never
   changes on hover, an outlined one fills with its own border colour.
   ------------------------------------------------------------------- */

.btn-order,
.btn-directions {
  /* inline-block, NOT flex, so the padding alone decides where the text
     sits. Only .btn-locate flexes, because it has an icon to align. */
  display: inline-block;
  text-align: center;
  border-radius: var(--yf-radius-pill);
  font-family: var(--yf-font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  padding: var(--yf-btn-pad-top) 16px var(--yf-btn-pad-bottom);
}

.btn-order:focus-visible,
.btn-directions:focus-visible,
.detail-row a:focus-visible {
  outline: 3px solid var(--yf-blue-deep);
  outline-offset: 2px;
}

.btn-order {
  flex: 0 0 auto;
  border: 0;
  background: var(--yf-pink);
  color: var(--yf-plum);
}

/* The only button here that reacts to hover, so the only one that needs a
   transition — .btn-order is solid and stays exactly as it is. */
.btn-directions {
  background: transparent;
  border: 1px solid var(--yf-blue);
  color: var(--yf-blue);
  transition: background-color var(--yf-ease), color var(--yf-ease);
}

.btn-block { display: block; width: 100%; }

/* -------------------------------------------------------------------
   Detail, expanded inside its card
   -------------------------------------------------------------------
   An overlay covering the list and the map loses the visitor's place —
   they can no longer see which of the seven stores they opened, or
   where it is relative to the others. Expanding in situ keeps the list,
   the map and the pin all visible.
   ------------------------------------------------------------------- */

/* Expand/collapse.
   grid-template-rows 0fr -> 1fr is the one way to transition to a height
   nobody has measured — max-height needs a guessed ceiling, and any guess
   is either too small (clipping long hour tables) or too large (making
   short cards close on a delay). */
.store-detail-slot {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s ease;
}
.store-card.is-open .store-detail-slot { grid-template-rows: 1fr; }

.store-detail-inner {
  min-height: 0;
  overflow: hidden;           /* required: the row is fractional while animating */
}

/* Spacing lives inside the collapsing box so it animates away too;
   on the slot itself it would leave a gap behind when closed. */
.detail-pad {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--yf-line);
}

.detail-row {
  margin: 0 0 8px;
  font-size: 14px;
  line-height: 1.5;           /* a wrapped address on default leading reads
                                 as one dense block rather than two lines */
}
.detail-row a { color: var(--yf-blue); text-decoration: none; }

.detail-subhead {
  margin: 14px 0 6px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--yf-ink-soft);
}

.detail-hours { width: 100%; border-collapse: collapse; font-size: 14px; }
.detail-hours th,
.detail-hours td { padding: 5px 0; text-align: left; font-weight: 400; }
/* Inset from the card edge: flush right, the times read as though they
   were about to fall out of the card. */
.detail-hours td { text-align: right; padding-right: 8px; }
.detail-hours .is-today th,
.detail-hours .is-today td { font-weight: 700; color: var(--yf-blue-deep); }

.detail-note { margin: 10px 0 0; font-size: 13px; color: var(--yf-ink-soft); }

.detail-actions { margin-top: 14px; }

/* -------------------------------------------------------------------
   Hover states
   -------------------------------------------------------------------
   Gated on the pointer actually being able to hover. On a touchscreen
   there is no hover: the browser fakes one on tap and then leaves it
   stuck on the last thing touched, so a tapped card stays highlighted
   until something else is tapped.

   This is a capability query, not a width breakpoint, on purpose — a
   touchscreen laptop is wide, and a tablet with a trackpad attached can
   hover. Asking the device beats guessing from its size.
   ------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .locator-close:hover { opacity: .7; }

  /* Solid-filled buttons (.btn-search, .btn-locate, .btn-order) deliberately
     have NO hover state — the site's own buttons behave the same way. Only
     outlined buttons react, and the reaction is to fill with the colour they
     are already outlined in, so the hover reads as the same object. */
  .btn-directions:hover { background: var(--yf-blue); color: #fff; }

  .detail-row a:hover { text-decoration: underline; }

  .store-card:hover {
    position: relative;
    z-index: 1;
    box-shadow: 0 2px 8px rgba(0, 118, 165, .38);
  }
}

/* -------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------
   Everything that moves is decoration over a state change that is
   already conveyed some other way, so it can all be switched off. The
   card still expands, the pin still enlarges — they just arrive at once.

   The JS honours the same preference: see PREFERS_REDUCED_MOTION in
   main2-mapbox.js, which swaps the map's flyTo for a jump and the list's
   animated scroll for an instant one. CSS alone cannot reach those.
   ------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* -------------------------------------------------------------------
   Request error banner
   -------------------------------------------------------------------
   Shown when a search request fails (network error, or 429 from the
   rate limiter). Without it a failed search is indistinguishable from
   a button that does nothing.
   ------------------------------------------------------------------- */

.request-error {
  margin: 0 0 10px;
  padding: 12px 14px;
  border-radius: var(--yf-radius-card);
  background: #fdecef;
  border: 1px solid var(--yf-pink);
  color: var(--yf-plum);
  font-size: 14px;
}


/* -------------------------------------------------------------------
   Phone layout (<=600px)
   -------------------------------------------------------------------
   At 390px the pill left the address field 132px wide, which truncated the
   placeholder to "Search by c...". The field takes its own row and the two
   buttons share the one below; the pill keeps its shadow and rounding.
   ------------------------------------------------------------------- */
@media (max-width: 600px) {
  .search-pill {
    flex-wrap: wrap;
    row-gap: 10px;
    padding: 12px 14px;
    border-radius: 24px;
  }
  .search-pill .geocoder { flex: 1 1 100%; }
  .btn-locate { flex: 1 1 auto; }

  /* 32px of badge-to-content air costs a fifth of the card on a phone. */
  .store-card { gap: 14px; padding: 18px 14px; }
  .store-name { font-size: 18px; }
  .btn-order  { font-size: 13px; padding-left: 12px; padding-right: 12px; }
}


/* Mapbox's own map.css does `.mapboxgl-ctrl-geocoder--input:focus { outline: none;
   box-shadow: none }`, which left the only text field on this page with no
   keyboard indicator at all. Same ring as the buttons; inset because the pill
   clips anything drawn outside it. */
html[data-yf-input="key"] .search-pill .mapboxgl-ctrl-geocoder--input:focus-visible {
  outline: 2px solid var(--yf-blue) !important;
  outline-offset: -2px !important;
  border-radius: 4px;
}
