/**
 * Ice Cream Truck — public widget  @version 1.1.1
 *
 * One fixed `.ic-root` bottom-LEFT (bottom-right is the businesses FAB) at z-index 410 —
 * in the 400–450 budget, above the FAB (200) and headers (100), below the toast (1000)
 * and skip link (2000); it opens its own stacking context so the card z-20 stays in that
 * band. Nothing joins page layout: fixed throughout, only transform/opacity animate.
 * Dark mode arrives two ways here, so every theme value is an `--ic-*` flipped by the one
 * dual selector below. Declarations are packed onto shared lines to fit the 8 KB budget.
 */

/* ---- anchor + tokens ---- */
.ic-root{
  --ic-berry:#ff6b9d;--ic-vanilla:#fff4e0;--ic-ink:#3c4657;--ic-tyre:#3c4657;
  --ic-glass:#bfe6ff;--ic-sky:linear-gradient(#f0f7ff,#cfe4ff);--ic-hot:#b3145a;
  --ic-bg:#fff;--ic-fg:#1a1a1a;--ic-fg2:#4a4a4a;--ic-line:#edf2f7;
  --ic-shade:rgba(15,23,42,.13);--ic-glow:rgba(15,23,42,.22);
  /* --ic-lift clears .quick-actions-mobile, whose real measured height is 94px
     (0.75rem padding + a 3-button grid), not the 80px it looks like. At 96px the
     gap was 2px on every device — the env() term cancels, so a bigger safe area
     never helped. Pages with no bottom bar (businesses.html) override --ic-lift
     instead of duplicating this rule.
     137px = 94px bar + 16px gutter + the "Click me" label, which hangs BELOW the
     60px root box and occupies 27px of it (5px offset + a 22px pill). Change the
     label's font-size, padding or offset and this number must move with it, or
     the label slides under the bar. Measured, not estimated. */
  position:fixed;left:16px;bottom:calc(var(--ic-lift,137px) + env(safe-area-inset-bottom,0px));
  width:60px;height:60px;z-index:410;pointer-events:none;line-height:1.45;
  font-family:var(--font-body,-apple-system,system-ui,sans-serif)
}
[data-theme="dark"] .ic-root, body.dark-mode .ic-root{
  --ic-ink:#2a3240;--ic-tyre:#5b6982;--ic-hot:#ff9ec4;--ic-sky:linear-gradient(#3b4a68,#1e2637);
  --ic-bg:#2d3748;--ic-fg:#f7fafc;--ic-fg2:#e2e8f0;--ic-line:#3d4a5c;
  --ic-shade:rgba(0,0,0,.35);--ic-glow:rgba(0,0,0,.5)
}
.ic-root.ic-hide{display:none}
.ic-sr{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%)}
/* >768px: no quick-actions bar, so sit lower — but still leave room for the
   label hanging below the root, hence 46px rather than 24px. */
@media (min-width:769px){
  .ic-root{left:24px;bottom:calc(46px + env(safe-area-inset-bottom,0px))}
  .ic-card{max-height:min(560px,calc(100vh - 130px))}
}

/* ---- launcher ---- */
.ic-btn{
  position:absolute;inset:0;padding:0;cursor:pointer;pointer-events:auto;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:var(--ic-sky);
  border:2px solid rgba(255,107,157,.45);
  box-shadow:0 6px 18px var(--ic-glow),0 1px 3px rgba(15,23,42,.16);transition:transform .12s ease
}
.ic-btn:active{transform:scale(.94)}
/* "Click me" / "Tap me" — hangs below the 60px root box. It floats over arbitrary
   page content (webcams, cards, photos), so it carries its own pill background
   rather than relying on whatever is behind it. aria-hidden because the button's
   aria-label already says the same thing; this is decoration, not a second
   announcement.

   The wording lives in CSS `content` rather than as two spans toggled by a media
   query: with two spans, a stylesheet that failed to load would render
   "Click meTap me" mashed together, whereas an empty span degrades to no label at
   all. Harmless either way, but one failure mode is uglier than the other.
   (hover:none) rather than a width breakpoint — a touchscreen laptop with a mouse
   reports hover:hover and correctly keeps "Click me". */
.ic-cta::after{content:"Click me"}
@media (hover:none){.ic-cta::after{content:"Tap me"}}
.ic-cta{
  position:absolute;top:calc(100% + 5px);left:50%;transform:translateX(-50%);
  pointer-events:auto;cursor:pointer;white-space:nowrap;
  font-size:11.5px;font-weight:800;letter-spacing:.01em;line-height:1;
  padding:4px 9px;border-radius:9999px;
  color:var(--ic-hot);background:var(--ic-bg);
  border:1.5px solid rgba(255,107,157,.55);
  box-shadow:0 2px 6px var(--ic-shade)
}
.ic-svg{width:50px;height:38px;display:block;pointer-events:none}
/* halo: sibling, can exceed the button */
.ic-ring{position:absolute;inset:-5px;border:3px solid var(--ic-berry);border-radius:50%;opacity:0}

