/* =============================================================
   COMPONENTS — chrome that appears on every page
   1. Buttons   2. Header + nav   3. Language switcher
   4. Mobile menu   5. Page strip / breadcrumb   6. Scroll progress
   7. Mobile action bar   8. Cards   9. Footer  10. Misc
   ============================================================= */

/* ---------- 1. BUTTONS ---------- */
.btn {
  --btn-bg: var(--sage-deep);
  --btn-fg: var(--white);
  --btn-bd: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-3);
  min-height: 52px;
  padding: var(--sp-3) var(--sp-6);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1.5px solid var(--btn-bd);
  border-radius: var(--r-pill);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: var(--sh-1);
  transition: transform var(--t-fast) var(--ease),
              box-shadow var(--t-base) var(--ease),
              background-color var(--t-base) var(--ease);
}
.btn:hover { color: var(--btn-fg); box-shadow: var(--sh-2); transform: translateY(-1px); }
.btn:active { transform: translateY(0); box-shadow: var(--sh-1); }
.btn svg { width: 20px; height: 20px; flex: none; }

/* On a phone a long label must wrap inside the button rather than push
   the whole page sideways. Malay is the case that needs it: "Tanya
   soalan ini kepada kami melalui WhatsApp" overran a 360px screen by
   28px with nowrap, which let the page scroll horizontally and dragged
   the fixed bottom controls off the edge with it. */
@media (max-width: 767px) {
  .btn { white-space: normal; padding-inline: var(--sp-5); }
}

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--sage-dark); --btn-bd: var(--sage-soft); box-shadow: none; }
.btn--ghost:hover { background: var(--sage-tint); }
.btn--white { --btn-bg: var(--white); --btn-fg: var(--sage-dark); --btn-bd: var(--line); }
.btn--wa    { --btn-bg: var(--whatsapp); --btn-fg: var(--white); }
.btn--gold  { --btn-bg: var(--gold-deep); --btn-fg: var(--white); }
.btn--sm    { min-height: 44px; padding: var(--sp-2) var(--sp-5); font-size: var(--fs-sm); }
.btn--lg    { min-height: 58px; padding: var(--sp-4) var(--sp-7); font-size: var(--fs-lead); }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
@media (max-width: 479px) { .btn-row .btn { width: 100%; } }

/* Quiet text link with arrow */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-weight: 600; text-decoration: none;
  color: var(--sage-deep);
  min-height: 44px;
}
.link-arrow::after { content: "\2192"; transition: transform var(--t-base) var(--ease); }
.link-arrow:hover { text-decoration: underline; }
.link-arrow:hover::after { transform: translateX(4px); }

/* ---------- 2. HEADER ---------- */
.header {
  position: sticky; top: 0; z-index: var(--z-header);
  background: var(--cream);
  border-bottom: 1px solid transparent;
  transition: background-color var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease);
}
.header.is-stuck {
  background: rgba(247,244,238,.86);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom-color: var(--line);
  box-shadow: 0 1px 14px rgba(58,50,42,.06);
}

.header__inner {
  display: flex; align-items: center; gap: var(--sp-4);
  height: var(--header-h);
  transition: height var(--t-base) var(--ease);
}
@media (min-width: 1040px) {
  .header.is-stuck .header__inner { height: var(--header-h-sm); }
}

/* Logo */
.logo { display: inline-flex; align-items: center; gap: var(--sp-3); text-decoration: none; flex: none; }
/* The real logo is a PNG with a transparent background, so it needs a
   fixed box and object-fit rather than the intrinsic sizing an SVG had. */
.logo__mark {
  width: 44px; height: 44px;
  flex: none;
  object-fit: contain;
  transition: width var(--t-base) var(--ease), height var(--t-base) var(--ease);
}
/* On the dark footer and the dark mobile menu the transparent background
   would swallow the artwork, so the mark sits on a cream disc. */
.logo__mark--on-dark {
  background: var(--cream);
  border-radius: 50%;
  padding: 3px;
}
.logo__text { display: flex; flex-direction: column; line-height: 1.1; }
.logo__name {
  font-family: var(--font-head); font-weight: 600;
  font-size: 1.1875rem; color: var(--bark); letter-spacing: -0.01em;
}
.logo__tag {
  font-size: .6875rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); font-weight: 500;
}
@media (min-width: 1040px) {
  .logo__mark { width: 48px; height: 48px; }
  .logo__name { font-size: 1.375rem; }
  /* shrunk header: still comfortably inside the 40-48px range */
  .header.is-stuck .logo__mark { width: 40px; height: 40px; }
}