/* ---- truck parts ---- */
.ic-bdy,.ic-wsh,.ic-win,.ic-awn,.ic-cone,.ic-sw,.ic-chy{stroke:var(--ic-ink);stroke-width:1.2;stroke-linejoin:round}
.ic-bdy,.ic-hub{fill:var(--ic-vanilla)}
.ic-wsh,.ic-win{fill:var(--ic-glass)}
.ic-sw,.ic-awns,.ic-str{fill:var(--ic-berry)}
.ic-awn{fill:#fff}
.ic-cone{fill:#e8a24a}
.ic-chy{fill:#ef4444}
.ic-shd{fill:var(--ic-shade)}
.ic-ty{fill:var(--ic-tyre)}
.ic-spk{stroke:var(--ic-tyre);stroke-width:1.1;fill:none;stroke-linecap:round}
.ic-whl{transform-box:fill-box;transform-origin:50% 50%}

/* ---- sprinkle trail (display:none until arrival) ---- */
.ic-trail{position:absolute;inset:0;display:none}
.ic-arriving .ic-trail{display:block}
.ic-sp{position:absolute;left:8px;top:30px;width:8px;height:3.5px;opacity:0;border-radius:2px;background:var(--c)}

/* ---- arrival / idle / exit ---- */
.ic-arriving .ic-btn{animation:ic-drive 1.15s cubic-bezier(.3,.6,.4,1) both;will-change:transform}
.ic-arriving .ic-whl{animation:ic-roll .28s linear 4 both}
.ic-arriving .ic-sp{animation:ic-trail .9s cubic-bezier(.33,.05,.5,1) var(--d) both}
.ic-arriving .ic-ring{animation:ic-ring .8s ease-out 1.2s forwards}
/* Label waits for the truck to park before appearing — telling someone to click
   a truck that is still sliding across the screen reads as noise. Base opacity is
   1, so when .ic-arriving is dropped the label simply stays put with no flash. */
.ic-arriving .ic-cta{animation:ic-in .35s ease 1.15s both}
.ic-idle .ic-svg{animation:ic-bob 3.2s ease-in-out infinite}
.ic-leaving .ic-btn{animation:ic-leave .55s cubic-bezier(.5,0,.9,.4) both}
.ic-leaving .ic-cta{animation:ic-in .2s linear reverse both}
.ic-leaving .ic-whl{animation:ic-roll .3s linear 2 both}
@keyframes ic-drive{0%{opacity:0;transform:translate3d(-120px,0,0) rotate(-2deg)}12%{opacity:1}
  55%{transform:translate3d(6px,0,0) rotate(1.5deg)}70%{transform:translate3d(-3px,-3px,0) rotate(-1deg)}
  84%{transform:translate3d(1px,1px,0) rotate(.5deg)}100%{opacity:1;transform:none}}
@keyframes ic-roll{to{transform:rotate(360deg)}}
@keyframes ic-trail{0%{opacity:0;transform:translate3d(16px,2px,0) scale(.2)}
  14%{opacity:1;transform:translate3d(4px,-2px,0) scale(1) rotate(40deg)}
  55%{opacity:.95;transform:translate3d(calc(var(--dx) * .58),calc(var(--dy) * .3 - 11px),0) rotate(calc(var(--r) * .55))}
  100%{opacity:0;transform:translate3d(var(--dx),var(--dy),0) scale(.55) rotate(var(--r))}}
@keyframes ic-ring{0%{opacity:.8;transform:scale(.8)}100%{opacity:0;transform:scale(1.6)}}
@keyframes ic-bob{0%,100%{transform:translate3d(0,0,0)}50%{transform:translate3d(0,-3px,0)}}
@keyframes ic-leave{0%{opacity:1}100%{opacity:0;transform:translate3d(150px,0,0)}}
@keyframes ic-in{from{opacity:0}to{opacity:1}}

/* ---- card: absolute in .ic-root, flows UPWARD off the one anchor ---- */
.ic-card{
  position:absolute;left:0;bottom:calc(100% + 12px);z-index:20;overflow:hidden;
  width:min(340px,calc(100vw - 32px));display:flex;flex-direction:column;
  max-height:min(520px,calc(100vh - 200px));max-height:min(520px,calc(100dvh - 200px));
  pointer-events:auto;transform-origin:0 100%;background:var(--ic-bg);color:var(--ic-fg);
  border:1px solid var(--ic-line);border-radius:1rem;box-sizing:border-box;
  box-shadow:0 18px 40px -12px var(--ic-glow),0 4px 12px rgba(15,23,42,.14)
}
.ic-card[hidden],.ic-card [hidden]{display:none}
.ic-card.ic-open{animation:ic-pop .28s cubic-bezier(.34,1.28,.64,1) both}
.ic-card.ic-closing{animation:ic-drop .18s ease-in both}
@keyframes ic-pop{0%{opacity:0;transform:translate3d(0,10px,0) scale(.92)}100%{opacity:1;transform:none}}
@keyframes ic-drop{0%{opacity:1}100%{opacity:0;transform:translate3d(0,6px,0) scale(.96)}}

/* card awning stripe, echoing the truck */
.ic-band{flex:none;height:8px;background:repeating-linear-gradient(115deg,
  var(--ic-berry) 0 12px,var(--ic-vanilla) 12px 24px,#6ee7b7 24px 36px,#ffd93d 36px 48px)}
.ic-hd{flex:none;display:flex;align-items:flex-start;gap:.5rem;padding:.75rem .75rem .5rem 1rem}
.ic-ttl{flex:1;margin:0;padding-top:6px;font:800 1.2rem/1.2 var(--font-heading,system-ui,sans-serif);color:var(--ic-fg)}
.ic-x{
  flex:none;width:44px;height:44px;margin:-4px -4px 0 0;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;background:none;border:0;
  border-radius:50%;color:var(--ic-fg2);font-size:26px;line-height:1
}
.ic-bd{flex:1 1 auto;overflow-y:auto;padding:0 1rem .75rem}
.ic-bd > p{margin:0 0 .5rem}
.ic-ttl,.ic-place,.ic-note{overflow-wrap:anywhere}
.ic-live{display:flex;align-items:center;gap:.45rem;font-weight:700;color:var(--ic-hot)}
/* The dot breathes only while the card is open, which is a deliberate few
   seconds — the idle launcher stays perfectly still so a commuter can ignore it. */
.ic-ld{width:10px;height:10px;border-radius:50%;background:#16a34a;animation:ic-ld 2.4s ease-in-out infinite}
@keyframes ic-ld{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.78);opacity:.62}}
.ic-bye,.ic-place{color:var(--ic-fg);font-weight:700}
.ic-place{font-weight:600}
.ic-note,.ic-cd{color:var(--ic-fg2);font-size:.9rem}
.ic-cd{padding:.4rem .6rem;background:var(--ic-line);border-radius:.375rem}
.ic-cdv{color:var(--ic-fg);font-weight:700}

/* ---- mini-map ---- */
.ic-mapw{margin-top:.5rem;border:1px solid var(--ic-line);border-radius:.75rem;overflow:hidden}
.ic-map{width:100%;height:140px;background:var(--ic-line)}

/* ---- CTA: deep strawberry — white on the #ff6b9d accent fails contrast ---- */
.ic-ft{flex:none;padding:.5rem 1rem 1rem}
.ic-go{
  display:flex;align-items:center;justify-content:center;min-height:48px;padding:.6rem 1rem;
  font-size:1rem;font-weight:700;color:#fff;text-decoration:none;border-radius:.75rem;
  background:linear-gradient(135deg,#d6246e,#b3145a);box-shadow:0 4px 12px rgba(179,20,90,.32)
}
.ic-btn:focus-visible,.ic-go:focus-visible,.ic-x:focus-visible{outline:3px solid var(--primary-blue,#1a73e8);outline-offset:3px}
.ic-x:focus-visible{outline-offset:-2px}
/* Hover affordance, gated on (hover:hover) so a tap on a touch device does not
   leave the control stuck in its hover state after the finger lifts. */
@media (hover:hover){
  .ic-btn:hover{transform:translateY(-2px) scale(1.04);box-shadow:0 10px 24px var(--ic-glow),0 2px 5px rgba(15,23,42,.2)}
  .ic-x:hover{background:var(--ic-line);color:var(--ic-fg)}
  .ic-go:hover{filter:brightness(1.07);box-shadow:0 6px 18px rgba(179,20,90,.45)}
}
.ic-x,.ic-go{transition:background .15s ease,color .15s ease,filter .15s ease,box-shadow .15s ease}

/* ---- reduced motion, not reduced function: loops/travel go, open/close becomes a fade ---- */
@media (prefers-reduced-motion:reduce){
  .ic-trail{display:none !important}
  .ic-arriving .ic-whl,.ic-leaving .ic-whl,.ic-arriving .ic-ring,.ic-idle .ic-svg,.ic-ld{animation:none !important}
  .ic-arriving .ic-btn,.ic-arriving .ic-cta,.ic-card.ic-open{animation:ic-in .18s linear both !important;will-change:auto}
  .ic-leaving .ic-btn,.ic-card.ic-closing{animation:ic-in .15s linear reverse both !important}
  .ic-btn,.ic-x,.ic-go{transition:none}
  .ic-btn:hover{transform:none}
}