/* Desktop nav. The full row (logo, eight links, language switcher) starts at
   1040px, not 1024px: at 1024-1035px it was a fraction of a pixel too wide
   in English on the longer labels and scrolled the page 1px sideways. The
   header, logo, burger, language switcher and page strip all switch together. */
.nav { display: none; }
@media (min-width: 1040px) {
  .nav { display: flex; align-items: center; gap: clamp(2px, .6vw, 10px); margin-left: auto; }
  .nav__link {
    display: inline-block;
    padding: var(--sp-2) clamp(6px, .7vw, 12px);
    font-size: clamp(.875rem, .78rem + .12vw, .9375rem);
    font-weight: 500;
    color: var(--bark);
    text-decoration: none;
    border-radius: var(--r-sm);
    white-space: nowrap;
    position: relative;
    transition: color var(--t-fast) var(--ease);
  }
  .nav__link::after {
    content: ""; position: absolute;
    left: clamp(6px,.7vw,12px); right: clamp(6px,.7vw,12px); bottom: 2px;
    height: 2px; border-radius: 2px; background: var(--gold);
    transform: scaleX(0); transform-origin: left;
    transition: transform var(--t-base) var(--ease);
  }
  .nav__link:hover { color: var(--sage-dark); }
  .nav__link:hover::after,
  .nav__link[aria-current="page"]::after { transform: scaleX(1); }
  .nav__link[aria-current="page"] { color: var(--sage-dark); font-weight: 600; }
}

.header__actions { display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }
@media (min-width: 1040px) { .header__actions { margin-left: var(--sp-4); } }
.header__cta { display: none; }
/* The header carries a logo, eight nav items and a three-language
   switcher. Measured, the whole row only fits once the viewport is
   ~1260px. At the old 1180px breakpoint the
   button ran off the right edge of the screen on a 1200px laptop. */
@media (min-width: 1280px) { .header__cta { display: inline-flex; } }
/* Malay is the widest language: longer nav labels plus "Tempah Lawatan"
   on the button itself. Measured, the row still pushed the button
   24px off the right edge of a 1280px screen, so BM waits for 1440px. */
@media (max-width: 1439px) { html[lang="ms"] .header__cta { display: none; } }

/* ---------- 3. LANGUAGE SWITCHER ---------- */
.lang {
  display: none;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: var(--sand);
  border-radius: var(--r-pill);
}
@media (min-width: 1040px) { .lang { display: inline-flex; } }
.lang__btn {
  min-height: 34px; padding: 0 var(--sp-3);
  white-space: nowrap;   /* stops the ZH label breaking between glyphs */
  background: transparent; border: 0; border-radius: var(--r-pill);
  font-size: .8125rem; font-weight: 600; color: var(--muted);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
/* Below 1280px the header row is tight, so the switcher goes compact.
   It keeps nowrap, so the ZH label still sits on one line. */
@media (max-width: 1279px) { .lang__btn { padding: 0 8px; } }
.lang__btn:hover { color: var(--bark); }
.lang__btn[aria-pressed="true"] { background: var(--white); color: var(--sage-dark); box-shadow: var(--sh-1); }

/* ---- the sliding pill ----
   A pseudo-element, so no page markup changes. JS measures the pressed
   button and writes --thumb-x/y/w/h; the pill then glides between them.
   It only switches on once JS has measured (.has-thumb), so with JS off
   the pressed button keeps its own white background, exactly as before. */
.lang { position: relative; }
.lang::before {
  content: "";
  position: absolute; left: 0; top: 0;
  width: var(--thumb-w, 0px);
  height: var(--thumb-h, 0px);
  transform: translate3d(var(--thumb-x, 0px), var(--thumb-y, 0px), 0);
  background: var(--white);
  border-radius: var(--r-pill);
  box-shadow: var(--sh-1);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
}
.lang.has-thumb::before { opacity: 1; }

/* ---- motion is OFF by default, and opt-in ----
   The pill has no transition at all unless .is-animating is present, and
   JS adds that ONLY while a press is being handled. Anything else that
   repositions the pill - a late webfont, a resize, restoring a saved
   language, a back/forward navigation - therefore lands instantly,
   because there is simply no transition to run. Opting in is safer than
   opting out: with the old "transition on, switch it off for this one
   placement" approach, every new caller had to remember to switch it
   off, and one that forgot made the pill slide on page load. */
.lang.is-animating::before {
  transition: transform .3s var(--ease-out),
              width     .3s var(--ease-out),
              height    .3s var(--ease-out);
}
/* Keep the labels above the pill. */
.lang__btn { position: relative; z-index: 1; }
/* Once the pill is doing the work, the button drops its own background. */
.lang.has-thumb .lang__btn[aria-pressed="true"] { background: transparent; box-shadow: none; }
/* A small nudge so a press feels physical. */
.lang.has-thumb .lang__btn:active { transform: scale(.94); }
/* The colour is held back until the pill has almost finished travelling,
   so the label lights up as the pill lands under it rather than before it
   sets off. Like the pill, it only transitions during a real press. */
.lang__btn { transition: transform var(--t-fast) var(--ease); }
.lang.is-animating .lang__btn { transition: background-color var(--t-fast) var(--ease),
                                            color 120ms var(--ease) 200ms,
                                            transform var(--t-fast) var(--ease); }

@media (prefers-reduced-motion: reduce) {
  .lang.is-animating::before,
  .lang.is-animating .lang__btn { transition: none; }
  .lang.has-thumb .lang__btn:active { transform: none; }
}

/* Big version used inside the mobile menu */
.lang--stack { display: flex; width: 100%; padding: var(--sp-1); background: rgba(255,255,255,.14); }
.lang--stack .lang__btn { flex: 1; min-height: 52px; font-size: var(--fs-body); color: #E7E2D6; }
.lang--stack .lang__btn[aria-pressed="true"] { background: var(--white); color: var(--sage-dark); }

/* ---------- 3b. LANGUAGE SWAP TRANSITION ----------
   Only the page's own content dips. The header, the action bar and the
   floating WhatsApp button are all outside these
   elements and must not move a pixel while the text changes. */
.lang-swap { transition: opacity 150ms ease-out, filter 150ms ease-out; }
.lang-swap.is-lang-out { opacity: .3; }
/* Blur is desktop-only: on older phones compositing a full-page blur
   stutters badly, so those get the fade alone. */
@media (min-width: 1024px) {
  .lang-swap.is-lang-out { filter: blur(6px); }
}
/* Coming back is a touch slower, and always lands sharp. */
.lang-swap.is-lang-in {
  transition-duration: 200ms;
  opacity: 1;
  filter: none;
}

@media (prefers-reduced-motion: reduce) {
  .lang-swap,
  .lang-swap.is-lang-in { transition: none; }
  .lang-swap.is-lang-out { opacity: 1; filter: none; }
}

/* ---------- 4. MOBILE MENU ---------- */
.burger {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 48px; height: 48px; padding: 0 12px;
  background: transparent; border: 0; border-radius: var(--r-sm);
  flex: none;
}
@media (min-width: 1040px) { .burger { display: none; } }
/* :not(.sr-only) matters: the button also holds a visually-hidden "Menu"
   label, and this rule used to stretch it to width:100%. Being absolutely
   positioned it resolved against the viewport, making the document 336px
   wider than the phone screen - which scrolled the page sideways and pushed
   every fixed bottom-right control off the edge. */
.burger span:not(.sr-only) {
  display: block; height: 2px; width: 100%; border-radius: 2px;
  background: var(--bark);
  transition: transform var(--t-base) var(--ease), opacity var(--t-fast) var(--ease);
}
.burger[aria-expanded="true"] span:not(.sr-only):nth-of-type(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:not(.sr-only):nth-of-type(2) { opacity: 0; }
.burger[aria-expanded="true"] span:not(.sr-only):nth-of-type(3) { transform: translateY(-7px) rotate(-45deg); }

.menu {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--sage-dark);
  color: #F2EFE7;
  display: flex; flex-direction: column;
  padding: var(--sp-4) 0 calc(var(--sp-6) + var(--safe-b));
  overflow-y: auto; overscroll-behavior: contain;
  opacity: 0; visibility: hidden;
  transform: translateY(-8px);
  /* visibility flips instantly on open and only after the fade on close,
     so the first menu item can take focus straight away */
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              visibility 0s linear var(--t-base);
}
.menu.is-open {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              visibility 0s linear 0s;
}
.menu > .container { display: flex; flex-direction: column; flex: 1; }
.menu__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-5); }
.menu__top .logo__name { color: var(--white); }
.menu__top .logo__tag  { color: #C6CDB9; }
.menu__close {
  width: 48px; height: 48px; background: transparent; border: 0;
  color: var(--white); font-size: 1.75rem; line-height: 1; border-radius: var(--r-sm);
}

.menu__list { list-style: none; margin: 0; padding: 0; }
.menu__list li { margin: 0; border-bottom: 1px solid rgba(255,255,255,.12); }
.menu__link {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 60px; padding: var(--sp-3) 0;
  font-family: var(--font-head); font-size: 1.25rem; font-weight: 500;
  color: #F2EFE7; text-decoration: none;
}
.menu__link[aria-current="page"] { color: var(--gold-soft); }
.menu__link::after { content: "\2192"; opacity: .45; }
.menu__foot { margin-top: auto; padding-top: var(--sp-6); display: grid; gap: var(--sp-3); }

/* ---------- 5. PAGE STRIP (you-are-here) ---------- */
.pagestrip {
  position: sticky; top: var(--header-h); z-index: calc(var(--z-header) - 1);
  background: var(--sand);
  border-bottom: 1px solid var(--line);
  /* Slides up behind the header while the visitor is scrolling down and
     reading, and slides back the moment they scroll up to navigate. */
  transition: transform var(--t-base) var(--ease),
              top var(--t-base) var(--ease);
  will-change: transform;
}
.pagestrip.is-tucked { transform: translateY(calc(-100% - 1px)); }

@media (min-width: 1040px) {
  /* The header shrinks on scroll, so the strip has to follow it up.
     Without this the strip stays pinned at the full header height while
     the header is only var(--header-h-sm) tall, and sliding up by its own
     height leaves a ~22px band of half-cut text showing in the gap. */
  .header.is-stuck ~ .pagestrip { top: var(--header-h-sm); }
}
.pagestrip__inner {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: 44px;
  font-size: var(--fs-sm); color: var(--muted);
  overflow-x: auto; scrollbar-width: none; white-space: nowrap;
}
.pagestrip__inner::-webkit-scrollbar { display: none; }
.pagestrip a { color: var(--muted); text-decoration: none; }
.pagestrip a:hover { text-decoration: underline; }
.pagestrip__sep { opacity: .5; }
.pagestrip__here { color: var(--bark); font-weight: 600; }

/* ---------- 6. SCROLL PROGRESS ---------- */
.progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: calc(var(--z-header) + 1);
  background: transparent; pointer-events: none;
}
.progress__bar {
  height: 100%; width: 100%;
  transform-origin: 0 50%; transform: scaleX(0);
  background: linear-gradient(90deg, var(--sage), var(--gold));
}

/* ---------- 7. MOBILE ACTION BAR — never hides ----------
   One continuous surface rather than three coloured blocks: the blocks
   read as a toolbar bolted onto the page. Colour now lives in the icons,
   and only "Book Visit" is filled, because it is the one primary action.
   Still three separate one-tap targets - hiding the phone number behind
   a menu would cost a tap at exactly the wrong moment. */
.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: var(--z-bar);
  display: grid; grid-template-columns: repeat(3, 1fr);
  align-items: stretch;
  background: var(--white);
  border-top: 1px solid var(--line);
  padding-bottom: var(--safe-b);
  box-shadow: 0 -4px 22px rgba(58, 50, 42, .07);
}
@media (min-width: 1024px) { .actionbar { display: none; } }
/* Out of the way of the hero on first load: main.js adds --waiting until the
   visitor has scrolled 150px. Without JS it is never added. */
.actionbar { transition: transform 280ms var(--ease), visibility 0s; }
.actionbar--waiting { transform: translateY(100%); visibility: hidden; transition: transform 200ms var(--ease), visibility 0s linear 200ms; }
@media (prefers-reduced-motion: reduce) { .actionbar, .actionbar--waiting { transition: none; } }

.actionbar__btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  min-height: 64px;
  padding: var(--sp-2) var(--sp-1);
  background: transparent;
  color: var(--bark);
  font-size: .75rem; font-weight: 600; letter-spacing: .01em;
  text-decoration: none;
  border: 0;
  transition: background-color var(--t-fast) var(--ease);
}
.actionbar__btn svg { width: 23px; height: 23px; color: var(--sage-deep); }
.actionbar__btn--wa svg { color: var(--whatsapp); }
.actionbar__btn:active { background: var(--cream); }

/* the one filled action, inset so it reads as a button inside the bar
   rather than a third slab. 50px tall, so still a comfortable target. */
.actionbar__btn--book {
  margin: 7px 10px 7px 3px;
  min-height: 50px;
  border-radius: var(--r-md);
  background: var(--sage-deep);
  color: var(--white);
}
.actionbar__btn--book svg { color: var(--white); }
.actionbar__btn--book:active { background: var(--sage-dark); }

/* ---------- 8. CARDS ---------- */
.card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--white);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  overflow: hidden;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.card__body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); flex: 1; }
.card__body > * { margin: 0; }
.card h3 { margin: 0; }
.card p { color: var(--muted); }
.card__frame { overflow: hidden; aspect-ratio: 4/3; background: var(--sand); }
.card__frame img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease); }

@media (hover: hover) and (min-width: 1024px) {
  .card--lift:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
  .card--lift:hover .card__frame img { transform: scale(1.05); }
}
/* Whole-card link without nesting interactive elements */
.card__link::after { content: ""; position: absolute; inset: 0; }
.card:focus-within { box-shadow: var(--sh-2); }
.card--tint { background: var(--sage-tint); box-shadow: none; border: 1px solid rgba(126,143,111,.22); }
/* A text-only card (no photo yet) runs the full width of its grid under the
   photo cards, instead of sitting beside one with an empty gap below it. */
.card--wide { grid-column: 1 / -1; }
.card--wide .card__body p { max-width: 70ch; }

/* Icon bubble */
.ibubble {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; flex: none;
  border-radius: var(--r-md);
  background: var(--sage-tint);
  color: var(--sage-dark);
}
.ibubble svg { width: 27px; height: 27px; }
.ibubble--gold { background: var(--gold-soft); color: #6E5608; }

/* ---------- 9. FOOTER ---------- */
.footer {
  background: var(--sage-dark);
  color: #DCDCD2;
  padding-block: var(--sp-9) var(--sp-6);
  font-size: var(--fs-sm);
  line-height: 1.65;
}
.footer h2, .footer h3 { color: var(--white); }
.footer a { color: #E8E5DA; text-decoration: none; }
.footer a:hover { color: var(--white); text-decoration: underline; }
.footer__grid { display: grid; gap: var(--sp-7); }
@media (min-width: 720px)  { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1024px) { .footer__grid { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: var(--sp-8); } }
.footer__title {
  font-family: var(--font-body); font-size: .8125rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--gold-soft);
  margin-bottom: var(--sp-4);
}
.footer__list { list-style: none; margin: 0; padding: 0; }
.footer__list li { margin-bottom: var(--sp-2); }
.footer__list a { display: inline-block; padding-block: 4px; }
.footer__bottom {
  margin-top: var(--sp-8); padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,.14);
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  justify-content: space-between;
  font-size: var(--fs-xs); color: #B9BCAC;
}
.footer .logo__name { color: var(--white); }
.footer .logo__tag { color: #C6CDB9; }
.footer__blurb { max-width: 38ch; margin-top: var(--sp-4); color: #D2D3C7; }
.footer__contact { display: grid; gap: var(--sp-3); margin: 0; }
.footer__contact dt { font-size: var(--fs-xs); letter-spacing: .08em; text-transform: uppercase; color: #A8AE99; }
.footer__contact dd { margin: 2px 0 0; }

/* ---------- 10. MISC ---------- */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  max-width: 100%;
  padding: 6px var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--sage-tint); color: var(--sage-dark);
  font-size: var(--fs-sm); font-weight: 600;
}
.badge svg { width: 16px; height: 16px; flex: none; }
.badge .placeholder { white-space: normal; }
.badge--light { background: rgba(255,255,255,.92); color: var(--sage-dark); box-shadow: var(--sh-1); }

.wa-float { display: none; }
@media (min-width: 1024px) {
  .wa-float {
    position: fixed; right: 24px; bottom: 24px; z-index: var(--z-bar);
    display: inline-flex; align-items: center; gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-5);
    background: var(--whatsapp); color: var(--white);
    border-radius: var(--r-pill); box-shadow: var(--sh-3);
    font-weight: 600; text-decoration: none;
    transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
  }
  .wa-float svg { width: 24px; height: 24px; }
  .wa-float:hover { color: var(--white); transform: translateY(-2px); }
}

/* ---------- 11. BACK TO TOP ----------
   Appears once the visitor is a screen or two down, so a long page never
   means a long scroll back. Sits clear of the mobile action bar on phones
   and above the WhatsApp pill on desktop. */
.to-top {
  position: fixed;
  right: 16px;
  z-index: var(--z-bar);
  bottom: calc(var(--actionbar-h) + var(--safe-b) + 14px);
  width: 48px; height: 48px;
  display: grid; place-items: center;
  background: var(--white);
  color: var(--sage-dark);
  border: 1px solid var(--line);
  border-radius: 50%;
  box-shadow: var(--sh-2);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              visibility 0s linear var(--t-base);
}
.to-top.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              visibility 0s linear 0s;
}
.to-top:hover { background: var(--cream); color: var(--bark); }
.to-top svg { width: 22px; height: 22px; }

@media (min-width: 1024px) {
  /* clear of the floating WhatsApp pill */
  .to-top { right: 24px; bottom: 92px; width: 52px; height: 52px; }
}
