/* HBE Yakabit theme — lifted verbatim from index.html.
   Generated by odoo/scripts/port_page.py. Edit index.html and re-run rather
   than editing this file, or the two versions drift.

   Plain CSS on purpose, not .scss. The stylesheet uses CSS min()/max(), which
   Sass claims as its own functions and then rejects for mixing units — the
   port is meant to be byte-identical to what the browser gets today, so it
   goes through no compiler at all. */

    body {
      margin: 0;
      padding: 0;
      font: 14px -apple-system, BlinkMacSystemFont, sans-serif
    }

    img {
      max-width: 100%
    }
  

/* --- assets/css/cart-indicator.css (linked, inlined by port_page.py) --- */
/* The header's cart button, compact.
   ==========================================================================
   The prototype styled this as a .cta-btn — the same wide pill as Sales
   Request, reading "Cart ( 1 )". Its own README records that the site's nav
   already overruns its box by about 70px at 1440px, and that is what the pill
   collided with: it sat on top of Videos, the last nav item.

   So the label goes and the count becomes a badge on the icon. That takes the
   control from roughly 110px to 34px, which is less than the nav was already
   overrunning by, so the collision cannot come back at this width.

   Tokens are read with a fallback because this stylesheet loads alongside the
   site's own CSS — a different page stylesheet on every page — and the custom
   properties come from whichever of those got there first.

   Shared with the Odoo site, which serves this file from hbe_product. The
   only difference is the note on the breakpoint below: there the cart is in
   every page's header, here it is in the four shop screens' headers. */

.cart-btn.cart-mini {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* A fixed square, and flex:none so a tight header shrinks the nav rather
     than squashing the button into an ellipse. */
  width: 34px;
  height: 34px;
  flex: none;
  padding: 0;
  margin: 0 6px 0 2px;
  /* On the utility bar's blue, not the header's cream: the button is drawn
     in the bar's own foreground colour the way Contact Us beside it is,
     rather than as a white chip stuck onto the blue. */
  border: 1px solid rgba(255, 255, 255, .38);
  border-radius: 50%;
  background: rgba(255, 255, 255, .08);
  color: #fff;
  text-decoration: none;
  transition: border-color .12s, background .12s;
}

.cart-btn.cart-mini:hover,
.cart-btn.cart-mini:focus-visible {
  border-color: #fff;
  background: rgba(255, 255, 255, .18);
  color: #fff;
}

.cart-btn.cart-mini svg {
  width: 18px;
  height: 18px;
  /* The pill's rules sized the icon against a text label that is gone. */
  margin: 0;
}

/* The count. A circle on the corner of the icon rather than a figure beside
   it: it has to be readable at a glance without taking a word's worth of
   width. min-width plus padding so 1 stays round and 12 stays legible. */
.cart-btn.cart-mini .cart-count {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 999px;
  /* The site's own blue would disappear into the bar it sits on. Magenta is
     the site's other brand colour and the one it already uses on this bar
     for the "Us" in Contact Us. */
  background: var(--magenta, #eb008b);
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  line-height: 17px;
  letter-spacing: 0;
  text-align: center;
  font-variant-numeric: tabular-nums;
  /* No ring: on the utility bar there is no pale ground to separate it
     from, and a cream ring would read as a sticker on the blue. */
}

/* An empty cart gets no badge. The page is served with 0 in it and shop.js
   paints the real figure on load, so this is also what stops a 0 flashing
   before the cart has been read. */
.cart-btn.cart-mini[data-count="0"] .cart-count,
.cart-btn.cart-mini:not([data-count]) .cart-count {
  display: none;
}

/* One nav rule, for the widest windows only.
   ==========================================================================
   The page is capped at --maxw (1400px), so above about 1440px a wider
   window buys the header nothing — the wrap stops growing. The site's nav
   keeps its loosest spacing until 1680px, which is fine for ten items in
   that box and one too many for eleven: at 1700px the last item runs into
   the Sales Request button.

   So the 1680px step is taken from 1681px up instead. It is the site's own
   next value, not a new one, and it only ever applies where extra window
   width is already doing nothing for the row.

   Unscoped, because this stylesheet is on every page now and so is the Shop
   item that needs the room. */
@media (min-width: 1681px) {
  /* header.site is a longer selector than the site's own `nav.main > a`,
     and it has to be: every page keeps its CSS in a <style> block in the
     body, which lands after this file's <link> in the head, so an
     equal-specificity rule here would lose on source order alone. */
  header.site nav.main > a,
  header.site nav.main .has-mega > a {
    padding: 0 12px;
  }
}

/* Nothing else here touches the nav.
   ==========================================================================
   Earlier versions did, in two heavier ways, and both were wrong.

   The first hid the nav below 1360px and handed it to the hamburger, so
   these four pages dropped their menus at widths where every other page on
   the site still showed them. The second tried to buy the space back by
   stepping the nav's own size ladder down harder, which is re-tuning a
   layout this file does not own: below 1520px the site runs the nav as one
   line of flex:none, nowrap items sized by a ladder written for exactly ten
   of them, so extra width does not compress, it spills out of the nav's box
   and lands on whatever is beside it.

   Neither is needed now. The cart is in the utility bar, a row up, and the
   nav carries its ten items plus Shop with the site's own ladder untouched. */

@media (max-width: 860px) {
  .cart-btn.cart-mini {
    width: 30px;
    height: 30px;
    margin: 0 6px 0 2px;
  }
  .cart-btn.cart-mini svg { width: 16px; height: 16px; }
  .cart-btn.cart-mini .cart-count {
    min-width: 15px;
    height: 15px;
    line-height: 15px;
    font-size: 9px;
    top: -4px;
    right: -4px;
  }
}

/* --- assets/css/account-indicator.css (linked, inlined by port_page.py) --- */
/* The header's Account button and its dropdown.
   ==========================================================================
   Loaded on every page, beside cart-indicator.css, because the control is in
   every page's utility bar. The account SCREENS are styled by account.css,
   which only those pages load.

   The button is deliberately the cart button's twin — same 34px circle, same
   border, same hover — because they sit next to each other and two controls
   a pixel apart that are almost the same read as a mistake. The only
   difference is the glyph and that this one opens a panel instead of going
   somewhere.

   Tokens are read with a fallback, as cart-indicator.css does: this loads
   alongside whichever page stylesheet got there first, and the custom
   properties come from that.

   Shared with the Odoo site. */

/* ---- the control ---- */

.acct-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  padding: 0;
  margin: 0 2px 0 2px;
  border: 1px solid rgba(255, 255, 255, .38);
  border-radius: 50%;
  background: rgba(255, 255, 255, .08);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
  transition: border-color .12s, background .12s;
}

.acct-btn:hover,
.acct-btn:focus-visible,
.acct-wrap.is-open .acct-btn {
  border-color: #fff;
  background: rgba(255, 255, 255, .18);
  color: #fff;
}

.acct-btn svg {
  width: 18px;
  height: 18px;
  margin: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A signed-in customer gets a filled dot on the glyph — the same corner the
   cart puts its count on, so the two controls report their state the same
   way. No initials: at 34px a letter is unreadable and a name is private. */
.acct-btn::after {
  content: "";
  position: absolute;
  top: -1px;
  right: -1px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--magenta, #eb008b);
  border: 2px solid var(--blue-deep, #005e87);
  opacity: 0;
  transform: scale(.4);
  transition: opacity .14s, transform .14s;
}

.acct-wrap[data-signed-in="true"] .acct-btn::after {
  opacity: 1;
  transform: none;
}

/* ---- the panel ---- */

.acct-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* Fixed, not absolute, and placed by script.

   The utility bar this control sits in is `overflow: hidden` — it has to be,
   to contain the gradient and the white logo plate that overhangs it — so an
   absolutely positioned panel is cut off at the bar's own 44px. A fixed
   panel is positioned against the viewport and an overflow ancestor does not
   clip it, which is why account-menu.js measures the button and sets top and
   left on open. Checked: nothing above .acct-wrap carries a transform, a
   filter or a perspective, any of which would have made this element
   containing-block-relative again and put us back where we started. */
.acct-menu {
  position: fixed;
  z-index: 120;
  width: 244px;
  padding: 8px;
  border-radius: 14px;
  border: 1px solid var(--line, #e6e0d6);
  background: var(--surface, #fff);
  box-shadow: 0 2px 6px rgba(20, 30, 40, .06), 0 18px 44px rgba(20, 30, 40, .16);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .14s, transform .14s, visibility .14s;
  /* the utility bar is short; the panel must not inherit its centring */
  text-align: left;
}

.acct-wrap.is-open .acct-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* The greeting. One line, and the name is allowed to truncate rather than
   wrap the panel into two heights depending on whose account it is. */
.acct-menu-head {
  padding: 10px 12px 12px;
  border-bottom: 1px solid var(--line, #e6e0d6);
  margin-bottom: 6px;
}

.acct-menu-hi {
  display: block;
  font-size: 15px;
  font-weight: 800;
  color: var(--ink, #1d2328);
  letter-spacing: -.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.acct-menu-sub {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-faint, #79828a);
}

.acct-menu a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 12px;
  border-radius: 9px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft, #4d565e);
  text-decoration: none;
  transition: background .1s, color .1s;
}

.acct-menu a:hover,
.acct-menu a:focus-visible {
  background: var(--surface-2, #f2ede5);
  color: var(--blue, #0076af);
}

.acct-menu a svg {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--ink-faint, #79828a);
}

.acct-menu a:hover svg,
.acct-menu a:focus-visible svg {
  color: inherit;
}

/* Sign Out is a different kind of action from the eight links above it, so
   it gets the rule rather than a colour — red here would be the only red on
   the site, and signing out is not destructive. */
.acct-menu-cut {
  height: 1px;
  margin: 6px 12px;
  background: var(--line, #e6e0d6);
}

/* ---- the two buttons a signed-out panel ends with ----

   Styled here in full rather than leaning on the site's .buybtn and
   .btn-outline. Those are defined in each page's own inline stylesheet, and
   not every page has them: the product pages style a.buybtn, the home page
   has no product hero and so never needed it. A dropdown that is in all 87
   headers cannot assume the page under it brought a button along — on the
   home page both of these rendered as plain centred text.

   The values are the site's own, so the pair looks the same as every other
   primary/secondary pair on the site; they are just not borrowed. */

.acct-menu-cta {
  padding: 4px 4px 2px;
}

.acct-menu-cta a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 34px;
  margin-bottom: 8px;
  padding: 0 14px;
  border-radius: 40px;
  box-sizing: border-box;
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
  transition: background .14s, border-color .14s, color .14s;
}

.acct-menu-cta a.buybtn {
  background: var(--blue, #0076af);
  border: 1px solid var(--blue, #0076af);
  color: #fff;
}

.acct-menu-cta a.buybtn:hover {
  background: var(--blue-deep, #005e87);
  border-color: var(--blue-deep, #005e87);
  color: #fff;
}

.acct-menu-cta a.btn-outline {
  background: var(--surface, #fff);
  border: 1px solid var(--line, #e6e0d6);
  color: var(--ink, #1d2328);
}

.acct-menu-cta a.btn-outline:hover {
  border-color: var(--blue, #0076af);
  color: var(--blue, #0076af);
}

/* ---- mobile ----
   Hover is not available and a 244px panel pinned to a 34px button near the
   right edge of a 360px screen would hang off it. Below 720px the panel
   becomes a sheet: full width, under the bar, still opened by the same
   click and closed by the same outside-click. */
@media (max-width: 720px) {
  .acct-menu {
    position: fixed;
    top: auto;
    left: 8px;
    right: 8px;
    width: auto;
    max-height: min(78vh, 560px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 16px;
  }

  .acct-menu a {
    /* a comfortable tap target, which 32px is not */
    padding: 12px;
    font-size: 15px;
  }
}

@media (prefers-reduced-motion: reduce) {

  .acct-menu,
  .acct-btn::after {
    transition: none;
  }
}

    :root {
      --blue: #0076af;
      --blue-deep: #005e87;
      --blue-ink: #0a4d70;
      --magenta: #eb008b;
      --magenta-deep: #c30074;
      --magenta-ink: #b3006b;
      /* text-safe magenta for labels/links on light bg (AA) */
      /* Ooma-matched: warm cream ground, white cards, slate footer */
      --bg: #faf7f2;
      --surface: #ffffff;
      --surface-2: #f2ede5;
      --ink: #1d2328;
      --ink-soft: #4d565e;
      --ink-faint: #79828a;
      --line: #e6e0d6;
      --line-soft: #f0ebe3;
      --charcoal: #2f3d47;
      /* Ooma slate footer */
      --warn: #b3441f;
      --good: #1f7d52;
      --warn-ink: #9c3a19;
      --good-ink: #16663f;
      --shadow-sm: 0 1px 2px rgba(20, 30, 40, .05), 0 3px 12px rgba(20, 30, 40, .05);
      --shadow-md: 0 2px 6px rgba(20, 30, 40, .07), 0 16px 38px rgba(20, 30, 40, .09);
      --r: 12px;
      --maxw: 1400px;
      --logo-plate-end: 232px; /* util .logo padding + 85px-tall img + padding */
      --hero-grad: linear-gradient(115deg, #0076af 0%, #0a5f8c 55%, #083d5c 100%);
    }

    @media (prefers-color-scheme:dark) {
      :root {
        --bg: #0c151b;
        --surface: #14212a;
        --surface-2: #1b2b35;
        --ink: #e8eef2;
        --ink-soft: #aab8c2;
        --ink-faint: #71828d;
        --line: #283a45;
        --line-soft: #20303a;
        --charcoal: #0a1218;
        --blue: #4fb0e0;
        --blue-deep: #7cc8ec;
        --blue-ink: #9fd6ef;
        --magenta: #ff5fb0;
        --magenta-deep: #ff8ac8;
        --magenta-ink: #ff7cc0;
        --warn: #e8804f;
        --good: #4fc48a;
        --warn-ink: #f0946a;
        --good-ink: #6fd6a2;
        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 14px rgba(0, 0, 0, .28);
        --shadow-md: 0 2px 6px rgba(0, 0, 0, .35), 0 18px 40px rgba(0, 0, 0, .4);
        --hero-grad: linear-gradient(115deg, #0a5075 0%, #0a3d5a 55%, #07293c 100%);
      }
    }

    :root[data-theme="light"] {
      --bg: #faf7f2;
      --surface: #ffffff;
      --surface-2: #f2ede5;
      --ink: #1d2328;
      --ink-soft: #4d565e;
      --ink-faint: #79828a;
      --line: #e6e0d6;
      --line-soft: #f0ebe3;
      --charcoal: #2f3d47;
      --blue: #0076af;
      --blue-deep: #005e87;
      --blue-ink: #0a4d70;
      --magenta: #eb008b;
      --magenta-deep: #c30074;
      --magenta-ink: #b3006b;
      --warn: #b3441f;
      --good: #1f7d52;
      --warn-ink: #9c3a19;
      --good-ink: #16663f;
      --shadow-sm: 0 1px 2px rgba(20, 30, 40, .05), 0 3px 12px rgba(20, 30, 40, .05);
      --shadow-md: 0 2px 6px rgba(20, 30, 40, .07), 0 16px 38px rgba(20, 30, 40, .09);
      --hero-grad: linear-gradient(115deg, #0076af 0%, #0a5f8c 55%, #083d5c 100%);
    }

    :root[data-theme="dark"] {
      --bg: #0c151b;
      --surface: #14212a;
      --surface-2: #1b2b35;
      --ink: #e8eef2;
      --ink-soft: #aab8c2;
      --ink-faint: #71828d;
      --line: #283a45;
      --line-soft: #20303a;
      --charcoal: #0a1218;
      --blue: #4fb0e0;
      --blue-deep: #7cc8ec;
      --blue-ink: #9fd6ef;
      --magenta: #ff5fb0;
      --magenta-deep: #ff8ac8;
      --magenta-ink: #ff7cc0;
      --warn: #e8804f;
      --good: #4fc48a;
      --warn-ink: #f0946a;
      --good-ink: #6fd6a2;
      --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 14px rgba(0, 0, 0, .28);
      --shadow-md: 0 2px 6px rgba(0, 0, 0, .35), 0 18px 40px rgba(0, 0, 0, .4);
      --hero-grad: linear-gradient(115deg, #0a5075 0%, #0a3d5a 55%, #07293c 100%);
    }

    * {
      box-sizing: border-box;
    }

    html {
      scroll-behavior: smooth;
    }

    body {
      margin: 0;
      background: var(--bg);
      color: var(--ink);
      font-family: "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
      line-height: 1.62;
      -webkit-font-smoothing: antialiased;
    }

    .brandface {
      font-style: italic;
      font-weight: 800;
      letter-spacing: -.01em;
    }

    /* Ooma-style serif display type */
    /* Nunito ExtraBold, subset to the header headline glyphs (~2KB, embedded so the page stays self-contained) */
    @font-face {
      font-family: "HeadlineSans";
      font-style: normal;
      font-weight: 800;
      font-display: swap;
      src: url(data:font/woff2;base64,d09GMgABAAAAAAeoAA8AAAAADkQAAAdOAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbg0YcZAZgP1NUQVREAIEMEQgKjHiKLgsoAAE2AiQDTAQgBYRAByAb0QsR1aweyDRSFs7fzw/dvt4kfEuA3T1TTkSsgxbKM9fKkaI5ER+DcLMGqFLVAxqywUTqVAWpUNEXdfX51lqdvTtcok5IhEhIRFLb/Tu3Nqh5IvJoPCLe3JLZ65oIiUimkhOlVpaxyZzCu7SxEHHWuzEIgImJLpw0ghZpFvIFwk9WqInmkJ279h6MIpNWLJwN/rMnLJ4bDyO58t6oN2vKwrnIXuV9gAGBbB6NhwLjt9zmUH1SsJDD5i9xDBbHf6ZjflkJfFwHo8k5AbZr7Pe4cf4jW9jzs0T+hyX8gV9TaQbXgueHdJQQyCCNLAdVaYCBUSk3JAWpmwiZDIVULPYZWaSL5La7TKAyikGggIala97QQgFspLswqgj3aYve5po2VXsCNHhgLweqG6OgBG7Jmj573qTZncrO0JrpAOPKDTFJOvrlCV8MF5G9zsvQWJShiiR12wbB/eH0cp/Qt1/fLrgGB/Pkl/9bWTujCdV2QGvD8+ipuI7cIQHKKgSAIkdSOX/ZtOmLq1E+Y/GE2RSHwQipDEEV8o2ifRUoK52hLQKX2SGDs4eB5U8thXxIKDjoiO7ojyGYgEmYgmmYgdmYRwELD98Pg8ncO/MnvsoX+BQf5z28m3fxTt7BO3g7jQNuRKggZuRxXjhOqEpK2ovScWKliLGfyUhhkJVmtpVdcldhIcJ7kGEUz+WcQnbhXPHyzWrUrm3bpl2qciHbHJKx0hOtjKn9K5TyrmodRBHcsDOdjlJDdfCAvPtKkYgakqhRcBmwCHYw3EvKv0JkguVO8OMYspIkKaRWGA4NkgRWipUfhnCjIaVI9mWUgntplA6ekPdYqQn+FZJ4oHdVW8FluJeUEvllxiTVLCHcSAeJKyMMhyh77pNEayj/1j64l3Vw8SiRd0X5txrvOnPAO1rtYlWiUMkIRTddu3dKi92bN+3bVXXPGeWfO3RscqQOzlbbu3v/5k2Vz4WJJBvGnLNPmaSLeCc+dBf3qGdugBx5nNxquaa99bKrzr/6cnLnqwZVssrOeYWb1XjZydnTzKp0wfDRT99MicsTN6g1SrxnvAFku5/Qif1HNQO594unl51+Jg64gj7lEpkpwLu5tqBhxheAAzpm9N0ajC5U+Sk1N2+esDmmkdfIcYboTBFfdKbop1hWZuy2uEID31WHy7sGQ+MHZtbuXLvUvp9Sua/90vVTrHvLZXtbT8EpJcwuo2N2GbLLvBJ+hdklzC6jY3bdH/Ze+D0mi2O5mXOGUxcv9aoPGRk/QJfMnT2UumipV3PoyMT+uuTBth6jPBNentoZsvYaZOnI0tReOT5OJjqc+Xlr/61cbv/trctvZ7LMfsfaP9XrP7YfC3vk/4F/3civ4fGr+f/yq/m8Gv6NfzFZbHBja0wixqzF+0TbDNkW9acSqWg0nkr1i7YJSYv65vxHHObD+1xjv0QVUhj327c1Y0jqdV9d2dQ+Q/Y8dR5vXb6hbvtmfKi1XahOf9RTIUxMyzWjkfeIiaJChMx1T94FMbdry+la77QJx/yeKcrOD1TWmD/QRv+wSI+s5b30EYfyuqO22h2r5U8p9YG42lcJM3dgH6d3LRl3ra25I4Z+yuHmj1rq1pqsyX/+lWw93UE09ytK4sFQsPnta3JGS0d1tLavFuQ+43RNd1YljP3VdHO0rM39pz1e+u2YxeKdshuWIybe0PFdlMY2bP72fAuZp+kUWd77sH32tlFVd0mcdr+W4l0lcdoCOLSY5EQpcY7QOXFKNEzHpY/R5DGp9DZC3xaxA77iDg1MTz/MzLOPn2fulTB7Sl4s+fExirffISechENLSJrMkHkhnSKWCyaH9VZbTE6Ggx+TNKHT5B1dnFEfrX0uAcLt3HC4GugdvBOUrXPD4V7ttNNjPt8kZV3p+P8+TcTm1wgqrtNEbEFE6DlKOEOTXqGwD0XMC6+qGLU47BO0j/X/P/Ai+43//77gbXoW56w9j1iW75iosv9awuF8wfLfbrr01emu72kvNfz3y3+fFvYU0IAvk/UbwL4ray4c/++X/z4p7Hkrv0Ad6xdo2bcjxClHiNMOLfsMhNg7///L/hxetgI06z1QbAKKnQbFKoeKxbh1TxIO7N6KBChW0/eS31pwwzpMoxj5b3mfDftyppfjtPe5UfAflHURq+ROWRDgC8pGJd6iHBhxyeiCeFqIVhxFiyBALqQSRugNlpoosSWwbNppCWrB1Tv4RYAe5LGEKSwjgB1sYA128yKPRcwigg1x/iKymMEA5pBFGhls7NtuYAXrsELFd1vHDNaQxQo2UFcuRfhti1AijzWkoUIngogjiU0sI4sN5KFQVJHCHNayfTePZQiggxJGqKG9hrYhiU4kERhCUULP6mlsYhFTWJMMS9DQhzxWsGsCM/AnCaCFGhroIUAfMpiDoAC9CxvmkcMcZkSGB5vEwGR9HccXk8TT2TpmsIlpKDFDO0LS8shjxSLmMG84KJyswrIiLvl7kaaz/X8D2rEBAA==) format("woff2");
    }

    :root {
      --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", "Times New Roman", Georgia, serif;
    }

    .band h2,
    .switch-title,
    .hero h1,
    .mobile-head h2,
    .soft-head h2,
    .srcard h2 {
      font-family: var(--serif);
      font-weight: 600;
      letter-spacing: -.015em;
      line-height: 1.14;
    }

    .band h2 em,
    .switch-title .focus {
      font-style: normal;
    }

    .wrap {
      max-width: var(--maxw);
      margin: 0 auto;
      padding: 0 26px;
    }

    h1,
    h2,
    h3 {
      letter-spacing: -.02em;
      text-wrap: balance;
      line-height: 1.08;
    }

    section {
      position: relative;
    }

    a {
      color: inherit;
    }

    /* ============ SCROLL REVEAL + MOTION ============ */
    [data-reveal] {
      opacity: 0;
      transform: translateY(26px);
      transition: opacity .7s cubic-bezier(.22, .61, .36, 1), transform .7s cubic-bezier(.22, .61, .36, 1);
    }

    [data-reveal].in {
      opacity: 1;
      transform: none;
    }

    [data-reveal="left"] {
      transform: translateX(-34px);
    }

    [data-reveal="right"] {
      transform: translateX(34px);
    }

    [data-reveal="zoom"] {
      transform: scale(.92);
    }

    [data-reveal="left"].in,
    [data-reveal="right"].in,
    [data-reveal="zoom"].in {
      transform: none;
    }

    /* stagger children */
    [data-stagger]>* {
      opacity: 0;
      transform: translateY(20px);
      transition: opacity .6s ease, transform .6s cubic-bezier(.22, .61, .36, 1);
    }

    [data-stagger].in>* {
      opacity: 1;
      transform: none;
    }

    [data-stagger].in>*:nth-child(1) {
      transition-delay: .05s;
    }

    [data-stagger].in>*:nth-child(2) {
      transition-delay: .13s;
    }

    [data-stagger].in>*:nth-child(3) {
      transition-delay: .21s;
    }

    [data-stagger].in>*:nth-child(4) {
      transition-delay: .29s;
    }

    [data-stagger].in>*:nth-child(5) {
      transition-delay: .37s;
    }

    [data-stagger].in>*:nth-child(6) {
      transition-delay: .45s;
    }

    /* the hero's seventh proof point; without its own delay it would inherit
       none and land before the six above it */
    [data-stagger].in>*:nth-child(7) {
      transition-delay: .53s;
    }

    /* image reveal: subtle clip + zoom */
    .reveal-img {
      overflow: hidden;
    }

    .reveal-img img {
      transition: transform .9s cubic-bezier(.22, .61, .36, 1);
    }

    .reveal-img.in img {
      animation: imgIn 1.1s cubic-bezier(.22, .61, .36, 1) both;
    }

    @keyframes imgIn {
      from {
        transform: scale(1.12);
        opacity: .4;
      }

      to {
        transform: scale(1);
        opacity: 1;
      }
    }

    @media (prefers-reduced-motion:reduce) {

      [data-reveal],
      [data-stagger]>* {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
      }

      .reveal-img.in img {
        animation: none;
      }

      * {
        scroll-behavior: auto;
      }
    }

    /* ===== design-variation switcher (client review tool) ===== */
    .vswitch {
      background: #141a1f;
      color: #cfd6dc;
      font-size: 12.5px;
      position: relative;
      z-index: 60;
    }

    .vswitch .wrap {
      display: flex;
      align-items: center;
      gap: 14px 18px;
      flex-wrap: wrap;
      padding: 11px 26px;
    }

    .vswitch .vs-lbl {
      font-weight: 800;
      letter-spacing: .09em;
      text-transform: uppercase;
      font-size: 10.5px;
      color: #8fa3b3;
    }

    .vswitch .vs-links {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
    }

    .vswitch a {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      text-decoration: none;
      color: #cfd6dc;
      border: 1px solid #2b353d;
      background: #1c242b;
      padding: 6px 14px;
      border-radius: 30px;
      font-weight: 600;
      transition: .15s;
    }

    .vswitch a:hover {
      border-color: #4a5a66;
      color: #fff;
    }

    .vswitch a.on {
      background: #fff;
      color: #141a1f;
      border-color: #fff;
    }

    .vswitch a i {
      font-style: normal;
      font-size: 10px;
      font-weight: 800;
      letter-spacing: .06em;
      opacity: .75;
    }

    .vswitch .vs-note {
      margin-left: auto;
      color: #7f8f9c;
      font-size: 11.5px;
    }

    @media (max-width:700px) {
      .vswitch .vs-note {
        display: none;
      }
    }

    /* ============ BLUE HEADER (real logo + badges + headline + contact) ============ */
    .util {
      background: var(--hero-grad);
      color: #eaf6ff;
      font-size: 13px;
      overflow: hidden;
      /* thin divider under the utility bar so the white logo plate doesn't blend
         into the white nav menu below it */
      border-bottom: 0.5px solid var(--blue);
    }

    @media (prefers-color-scheme:dark) {
      .util {
        background: linear-gradient(115deg, #0a3d5a, #07293c);
      }
    }

    :root[data-theme="dark"] .util {
      background: linear-gradient(115deg, #0a3d5a, #07293c);
    }

    .util .wrap {
      display: flex;
      gap: 24px;
      align-items: center;
      justify-content: space-between;
      min-height: 92px;
      padding-top: 12px;
      padding-bottom: 12px;
    }

    .util-left {
      display: flex;
      align-items: center;
      align-self: stretch;
      gap: 24px;
      flex: none;
      /* full-bleed the logo group out to the true left viewport edge at every width.
         `%` here resolves against .wrap's fixed max-width content box, so this equals
         exactly the negative offset needed to cancel the auto-centering + 26px padding. */
      margin-left: calc(50% - 50vw);
    }

    .util-right {
      display: flex;
      align-items: center;
      gap: 22px;
      flex: none;
    }

    /* real logo on a white panel so the blue wordmark stays legible */
    /* white plate runs the full height of the utility bar and bleeds to the left viewport edge;
     negative margin cancels .wrap's 12px padding, ::before paints the bleed past .wrap's max-width */
    .util .logo {
      position: relative;
      display: flex;
      align-items: center;
      align-self: stretch;
      text-decoration: none;
      background: #fff;
      border-radius: 0;
      /* margin: -12px cancels .wrap's 12px top/bottom padding so the white plate
         fills the full height of the utility bar and touches the top edge */
      padding: 0 28px;
      margin: -12px 0;
      box-shadow: 6px 0 20px rgba(0, 0, 0, .14);
    }

    .util .logo img {
      height: 85px;
      width: auto;
      display: block;
    }

    /* both certification marks pull inward toward the headline by the same amount,
       which keeps the headline optically centred while evening out the banner */
    .util .badge-hipaa {
      height: 54px;
      width: auto;
      display: block;
      margin-left: clamp(9px, 2.25vw, 45px);
      opacity: .96;
    }

    /* the right-hand badge is the same HIPAA artwork as the left, mirrored:
       same height, and the gap moves to the Contact Us side */
    .util .badge-hipaa-right {
      margin-left: 0;
      margin-right: clamp(9px, 2.25vw, 45px);
    }

    /* centered serif headline */
    /* flex:1 makes the headline span the whole gap between the two badges, so
       centring inside it puts the text exactly midway between them. Under
       space-between alone it merely sat wherever the free space fell. */
    .util .headline {
      flex: 1;
      text-align: center;
      margin: 0;
      white-space: nowrap;
      color: #fff;
      font-family: "HeadlineSans", "Avenir Next", "Nunito Sans", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
      font-weight: 800;
      font-style: italic;
      font-size: clamp(24px, 2.9vw, 46px);
      letter-spacing: .14em;
      line-height: 1.06;
      text-shadow: 0 2px 12px rgba(0, 0, 0, .22);
    }

    /* no extra margin after UP — the word space plus the headline's letter-spacing
       already matches every other gap in the phrase */
    .util .headline em {
      color: inherit;
      font-style: italic;
      font-weight: 800;
      margin-right: 0;
    }

    /* plain clickable Contact Us text link (holds all contact info) */
    .contact-us {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      flex: none;
      background: none;
      border: 0;
      padding: 0;
      box-shadow: none;
      color: #fff;
      text-decoration: none;
      font-weight: 800;
      font-size: 17px;
      letter-spacing: .01em;
      text-shadow: 0 2px 10px rgba(0, 0, 0, .25);
      transition: opacity .12s;
    }

    .contact-us em {
      color: #ff8ac8;
      font-style: italic;
    }

    .contact-us svg {
      width: 18px;
      height: 18px;
    }

    .contact-us span {
      border-bottom: 1.5px solid rgba(255, 255, 255, .45);
      padding-bottom: 2px;
    }

    .contact-us:hover {
      opacity: .82;
    }

    .contact-us:hover span {
      border-bottom-color: #fff;
    }

    @media (max-width:1240px) {
      .util .headline {
        display: none;
      }
    }

    @media (max-width:920px) {

      .util .badge-hipaa,
      .util .badge-hipaa-right {
        display: none;
      }
    }

    /* ============ HEADER / NAV ============ */
    header.site {
      position: sticky;
      top: 0;
      z-index: 40;
      /* page background, not surface — the nav bar reads as part of the cream
         page rather than a white band sitting on it */
      background: var(--bg);
      border-bottom: 0;
      box-shadow: none;
    }

    header.site .wrap {
      display: flex;
      align-items: center;
      gap: 12px;
      height: 66px;
      min-width: 0;
    }

    .logo {
      display: flex;
      align-items: center;
      gap: 11px;
      text-decoration: none;
      flex: none;
    }

    .logo svg {
      width: 42px;
      height: auto;
      display: block;
    }

    .logo .wm {
      display: flex;
      flex-direction: column;
      line-height: 1;
    }

    .logo .wm .n {
      font-size: 21px;
      font-weight: 800;
      letter-spacing: -.02em;
      color: var(--blue);
    }

    .logo .wm .n em {
      color: var(--magenta);
      font-style: italic;
    }

    .logo .wm .t {
      font-size: 9.5px;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--ink-faint);
      margin-top: 3px;
      font-weight: 600;
    }

    nav.main {
      display: flex;
      gap: 0;
      flex: 1;
      min-width: 0;
      margin-left: 0;
      margin-right: auto;
      align-items: stretch;
    }

    nav.main>a,
    nav.main .has-mega>a {
      position: relative;
      display: flex;
      align-items: center;
      gap: 6px;
      height: 66px;
      padding: 0 14px;
      text-decoration: none;
      color: var(--ink-soft);
      font-weight: 600;
      font-size: 14.5px;
      white-space: nowrap;
      border-bottom: 2.5px solid transparent;
      transition: color .15s, border-color .15s;
    }

    nav.main>a:hover,
    nav.main .has-mega:hover>a,
    nav.main .has-mega:focus-within>a {
      color: var(--blue);
      border-color: var(--blue);
    }

    nav.main .has-mega {
      display: flex;
    }

    nav.main .caret {
      width: 10px;
      height: 10px;
      opacity: .6;
      transition: transform .16s;
    }

    nav.main .has-mega:hover .caret {
      transform: rotate(180deg);
    }
    /* align Home with the right edge of the white logo plate in the bar above */
    @media (min-width: 921px) {
      nav.main {
        margin-left: calc(var(--logo-plate-end) - 26px - (100vw - min(100vw, var(--maxw))) / 2);
      }
    }

    @media (max-width:1680px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 12px;
      }
    }

    @media (max-width:1620px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 9px;
        font-size: 14px;
      }

      header.site .wrap {
        gap: 8px;
      }

      .cta-btn {
        padding: 5px 12px;
        font-size: 13.5px;
      }

      .logo .wm .t {
        display: none;
      }
    }

    @media (max-width:1080px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 5px;
        font-size: 12.8px;
        gap: 4px;
      }

      .nav-badge {
        margin-left: 2px;
        padding: 2px 5px;
        font-size: 9px;
      }
    }

    /* between desktop and mobile: nav + Sales Request no longer fit on one line */

    /* the last ~80px before the hamburger: the decorative badge is the first thing
       to go, so the labels themselves stay as large as possible */
    @media (min-width:1011px) and (max-width:1060px) {
      nav.main .nav-badge {
        display: none;
      }

      nav.main {
        margin-right: 6px;
      }

      /* and the CTA gives back a few pixels rather than the labels shrinking further */
      .cta-btn.desktop {
        padding: 0 9px;
        font-size: 12px;
      }
    }

    /* ---- the white logo plate scales with the viewport, and --logo-plate-end
       tracks it, so "menu starts where the logo ends" holds at every width ---- */
    @media (max-width:1520px) {
      :root {
        --logo-plate-end: 196px;
      }

      .util .wrap {
        min-height: 80px;
        padding-top: 10px;
        padding-bottom: 10px;
      }

      .util .logo {
        padding: 0 23px;
        margin: -10px 0;
      }

      .util .logo img {
        height: 72px;
      }
    }

    @media (max-width:1200px) {
      :root {
        --logo-plate-end: 166px;
      }

      .util .wrap {
        min-height: 70px;
        padding-top: 9px;
        padding-bottom: 9px;
      }

      .util .logo {
        padding: 0 19px;
        margin: -9px 0;
      }

      .util .logo img {
        height: 62px;
      }
    }

    @media (max-width:1030px) {
      :root {
        --logo-plate-end: 142px;
      }

      .util .wrap {
        min-height: 62px;
        padding-top: 8px;
        padding-bottom: 8px;
      }

      .util .logo {
        padding: 0 15px;
        margin: -8px 0;
      }

      .util .logo img {
        height: 54px;
      }
    }

    /* ---- One line at every width. The nav still starts at the logo plate's right
       edge; item size is interpolated against the viewport so the row always fits
       between that edge and the Sales Request button — no steps, no wrapping. ---- */
    @media (min-width:1011px) and (max-width:1520px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 clamp(2px, calc(1.34vw - 11.4px), 9px);
        font-size: clamp(9.9px, calc(0.76vw + 2.45px), 14px);
        gap: clamp(2px, .42vw, 6px);
      }

      nav.main .caret {
        width: clamp(9px, .78vw, 12px);
      }

      .nav-badge {
        margin-left: clamp(2px, .3vw, 6px);
        padding: 1px clamp(4px, .38vw, 6px);
        font-size: clamp(8px, .62vw, 10px);
      }
    }

    /* ---- the white logo plate scales with the viewport, and --logo-plate-end
       tracks it, so "menu starts where the logo ends" holds at every width ---- */
    @media (max-width:1520px) {
      :root {
        --logo-plate-end: 196px;
      }

      .util .wrap {
        min-height: 80px;
        padding-top: 10px;
        padding-bottom: 10px;
      }

      .util .logo {
        padding: 0 23px;
        margin: -10px 0;
      }

      .util .logo img {
        height: 72px;
      }
    }

    @media (max-width:1200px) {
      :root {
        --logo-plate-end: 166px;
      }

      .util .wrap {
        min-height: 70px;
        padding-top: 9px;
        padding-bottom: 9px;
      }

      .util .logo {
        padding: 0 19px;
        margin: -9px 0;
      }

      .util .logo img {
        height: 62px;
      }
    }

    @media (max-width:1030px) {
      :root {
        --logo-plate-end: 142px;
      }

      .util .wrap {
        min-height: 62px;
        padding-top: 8px;
        padding-bottom: 8px;
      }

      .util .logo {
        padding: 0 15px;
        margin: -8px 0;
      }

      .util .logo img {
        height: 54px;
      }
    }

    /* ---- keep the ten top-level items on one line all the way down to the
       hamburger breakpoint: shrink the items, never wrap the row ---- */
    @media (max-width:1180px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 7px;
        font-size: 13.5px;
      }

      nav.main .caret {
        width: 10px;
      }
    }

    @media (max-width:1080px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 5px;
        font-size: 12.6px;
        gap: 4px;
      }

      .nav-badge {
        margin-left: 2px;
        padding: 2px 5px;
        font-size: 9px;
      }
    }

    /* last stop before the hamburger takes over at 980px */
    @media (max-width:1030px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 3px;
        font-size: 11.6px;
        gap: 3px;
      }

      nav.main .caret {
        width: 9px;
      }

      .nav-badge {
        padding: 1px 4px;
        font-size: 8.5px;
      }
    }

    @media (max-width:1520px) {
      /* one row at every width: nav on the left, Sales Request pinned right.
         Nothing wraps — the size ladder above shrinks the items to fit. */
      header.site .wrap {
        flex-wrap: nowrap;
        height: 66px;
        row-gap: 0;
        padding-top: 0;
        padding-bottom: 0;
      }

      nav.main {
        order: 0;
        flex: 1 1 auto;
        min-width: 0;
        margin-right: 12px;
        justify-content: flex-start;
        flex-wrap: nowrap;
      }

      nav.main>a,
      nav.main .has-mega>a {
        flex: none;
        white-space: nowrap;
        height: 66px;
      }

      .cta-btn.desktop {
        margin-left: auto;
      }

      /* anchor compact mega menus to the bar instead of running off-screen */
      header.site .has-mega.hp {
        position: static;
      }

      header.site .mega.mega-sm {
        left: 12px;
        right: 12px;
        width: auto;
      }

      /* the About menu is narrow enough to stay centred on its trigger — it does
         not need the full-bar anchoring the wider Home Phone menu relies on */
      header.site .mega.mega-sm.ab-menu {
        left: 50%;
        right: auto;
        width: min(524px, calc(100vw - 32px));
      }
    }

    /* Narrow band between the header wrap's max-width and the nav-wrap point:
       About Us sits close enough to the right edge that a perfectly centred panel
       would clip. Nudge it back just far enough — it still reads as centred. */
    @media (min-width:1361px) and (max-width:1405px) {
      header.site .mega.mega-sm.ab-menu {
        transform: translateX(calc(-50% - 46px)) translateY(-8px);
      }

      header.site .has-mega.ab:hover .ab-menu,
      header.site .has-mega.ab:focus-within .ab-menu,
      header.site .has-mega.ab.open .ab-menu {
        transform: translateX(calc(-50% - 46px));
      }
    }

    /* Wrapped-nav band: About Us sits far enough right that the full-width panel
       would overhang. Narrower panel, still centred, still on-screen. */
    @media (max-width:1015px) {

      /* one class more specific than the max-width:1360 block, which on the
         sub-pages is emitted after this rule */
      header.site nav.main .mega.mega-sm.ab-menu {
        width: min(420px, calc(100vw - 32px));
      }
    }

    @media (max-width:1200px) {
      .cta-btn svg {
        display: none;
      }
    }

    @media (max-width:1080px) {

      /* the nav item sizing lives in the one-line ladder above; this legacy rule
         used to reset it back to 14px and undo the whole thing */
      header.site .wrap {
        gap: 10px;
      }

      .cta-btn svg {
        display: none;
      }
    }

    .cta-btn {
      flex: none;
      margin-left: auto;
      display: inline-flex;
      align-items: center;
      gap: 8px;
      background: var(--magenta);
      color: #fff;
      text-decoration: none;
      font-weight: 700;
      /* explicit height so the product-page CTAs can match it exactly */
      height: 30px;
      padding: 0 12px;
      border-radius: 40px;
      font-size: 13px;
      letter-spacing: .01em;
      box-shadow: 0 6px 18px -6px var(--magenta);
      transition: transform .12s, box-shadow .12s, background .12s;
    }

    .cta-btn:hover {
      transform: translateY(-1px);
      background: var(--magenta-deep);
      box-shadow: 0 10px 24px -6px var(--magenta);
    }

    .cta-btn svg {
      width: 14px;
      height: 14px;
    }

    /* mega menu */
    header.site {
      overflow: visible;
    }

    header.site .wrap {
      position: relative;
    }

    .has-mega {
      position: static;
    }

    .has-mega .mega {
      position: absolute;
      left: 12px;
      right: 12px;
      top: calc(100% + 8px);
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 16px;
      box-shadow: var(--shadow-md);
      opacity: 0;
      visibility: hidden;
      pointer-events: none;
      transform: translateY(-8px);
      transition: opacity .16s ease, transform .16s ease, visibility .16s;
      padding: 28px 32px 30px;
      z-index: 50;
    }

    /* invisible hover bridge across the gap so the cursor never leaves the hover chain */
    .has-mega .mega::before {
      content: "";
      position: absolute;
      left: 0;
      right: 0;
      top: -14px;
      height: 16px;
      background: transparent;
    }

    /* keep the trigger itself an active hover target the full height of the bar */
    .has-mega>a::after {
      content: "";
      position: absolute;
      left: 0;
      right: 0;
      bottom: -10px;
      height: 12px;
    }

    .has-mega:hover .mega,
    .has-mega:focus-within .mega,
    .has-mega.open .mega {
      opacity: 1;
      visibility: visible;
      pointer-events: auto;
      transform: none;
    }

    .mega .mega-grid {
      max-width: none;
      margin: 0;
      padding: 0;
      display: grid;
      grid-template-columns: 0.9fr 1fr 1.05fr 0.9fr;
      gap: 34px;
      align-items: start;
    }

    .mega .mm-rail {
      display: flex;
      flex-direction: column;
      gap: 18px;
    }

    /* 5G menu: two image rails plus four lists is six tracks in the width the
       other menus use for four, so this panel runs a size down on its own.
       It needs its own responsive rules — .mega.g5-menu .mega-grid outranks
       the shared .mega .mega-grid override inside the media queries. */
    .mega.g5-menu .mega-grid {
      /* column widths track what each column's longest label actually needs:
         products 215px, accessories 181px, carrier 169px, pricing 253px */
      grid-template-columns: 0.58fr 0.95fr 0.8fr 0.74fr 1.11fr 0.58fr;
      gap: 18px;
    }

    .mega.g5-menu .col a,
    .mega.g5-menu .col .mm-soon {
      font-size: 13.5px;
      padding: 7.5px 0;
      gap: 7px;
    }

    .mega.g5-menu .col h4 {
      font-size: 10.5px;
      letter-spacing: .1em;
    }

    .mega.g5-menu .mm-rail {
      gap: 14px;
    }

    .mega.g5-menu .mm-thumb img {
      max-height: 70px;
    }

    .mega.g5-menu .mm-thumb figcaption {
      font-size: 9.5px;
    }

    /* laptops: the rails go first so the four lists keep full-size labels */
    @media (max-width:1390px) {
      .mega.g5-menu .mm-rail {
        display: none;
      }

      .mega.g5-menu .mega-grid {
        /* the pricing names are the longest in this menu, so that column keeps
           more of the row than an even four-way split would give it */
        grid-template-columns: 1.05fr 0.89fr 0.83fr 1.24fr;
        gap: 26px;
      }

      .mega.g5-menu .col a,
      .mega.g5-menu .col .mm-soon {
        font-size: 14.5px;
        padding: 9px 0;
      }
    }

    @media (max-width:1120px) {
      .mega.g5-menu .mega-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 26px 34px;
      }
    }

    /* ---- 5G Accessories ----------------------------------------------------
       Two levels in a panel whose other columns have one, so the product rows
       are left to the shared .mega .col a treatment untouched — same bullet,
       size, weight, padding and hairline as 5G Products beside it — and only
       the sub-category is given a style of its own.

       That style is a label, not a heading: micro caps in grey, no bullet and
       no rule, so it sits between the rows the way a column head sits above
       them. An earlier pass made it bold and hung the products off a vertical
       rail; the rail and the weight cut the column into three blocks and made
       it the heaviest thing in the panel. The full-width hairlines under the
       product rows are what hold the column together as one list. ------- */
    .mega.g5-menu .mm-acc .mm-cat {
      display: block;
      padding: 13px 0 2px;
      border-bottom: 0;
      font-size: 10px;
      font-weight: 700;
      letter-spacing: .09em;
      text-transform: uppercase;
      /* not --ink-faint: at 10px it lands at 3.9:1 on the panel, under the
         4.5:1 small text wants. Mixed toward --ink-soft it clears 4.5 and is
         still plainly quieter than the rows it labels. */
      color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft));
    }

    .mega.g5-menu .mm-acc .mm-cat:first-of-type {
      padding-top: 3px;
    }

    .mega.g5-menu .mm-acc .mm-cat::before {
      content: none;
    }

    /* the shared list steps a row right on hover; a label is not a row, so it
       takes the colour and stays put */
    .mega.g5-menu .mm-acc .mm-cat:hover {
      padding-left: 0;
      color: var(--blue);
    }


    /* the qualifier sits inside the model's own text flow, so it wraps with it
       and shares its baseline rather than being a second flex item */
    .mega.g5-menu .mm-acc .mm-prod-meta {
      margin-left: 5px;
      font-size: 11.5px;
      color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft));
    }

    /* Panamax menu: About column plus two product columns, one image rail
       either side. Needs its own responsive rule — .mega.pnx-menu .mega-grid
       outranks the shared .mega .mega-grid override inside the media query.

       Battery Backup is commented out of the markup for as long as every
       product in it is unpublished. Restore these two track lists along with
       the column, or the panel renders a column short of its own grid:
           here                 0.7fr 0.8fr 0.95fr 0.95fr 1fr 0.7fr
           1390 breakpoint      repeat(4, minmax(0, 1fr)) */
    .mega.pnx-menu .mega-grid {
      grid-template-columns: 0.7fr 0.9fr 1.1fr 1.1fr 0.7fr;
      gap: 20px;
    }

    /* more tracks in the width the other menus use for four, so the Panamax
       panel runs a size down on type, padding and thumbnails */
    .mega.pnx-menu .col a {
      font-size: 13.5px;
      padding: 7.5px 0;
      gap: 7px;
    }

    .mega.pnx-menu .col h4 {
      font-size: 10.5px;
      letter-spacing: .1em;
    }

    .mega.pnx-menu .mm-rail {
      gap: 14px;
    }

    .mega.pnx-menu .mm-thumb img {
      max-height: 70px;
    }

    .mega.pnx-menu .mm-thumb figcaption {
      font-size: 9.5px;
    }

    /* Prime Surge menu — same panel as Panamax (it carries pnx-menu too), with
       its own track list because it runs one product column fewer. */
    .mega.pnx-menu.prime-menu .mega-grid {
      grid-template-columns: 0.7fr 0.85fr 1fr 1fr 1fr 0.7fr;
    }

    @media (max-width:1390px) {
      .mega.pnx-menu.prime-menu .mega-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
      }
    }

    /* laptops: the rails go first so the four lists keep full-size labels.
       1390 is where the six-track layout stops fitting the longest label,
       P360-8 Power360 8 Outlet Strip, on a single line. */
    @media (max-width:1390px) {
      .mega.pnx-menu .mm-rail {
        display: none;
      }

      .mega.pnx-menu .mega-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 26px;
      }

      .mega.pnx-menu .col a {
        font-size: 14.5px;
        padding: 9px 0;
      }
    }

    @media (max-width:1120px) {
      .mega.pnx-menu .mega-grid {
        grid-template-columns: 1fr 1fr;
        gap: 26px 34px;
      }
    }

    .mega .mm-thumb {
      margin: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
      gap: 8px;
      padding: 12px;
      border: 1px solid var(--line-soft);
      border-radius: 12px;
      background: var(--surface-2);
      transition: border-color .14s, transform .14s;
    }

    .mega .mm-thumb:hover {
      border-color: var(--magenta);
      transform: translateY(-2px);
    }

    .mega .mm-thumb img {
      width: 100%;
      max-height: 88px;
      object-fit: contain;
      mix-blend-mode: multiply;
    }

    .mega .mm-thumb figcaption {
      font-size: 10.5px;
      letter-spacing: .04em;
      color: var(--ink-faint);
      line-height: 1.4;
    }

    .mega .mm-thumb figcaption b {
      display: block;
      color: var(--ink-soft);
      font-size: 12px;
      letter-spacing: 0;
      margin-top: 2px;
    }

    @media (prefers-color-scheme:dark) {
      .mega .mm-thumb {
        background: #fff;
      }

      .mega .mm-thumb img {
        mix-blend-mode: normal;
      }
    }

    :root[data-theme="dark"] .mega .mm-thumb {
      background: #fff;
    }

    :root[data-theme="dark"] .mega .mm-thumb img {
      mix-blend-mode: normal;
    }

    :root[data-theme="light"] .mega .mm-thumb {
      background: var(--surface-2);
    }

    :root[data-theme="light"] .mega .mm-thumb img {
      mix-blend-mode: multiply;
    }

    @media (max-width:1120px) {
      .mega .mm-rail {
        display: none;
      }

      .mega .mega-grid {
        grid-template-columns: 1fr 1fr;
      }
    }

    .mega .col h4 {
      margin: 0 0 6px;
      padding-bottom: 10px;
      font-size: 11px;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--magenta);
      border-bottom: 2px solid color-mix(in srgb, var(--magenta) 22%, transparent);
    }

    .mega .col a {
      display: flex;
      align-items: center;
      gap: 8px;
      text-decoration: none;
      color: var(--ink-soft);
      font-size: 14.5px;
      padding: 9px 0;
      border-bottom: 1px solid var(--line-soft);
      font-weight: 500;
      transition: color .13s, padding-left .13s;
    }

    .mega .col a:last-child {
      border-bottom: 0;
    }

    .mega .col a::before {
      content: "";
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background: var(--line);
      transition: background .13s;
      flex: none;
    }

    .mega .col a:hover {
      color: var(--blue);
      padding-left: 5px;
    }

    .mega .col a:hover::before {
      background: var(--magenta);
    }

    /* A menu row that is named but not yet linked. Matches .mega .col a apart from
       the muted colour and the missing hover affordance, so it reads as "listed,
       not ready" instead of as a broken link. Swap the span for an <a> to enable it. */
    .mega .col .mm-soon {
      display: flex;
      align-items: center;
      gap: 8px;
      flex: 1;
      color: var(--ink-faint);
      font-size: 14.5px;
      padding: 9px 0;
      font-weight: 500;
      cursor: default;
    }

    .mega .col .mm-soon::before {
      content: "";
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background: var(--line);
      flex: none;
    }

    /* mega-menu product row: link + data-sheet (client asked for data sheets) */
    .mega .mm-item {
      display: flex;
      align-items: center;
      gap: 10px;
      border-bottom: 1px solid var(--line-soft);
      padding: 2px 0;
    }

    .mega .mm-item:last-child {
      border-bottom: 0;
    }

    .mega .mm-item>a:first-child {
      flex: 1;
      border-bottom: 0;
      padding: 9px 0;
    }

    .mega .mm-item .ds,
    .mega .hp-desc .ds {
      flex: none;
      border-bottom: 0;
      padding: 4px 10px;
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .04em;
      text-transform: uppercase;
      color: var(--ink-faint);
      background: var(--surface-2);
      border-radius: 20px;
      white-space: nowrap;
      transition: .14s;
    }

    .mega .hp-desc .ds {
      display: inline-block;
      text-decoration: none;
    }

    .mega .mm-item .ds::before,
    .mega .hp-desc .ds::before {
      content: "\2193";
      margin-right: 5px;
      font-weight: 900;
    }

    .mega .mm-item .ds:hover,
    .mega .hp-desc .ds:hover {
      background: var(--blue);
      color: #fff;
      padding-left: 10px;
    }

    /* ---- Switches: one compact row per product, so the menu keeps its height as
       the catalogue grows. Data sheets and quick guides deliberately are not
       repeated here — they live on each product page and on the Switches listing.
       Adding a product is a single .mm-item row. ---- */
    .mega.switches-menu .mega-grid {
      grid-template-columns: .9fr 1fr 1.15fr .9fr;
    }

    /* price sits flush right on the same line as the product name */
    .mega.switches-menu .mm-price {
      margin-left: auto;
      padding-left: 14px;
      color: var(--ink);
      font-size: 13px;
      font-weight: 750;
      font-variant-numeric: tabular-nums;
      white-space: nowrap;
    }

    .mega.switches-menu .col a:hover .mm-price {
      color: var(--blue);
    }

    /* The list scrolls inside itself rather than pushing the menu past the
       viewport. With ~46px per row this only engages once a category holds a
       dozen or so products, so nothing changes at today's catalogue size. */
    .mega.switches-menu .mm-list {
      max-height: min(56vh, 480px);
      overflow-y: auto;
      overscroll-behavior: contain;
      scrollbar-width: thin;
      scrollbar-color: var(--line) transparent;
    }

    @media (max-width:1120px) {
      .mega.switches-menu .mega-grid {
        grid-template-columns: 1fr 1fr;
      }
    }

    /* ---- Home Phone: compact two-section mega menu (images left, copy right) ---- */
    .has-mega.hp {
      position: relative;
    }

    .mega.mega-sm {
      left: 0;
      right: auto;
      width: min(680px, calc(100vw - 40px));
      padding: 24px 26px 20px;
    }

    .hp-grid {
      display: grid;
      grid-template-columns: 136px 1fr;
      gap: 20px 24px;
      align-items: center;
    }

    .hp-grid .mm-thumb {
      padding: 10px;
      background: #fff;
    }

    .hp-grid .mm-thumb img {
      max-height: 78px;
      mix-blend-mode: normal;
    }

    .hp-desc a.hp-title {
      display: block;
      color: var(--ink);
      font-size: 15.5px;
      font-weight: 700;
      line-height: 1.25;
      text-decoration: none;
      transition: color .13s;
    }

    .hp-desc a.hp-title:hover {
      color: var(--blue);
    }

    .hp-desc p {
      margin: 7px 0 11px;
      font-size: 13.5px;
      line-height: 1.5;
      color: var(--ink-soft);
    }

    .mega .hp-all {
      display: block;
      margin-top: 18px;
      padding-top: 14px;
      border-top: 1px solid var(--line-soft);
      color: var(--magenta-ink);
      font-size: 13.5px;
      font-weight: 700;
      text-decoration: none;
      transition: padding-left .13s;
    }

    .mega .hp-all:hover {
      padding-left: 4px;
    }

    /* ---- About Us: compact two-column mega menu ----
       Left is the image slot. Until the client's photo lands it shows the brand
       panel — the same hero gradient and magenta glow used by .mega .promo — so
       the menu reads as finished rather than as a missing asset. Dropping an
       <img> in as the first child of .ab-shot fills the panel; the caption keeps
       its scrim and stays legible. Nothing else has to change. */
    .has-mega.ab {
      position: relative;
    }

    /* centred on its trigger. The base .mega animates with transform, so the
       centring translate has to ride along in both the closed and open state. */
    .mega.mega-sm.ab-menu {
      left: 50%;
      right: auto;
      width: min(524px, calc(100vw - 32px));
      padding: 20px;
      transform: translateX(-50%) translateY(-8px);
    }

    .has-mega.ab:hover .ab-menu,
    .has-mega.ab:focus-within .ab-menu,
    .has-mega.ab.open .ab-menu {
      transform: translateX(-50%);
    }

    .ab-grid {
      display: grid;
      grid-template-columns: 164px 1fr;
      gap: 22px;
      align-items: stretch;
    }

    .ab-shot {
      position: relative;
      margin: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 198px;
      border-radius: 12px;
      overflow: hidden;
      background: var(--hero-grad);
    }

    /* glow, same device as .mega .promo — keeps the empty slot on-brand */
    .ab-shot::after {
      content: "";
      position: absolute;
      right: -46px;
      top: -46px;
      width: 150px;
      height: 150px;
      border-radius: 50%;
      background: radial-gradient(circle, var(--magenta), transparent 66%);
      opacity: .5;
    }

    .ab-shot img {
      position: absolute;
      inset: 0;
      z-index: 2;
      width: 100%;
      height: 100%;
      object-fit: cover;
      mix-blend-mode: normal;
    }

    /* placeholder — dashed ring says "image slot" without looking unfinished */
    .ab-shot .ab-ph {
      position: absolute;
      inset: 10px;
      z-index: 1;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 9px;
      border: 1px dashed rgba(255, 255, 255, .34);
      border-radius: 8px;
      color: rgba(255, 255, 255, .82);
      text-align: center;
    }

    .ab-shot .ab-ph svg {
      width: 26px;
      height: 26px;
      opacity: .85;
    }

    .ab-shot .ab-ph span {
      font-size: 9.5px;
      font-weight: 800;
      letter-spacing: .14em;
      text-transform: uppercase;
      opacity: .9;
    }

    /* the photo lands, the placeholder steps aside — no markup surgery needed */
    .ab-shot:has(img) .ab-ph {
      display: none;
    }

    /* the HBE Internet slot holds a logo, not a photograph like the team shot,
       so it is contained and centred rather than cropped edge to edge */
    .hbei .ab-shot img {
      position: static;
      width: auto;
      height: auto;
      max-width: 84%;
      max-height: 66%;
      object-fit: contain;
    }

    /* the Company slot holds a cut-out figure, so she stands the full height of
       the slot instead of being cropped edge to edge */
    .ab-shot img.ab-figure {
      position: static;
      width: auto;
      height: 100%;
      max-width: 96%;
      object-fit: contain;
    }

    /* and she stands on the menu surface itself — no gradient panel, no glow,
       which the HBE Internet slot next door still keeps */
    .ab-shot:has(img.ab-figure) {
      background: none;
    }

    .ab-shot:has(img.ab-figure)::after {
      display: none;
    }

    .ab-links h4 {
      margin: 0 0 3px;
      padding: 0 0 9px;
      font-size: 11px;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--magenta);
      border-bottom: 2px solid color-mix(in srgb, var(--magenta) 22%, transparent);
    }

    .ab-links a {
      position: relative;
      display: block;
      padding: 9px 22px 9px 0;
      border-bottom: 1px solid var(--line-soft);
      text-decoration: none;
      transition: padding-left .14s;
    }

    .ab-links a:last-child {
      border-bottom: 0;
    }

    .ab-links a b {
      display: block;
      font-size: 14.5px;
      font-weight: 650;
      line-height: 1.25;
      color: var(--ink);
      transition: color .14s;
    }

    .ab-links a span {
      display: block;
      margin-top: 1px;
      font-size: 11.5px;
      line-height: 1.45;
      color: var(--ink-faint);
    }

    /* chevron slides in on hover — same restraint as the rest of the nav */
    .ab-links a::after {
      content: "";
      position: absolute;
      right: 7px;
      top: 50%;
      width: 6px;
      height: 6px;
      margin-top: -4px;
      border-top: 1.5px solid var(--magenta);
      border-right: 1.5px solid var(--magenta);
      transform: translateX(-5px) rotate(45deg);
      opacity: 0;
      transition: opacity .14s, transform .14s;
    }

    .ab-links a:hover {
      padding-left: 6px;
    }

    .ab-links a:hover b {
      color: var(--blue);
    }

    .ab-links a:hover::after {
      opacity: 1;
      transform: translateX(0) rotate(45deg);
    }

    @media (prefers-reduced-motion: reduce) {

      .ab-links a,
      .ab-links a::after {
        transition: none;
      }
    }

    @media (max-width:560px) {
      .ab-grid {
        grid-template-columns: 1fr;
        gap: 14px;
      }

      .ab-shot {
        min-height: 132px;
      }
    }

    .mega .promo {
      background: var(--hero-grad);
      border-radius: 12px;
      padding: 22px;
      color: #eaf6ff;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      position: relative;
      overflow: hidden;
    }

    .mega .promo::after {
      content: "";
      position: absolute;
      right: -30px;
      bottom: -30px;
      width: 120px;
      height: 120px;
      border-radius: 50%;
      background: radial-gradient(circle, var(--magenta), transparent 65%);
      opacity: .4;
    }

    .mega .promo strong {
      font-size: 17px;
      color: #fff;
      display: block;
      margin-bottom: 6px;
      position: relative;
    }

    .mega .promo span {
      font-size: 13px;
      opacity: .9;
      line-height: 1.5;
      position: relative;
    }

    .mega .promo a {
      margin-top: 16px;
      align-self: flex-start;
      background: #fff;
      color: var(--blue-ink);
      text-decoration: none;
      font-weight: 700;
      font-size: 13px;
      padding: 9px 17px;
      border-radius: 30px;
      position: relative;
      transition: transform .12s;
    }

    .mega .promo a:hover {
      transform: translateY(-2px);
    }

    .menu-toggle {
      display: none;
      margin-left: auto;
      background: none;
      border: 1px solid var(--line);
      border-radius: 8px;
      width: 44px;
      height: 40px;
      cursor: pointer;
      align-items: center;
      justify-content: center;
    }

    .menu-toggle svg {
      width: 22px;
      height: 22px;
      color: var(--ink);
    }

    /* below this the ten items can no longer be shown at a legible size, so the
       existing mobile menu takes over (1024 still gets the full nav) */
    @media (max-width:1010px) {

      nav.main,
      .cta-btn.desktop {
        display: none;
      }

      .menu-toggle {
        display: flex;
      }
    }

    /* ============ HERO — Ooma-style light, centered ============ */
    .hero {
      background: var(--bg);
      color: var(--ink);
      overflow: hidden;
    }

    .hero .wrap {
      position: relative;
      display: block;
      text-align: center;
      padding: 56px 26px 0;
      max-width: 1080px;
    }

    .hero .eyebrow {
      display: none;
    }

    .hero h1 {
      font-family: var(--serif);
      font-size: clamp(34px, 5.2vw, 58px);
      margin: 0 auto 10px;
      font-weight: 600;
      color: var(--ink);
      max-width: 18ch;
      line-height: 1.12;
    }

    .hero h1 .voice {
      color: var(--magenta-ink);
      font-style: italic;
    }

    .hero h1 .noise {
      color: var(--blue);
      font-style: italic;
    }

    .hero .sig {
      font-size: clamp(16px, 1.9vw, 19px);
      font-weight: 500;
      margin: 0 auto 10px;
      color: var(--ink-soft);
    }

    .hero .sig em {
      color: var(--ink);
      font-style: normal;
      font-weight: 700;
    }

    .hero p.lead {
      font-size: 16.5px;
      color: var(--ink-soft);
      max-width: 56ch;
      margin: 0 auto 26px;
    }

    /* =================================================================
       HERO — "one provider, five signals"

       The five things HBE Yakabit sells are not five pages of a slider;
       they are five capabilities of one company, so the hero states the
       company once and lets the capability change underneath it. A rail
       on the left names all five at once — nobody has to wait through a
       carousel to learn what is on offer — and drives a layered hx-frame on
       the right, where the photograph is the floor and each capability
       composes its own cards on top of it.
       ================================================================= */
    :root {
      /* the curve every new move in this hero shares */
      --e: cubic-bezier(0.22, 1, 0.36, 1);
      /* and the clock. Every line pulse, every arrival mark and every box
         response runs on this one duration, so the hero reads as a single
         system rather than as five things that happen to be nearby. Anything
         timed against an arrival is expressed as a fraction of it below —
         change this number and the whole set moves together. */
      --flow: 6.6s;
      /* When the things inside a card start moving. The card's own content
         finishes arriving at ~700ms, and until now every instrument was
         already at full swing before that — the motion was running before
         the thing carrying it had finished appearing, which is what made it
         feel like it started fast. They now wake after the card has landed,
         and fade up rather than switching on. */
      --warm: 780ms;
    }

    .hero.mag {
      position: relative;
      isolation: isolate;
      overflow: hidden;
    }

    /* brand aurora: keeps the cream ground but gives the section a light
       source, so the hx-frame below has something to sit in front of */
    .hero.mag::before {
      content: "";
      position: absolute;
      inset: -20% -10% auto;
      height: 150%;
      background:
        radial-gradient(52% 46% at 78% 18%, color-mix(in srgb, var(--blue) 22%, transparent), transparent 68%),
        radial-gradient(40% 40% at 96% 76%, color-mix(in srgb, var(--magenta) 15%, transparent), transparent 66%),
        radial-gradient(46% 40% at 6% 92%, color-mix(in srgb, var(--blue) 10%, transparent), transparent 70%);
      z-index: -1;
      pointer-events: none;
    }

    .hero.mag .wrap.mag-grid {
      display: grid;
      /* back to the pre-rail width: the six points are set on one line each,
         and the longest of them needs the room */
      grid-template-columns: minmax(0, clamp(480px, 46vw, 620px)) minmax(0, 1fr);
      gap: clamp(30px, 3.6vw, 58px);
      align-items: center;
      text-align: left;
      max-width: var(--maxw);
      padding: clamp(34px, 3.6vw, 58px) 26px clamp(40px, 4.4vw, 70px);
    }

    .hero.mag .mag-lead {
      display: flex;
      flex-direction: column;
      min-width: 0;
    }

    /* ---------- eyebrow ---------- */
    .hx-eyebrow {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      align-self: start;
      margin: 0 0 16px;
      padding: 6px 14px 6px 11px;
      border-radius: 30px;
      background: color-mix(in srgb, var(--blue) 8%, var(--surface));
      border: 1px solid color-mix(in srgb, var(--blue) 20%, transparent);
      font-size: 12px;
      font-weight: 800;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--blue-ink);
    }

    .hx-eyebrow i {
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--magenta);
      box-shadow: 0 0 0 0 color-mix(in srgb, var(--magenta) 60%, transparent);
      animation: hx-ping 2.4s ease-out infinite;
    }

    @keyframes hx-ping {
      0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--magenta) 55%, transparent); }
      70%, 100% { box-shadow: 0 0 0 9px transparent; }
    }

    .hero.mag h1 {
      margin: 0;
      text-align: left;
      max-width: 17ch;
      font-size: clamp(40px, 4.6vw, 66px);
      line-height: 1.02;
      letter-spacing: -.025em;
      font-weight: 700;
      color: var(--ink);
    }

    /* ---------- the line that changes with the rail ---------- */
    .hx-line {
      margin: 18px 0 0;
      /* Reserves the tallest of the five lines — three of them here. Without
         a floor the buttons and the rail below step up and down by ~26px
         every time the rail advances onto a longer or shorter line. */
      min-height: 4.9em;
      max-width: 40ch;
      font-size: clamp(16.5px, 1.15vw, 18.5px);
      line-height: 1.62;
      color: var(--ink-soft);
    }

    .hx-line b {
      color: var(--ink);
      font-weight: 700;
    }

    /* the one phrase that carries the promise, in the headline's blue */
    .hx-line .blue {
      color: var(--blue);
    }

    .hx-line>span {
      display: block;
      animation: hx-rise .5s cubic-bezier(.22, .61, .36, 1) both;
    }

    @keyframes hx-rise {
      from { opacity: 0; transform: translateY(9px); }
      to { opacity: 1; transform: none; }
    }

    .hx-cta {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      margin: 22px 0 0;
    }

    /* ---------- pillar rail ---------- */
    .hx-pillars {
      margin: clamp(24px, 2.6vw, 34px) 0 0;
      padding: 0;
      list-style: none;
      display: grid;
      gap: 2px;
      border-top: 1px solid var(--line);
    }

    .hx-pillars button {
      position: relative;
      width: 100%;
      display: grid;
      grid-template-columns: 30px minmax(0, 1fr) 18px;
      align-items: center;
      gap: 12px;
      padding: 13px 4px 13px 2px;
      background: none;
      border: 0;
      border-bottom: 1px solid var(--line-soft);
      font: inherit;
      text-align: left;
      color: var(--ink-faint);
      cursor: pointer;
      transition: color .25s, padding-left .25s;
    }

    .hx-pillars button:hover {
      color: var(--ink-soft);
      padding-left: 6px;
    }

    .hx-pillars button:focus-visible {
      outline: 2px solid var(--blue);
      outline-offset: 2px;
      border-radius: 6px;
    }

    .pr-n {
      font-size: 11.5px;
      font-weight: 800;
      letter-spacing: .12em;
      font-variant-numeric: tabular-nums;
      color: var(--ink-faint);
      transition: color .25s;
    }

    .pr-t {
      font-size: clamp(15px, 1.05vw, 16.5px);
      font-weight: 600;
      letter-spacing: -.005em;
      line-height: 1.3;
      transition: color .25s;
    }

    .pr-go {
      opacity: 0;
      transform: translateX(-4px);
      color: var(--magenta-ink);
      transition: opacity .25s, transform .25s;
    }

    .pr-go svg {
      display: block;
      width: 16px;
      height: 16px;
      fill: none;
      stroke: currentColor;
      stroke-width: 2.2;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    /* the active row: ink text, brand number, and a timer bar that runs the
       length of the row so the auto-advance is legible rather than abrupt */
    .hx-pillars button[aria-selected="true"] {
      color: var(--ink);
    }

    .hx-pillars button[aria-selected="true"] .pr-n {
      color: var(--magenta-ink);
    }

    .hx-pillars button[aria-selected="true"] .pr-t {
      font-weight: 700;
      color: var(--ink);
    }

    .hx-pillars button[aria-selected="true"] .pr-go {
      opacity: 1;
      transform: none;
    }

    .pr-bar {
      position: absolute;
      left: 0;
      right: 0;
      bottom: -1px;
      height: 2px;
      overflow: hidden;
    }

    .pr-bar i {
      display: block;
      height: 100%;
      width: 100%;
      transform: scaleX(0);
      transform-origin: left;
      background: linear-gradient(90deg, var(--blue), var(--magenta));
    }

    .hx-pillars button[aria-selected="true"] .pr-bar i {
      animation: hx-timer var(--hx-dwell, 6s) linear forwards;
    }

    .hx-pillars.is-paused button[aria-selected="true"] .pr-bar i {
      animation-play-state: paused;
    }

    @keyframes hx-timer {
      from { transform: scaleX(0); }
      to { transform: scaleX(1); }
    }

    /* ---------- the seven points ----------
       Restored from the pre-rail hero. The first six take over the timer bar
       the rail used to carry and drive the scenes on the photograph; the
       seventh — the warranty line — sits out of the cycle at the foot of the
       column, which is why it carries neither a bar nor a data-step. */
    ul.hero-points {
      margin: 22px 0 0;
      padding: 0;
      list-style: none;
      /* a flex column rather than a grid one: same single-column stack and the
         same gap, but leftover height lands inside the list, where the warranty
         row's auto top margin can spend it pushing itself to the bottom */
      display: flex;
      flex-direction: column;
      flex: 1;
      gap: 13px;
      max-width: none;
    }

    ul.hero-points li {
      display: flex;
      font-size: 17px;
      line-height: 1.35;
      color: var(--ink-soft);
      transition: color .35s;
    }

    /* The whole row is the target, not just the 26px mark. A 26px hit area is
       under every pointer-target guideline going, and the words beside it are
       what people actually aim at — so the button takes the row and the mark
       stays the visible affordance. The warranty line shares the geometry
       without being a control. */
    ul.hero-points .hp-row,
    ul.hero-points li.hp-warranty {
      display: flex;
      align-items: center;
      gap: 13px;
    }

    ul.hero-points .hp-row {
      width: 100%;
      margin: 0;
      padding: 0;
      background: none;
      border: 0;
      font: inherit;
      color: inherit;
      text-align: left;
      cursor: pointer;
    }

    /* the mark answers the pointer, since it is what reads as the control */
    .hp-row:hover .hp-ico {
      transform: scale(1.09);
      border-color: color-mix(in srgb, var(--blue) 42%, transparent);
    }

    .hp-row:focus-visible {
      outline: 2px solid var(--blue);
      outline-offset: 3px;
      border-radius: 10px;
    }

    /* the row being timed comes forward in ink alone — no movement, so the
       column never reflows as the cycle steps */
    ul.hero-points li.is-on {
      color: var(--ink);
    }

    .hp-row>span:last-child,
    ul.hero-points li.hp-warranty>span:last-child {
      position: relative;
      white-space: nowrap;
    }

    ul.hero-points b {
      color: var(--ink);
      font-weight: 700;
    }

    .hp-ico {
      flex: none;
      width: 26px;
      height: 26px;
      display: grid;
      place-items: center;
      border-radius: 8px;
      color: var(--blue);
      background: color-mix(in srgb, var(--blue) 9%, var(--surface));
      border: 1px solid color-mix(in srgb, var(--blue) 20%, transparent);
      box-shadow: var(--shadow-sm);
      transition: transform .2s var(--e), border-color .2s;
    }

    /* alternate the two brand accents so the column reads as a rhythm, not a wall */
    ul.hero-points li:nth-child(3) .hp-ico,
    ul.hero-points li:nth-child(6) .hp-ico {
      color: var(--magenta-ink);
      background: color-mix(in srgb, var(--magenta) 9%, var(--surface));
      border-color: color-mix(in srgb, var(--magenta) 22%, transparent);
    }

    .hp-ico svg {
      width: 14px;
      height: 14px;
      fill: none;
      stroke: currentColor;
      stroke-width: 1.7;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    /* ---- warranty row ----
       Sits at the foot of the column, level with the bottom of the shot: the
       auto margin spends whatever height the six rows above left over. */
    ul.hero-points li.hp-warranty {
      margin-top: auto;
      padding-top: 10px;
    }

    /* Bold and 62 characters, this line is wider than the longest of the six,
       so it wraps instead of holding one line. */
    ul.hero-points li.hp-warranty>span:last-child {
      white-space: normal;
    }

    /* the same blue as "Noise" in the headline */
    ul.hero-points li.hp-warranty b {
      color: var(--blue);
    }

    /* ---- the timer bar ----
       It lives inside the text span rather than the row, so it begins at the
       first character instead of under the icon, and it is exactly as wide as
       the line it is timing. */
    .hp-bar {
      position: absolute;
      left: 0;
      right: 0;
      bottom: -6px;
      height: 2px;
      border-radius: 2px;
      overflow: hidden;
      background: color-mix(in srgb, var(--blue) 13%, transparent);
      opacity: 0;
      transition: opacity .35s;
    }

    ul.hero-points li.is-on .hp-bar {
      opacity: 1;
    }

    .hp-bar i {
      display: block;
      width: 100%;
      height: 100%;
      transform: scaleX(0);
      transform-origin: left;
      background: linear-gradient(90deg, var(--blue), var(--magenta));
    }

    /* --hp-dwell is written by the script from the same constant that sets the
       advance timer, so the bar can never drift out of step with the rotation */
    ul.hero-points li.is-on .hp-bar i {
      animation: hx-timer var(--hp-dwell, 7s) linear forwards;
    }

    ul.hero-points.is-paused li.is-on .hp-bar i {
      animation-play-state: paused;
    }

    /* The instruments fade up as they wake, so the motion emerges instead of
       appearing at full amplitude. The loops are staggered per child inside
       each of these, so the container is the right place to put the ramp —
       it lifts the whole instrument without disturbing the stagger. */
    .hx-scene .hx-eq,
    .hx-scene .hx-chips,
    .hx-scene .hx-faces,
    .hx-scene .hx-stars,
    .hx-5g .g5-meter {
      opacity: 0;
    }

    .hx-scene.is-on .hx-eq,
    .hx-scene.is-on .hx-chips,
    .hx-scene.is-on .hx-faces,
    .hx-scene.is-on .hx-stars,
    .hx-frame.is-5g .hx-5g .g5-meter {
      animation: hx-warm .62s var(--e) var(--warm) both;
    }

    @keyframes hx-warm {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    /* ---------- the headline, in three beats ---------- */
    /* This is the loudest thing in the hero now that the photograph is still.
       "Business voice," / "Without" / "the Noise", 120ms apart, done at
       960ms — then the eyebrow, the buttons and the rail follow it down. */
    /* each .hl-line is one headline line by definition — "Business voice," /
       "Without the Noise" — so it never re-wraps. The clamp shrinks the type
       with the viewport, which is what keeps a nowrap line from overflowing
       its column. */
    .hero.mag h1 .hl-line {
      display: block;
      white-space: nowrap;
    }

    .hero.mag h1 .hl-i {
      display: inline-block;
      opacity: 0;
      transform: translateY(18px);
      animation: hx-rise .74s var(--e) var(--d, 0ms) both;
    }

    @keyframes hx-rise {
      to {
        opacity: 1;
        transform: none;
      }
    }

    .hx-eyebrow,
    .hx-cta,
    ul.hero-points li {
      opacity: 0;
      animation: hx-up .6s var(--e) both;
    }

    .hx-eyebrow {
      animation-delay: 380ms;
    }

    .hx-cta {
      animation-delay: 480ms;
    }

    ul.hero-points li {
      animation-delay: calc(560ms + var(--r, 0) * 70ms);
    }

    @keyframes hx-up {
      from {
        opacity: 0;
        transform: translateY(12px);
      }

      to {
        opacity: 1;
        transform: none;
      }
    }

    /* =================== the hx-frame =================== */
    .hx-art {
      position: relative;
      min-width: 0;
      perspective: 1500px;
    }

    /* The frame is square to the page and stays there. It used to lean a few
       degrees toward the cursor, which meant the photograph itself was the
       thing being animated — the one move that reliably makes a hero feel
       cheaper. preserve-3d stays because the cards still need the depth: the
       perspective on .hx-art is what turns their translateZ into scale. */
    .hx-frame {
      position: relative;
      aspect-ratio: 4 / 3.15;
      transform-style: preserve-3d;
    }

    /* base plate: the photograph, pushed back in Z so the cards float over it */
    .hx-plate {
      position: absolute;
      inset: 0 0 0 8%;
      margin: 0;
      border-radius: 20px;
      overflow: hidden;
      background: var(--surface-2);
      box-shadow:
        0 2px 8px rgba(20, 30, 40, .08),
        0 30px 70px -20px rgba(10, 45, 70, .45);
      transform: translateZ(0);
    }

    .hx-plate img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: 62% 30%;
    }

    /* the shot arrives by fading up, never by zooming: no scale, no pan */
    .hx-plate {
      opacity: 0;
      animation: hx-plate-in .85s var(--e) 80ms both;
    }

    @keyframes hx-plate-in {
      to {
        opacity: 1;
      }
    }

    /* a wash over the photo so white cards keep their edge against it */
    .hx-plate::after {
      content: "";
      position: absolute;
      inset: 0;
      background:
        linear-gradient(200deg, rgba(4, 40, 62, .48) 0%, rgba(4, 40, 62, .08) 44%, transparent 66%),
        linear-gradient(20deg, rgba(4, 40, 62, .38), transparent 50%),
        /* the corner each floating card lands in, so white-on-white never happens */
        radial-gradient(58% 48% at 96% 104%, rgba(4, 40, 62, .5), transparent 72%),
        radial-gradient(46% 40% at 2% 22%, rgba(4, 40, 62, .34), transparent 70%);
    }

    /* ---------- scenes ---------- */
    /* The scene itself never fades, and that is not a style choice.
       opacity below 1 forces transform-style to flat, which collapses the
       cards' translateZ — so a scene cross-faded on its own opacity renders
       every card ~4% small for the whole transition and then snaps them to
       size the instant it reaches 1. The fade therefore lives on the card
       faces and the line layers below, none of which carry 3D children, and
       the scene keeps an intact preserve-3d context throughout. */
    .hx-scene {
      position: absolute;
      inset: 0;
      transform-style: preserve-3d;
      visibility: hidden;
      pointer-events: none;
      transition: visibility .66s;
    }

    .hx-scene.is-on,
    .hx-scene.is-out {
      visibility: visible;
    }

    /* What actually cross-fades. Incoming starts a beat behind the exit, so
       the outgoing is already clearing before this arrives — the overlap is
       what stops it reading as two separate events. */
    .hx-scene .hx-card-in,
    .hx-scene .hx-trace,
    .hx-scene .voip-link,
    .hx-scene .voip-thread {
      opacity: 0;
      transition: opacity .66s var(--e) .16s;
    }

    .hx-scene.is-on .hx-card-in,
    .hx-scene.is-on .hx-trace,
    .hx-scene.is-on .voip-link,
    .hx-scene.is-on .voip-thread {
      opacity: 1;
    }

    /* and out, accelerating, against the entrance's ease-out */
    .hx-scene.is-out .hx-card-in,
    .hx-scene.is-out .hx-trace,
    .hx-scene.is-out .voip-link,
    .hx-scene.is-out .voip-thread {
      opacity: 0;
      transition: opacity .52s cubic-bezier(.37, 0, .63, 1);
    }

    /* The card holds the exact pose it held while live. Its depth comes from
       translateZ, and the perspective scales the box by ~4% at 56px — so a
       card that lost that transform on the way out would visibly shrink at
       the moment it started leaving, which is precisely the fixed-frame
       movement this hero must never show. */
    .hx-scene.is-out .hx-card {
      transform: translate3d(0, 0, var(--z, 40px));
    }

    /* The cards are the motion in this hero now. Each enters from the side it
       sits on — the lead from the left edge it overlaps, the trail up from the
       bottom — then, once it has landed, takes over a 2.5px drift that runs
       forever on its own clock, so the two never bob in lockstep.

       The drift is an animation and the entrance is a transition, on the same
       element; they do not collide because the animation is delayed past the
       end of the entrance and its keyframes resolve to the same resting
       transform the entrance finishes on. */
    /* The frame holds absolutely still. It used to slide in — the lead from
       -26px, the trail up from +22px — and it used to drift on an endless bob.
       Both made sense when each scene's card was its own shape. Now that all
       five share one box, the outgoing frame sat still while the incoming one
       slid 26px into the very same place, and the two bobs cross-faded out of
       phase. A fixed frame that visibly moves is the one thing this must not
       look like, so the motion moved inward: see .hx-txt below. */
    .hx-scene .hx-card {
      transform: translate3d(0, 0, var(--z, 40px));
    }

    .hx-scene.is-on .hx-card {
      /* the scene stays transparent to the pointer; only the cards take it */
      pointer-events: auto;
    }

    /* What arrives is the content, not the container: the mark and the text
       rise 6px under the scene's cross-fade, the trail an eighth of a second
       behind the lead so the pair does not land on one frame. */
    .hx-scene .hx-txt,
    .hx-scene .hx-ico,
    .hx-scene .voip-ico {
      transform: translateY(6px);
      transition: transform .7s var(--e);
      transition-delay: calc(var(--i, 0) * 100ms);
    }

    .hx-scene.is-on .hx-txt,
    .hx-scene.is-on .hx-ico,
    .hx-scene.is-on .voip-ico {
      transform: none;
    }

    /* The content carries on upward as it goes rather than sinking back the
       way it came. Outgoing rises 5px further, incoming starts 6px below —
       so across the swap the eye follows one continuous rise, and the two
       cards leave 40ms apart, half the interval they arrive on. */
    .hx-scene.is-out .hx-txt,
    .hx-scene.is-out .hx-ico,
    .hx-scene.is-out .voip-ico {
      transform: translateY(-5px);
      transition: transform .52s cubic-bezier(.37, 0, .63, 1);
      transition-delay: calc(var(--i, 0) * 60ms);
    }

    /* ---------- the floating card ---------- */
    /* Two elements, one card. The outer is only ever placed and moved — it
       owns the entrance and the drift. The inner is the card you can see, and
       it owns the hover lift. Collapsing them back into one element is what
       would put three separate effects on a single transform. */
    .hx-card {
      position: absolute;
    }

    .hx-card-in {
      display: grid;
      /* the frame decides the box, so the inner fills whatever .hx-card gives
         it and clips. Without the hidden overflow a long line would still push
         the visible edge out even though the outer box held its size. */
      width: 100%;
      height: 100%;
      box-sizing: border-box;
      overflow: hidden;
      align-content: center;
      padding: 11px 15px;
      border-radius: 14px;
      /* The cards take the page's own cream rather than white. The lead card
         overhangs the photograph's left edge by 3%, and on white that overhang
         read as a separate block laid over the page; in --bg it simply is the
         page, and only the part across the shot reads as a card at all.

         Translucent, chosen deliberately over the opaque version. Two things
         to know before touching this number:

         70% is the floor, not a preference. .s in --ink-soft on the device
         card lies over the darkest part of the shot and measures 5.09:1 here,
         4.64:1 at 62% and 3.95:1 at 48% — the last is under the 4.5:1 AA line
         for body text. Going lower trades away legibility, not polish.

         And this is flat alpha, not frosted glass. backdrop-filter is inert on
         these cards: they sit in a preserve-3d scene at a different Z from
         .hx-plate, so the photograph never reaches their backdrop and
         blur(16px), blur(30px) and no filter at all render identically.
         Adding one back would be dead code.

         For the opaque version, restore: background: var(--bg); and drop the
         #fff mix from the border below. */
      background: color-mix(in srgb, var(--bg) 70%, transparent);
      border: 1px solid color-mix(in srgb, #fff 50%, color-mix(in srgb, var(--line) 62%, transparent));
      box-shadow:
        0 1px 2px rgba(10, 40, 60, .06),
        0 14px 30px -12px rgba(10, 45, 70, .34);
      color: var(--ink);
      transition: transform .34s var(--e), box-shadow .34s var(--e);
    }

    /* The text is a container in its own right, not a set of rows the frame
       happens to hold. That separation is what lets the copy be centred,
       nudged or re-stacked without any of it reaching the box — and it gives
       the entrance something to move that is not the frame. */
    .hx-txt {
      display: grid;
      gap: 2px;
      min-width: 0;
    }

    .hx-card .k {
      font-size: 10.5px;
      font-weight: 800;
      letter-spacing: .155em;
      text-transform: uppercase;
      color: var(--blue-ink);
    }

    /* Wrapping, not nowrap. Inside a box that will not grow, the copy is what
       has to give: two clamped lines is a controlled failure, an overflowing
       card is not. Both lines keep their box height either way, so a longer
       string can never move the frame. */
    .hx-card .v {
      font-size: clamp(12.5px, 1vw, 14px);
      font-weight: 700;
      line-height: 1.28;
      letter-spacing: -.01em;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      line-clamp: 2;
      overflow: hidden;
    }

    .hx-card .s {
      font-size: clamp(11px, .9vw, 12.5px);
      line-height: 1.4;
      color: var(--ink-soft);
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      line-clamp: 2;
      overflow: hidden;
    }

    /* The three carriers were pills. Three bordered chips spend ~54px on
       padding and 12px on gaps before a single letter is set, which made the
       5G card the widest of the five for no editorial reason. As a line they
       keep the chips' blue and weight, so they still read as the deliberate,
       interactive-looking thing they were. */
    .hx-card .s.carriers {
      color: var(--blue-ink);
      font-weight: 600;
    }

    /* whatever image a scene puts in a card crops to its slot rather than
       sizing it — the natural dimensions of the file never reach the layout */
    .hx-card img {
      display: block;
      max-width: 100%;
      max-height: 100%;
      object-fit: cover;
    }

    /* The plate starts 8% in from the left of the frame, so a card at left:0
       hangs off the photograph entirely and reads as clipped rather than
       layered. At 3% it still breaks the photograph's edge — which is the
       point — but lands most of its width on the shot. */
    /* ---- the two fixed frames ----
       Each position is a picture frame: one size for the lead, one for the
       trail, and neither depends on what the scene hangs inside it. Sized as a
       share of the photograph rather than in px alone so the pair tracks the
       shot as it scales, with px bounds so neither collapses on a small frame
       nor swells on a large one. Nothing below is scoped to a scene. */
    .hx-card.lead {
      left: 5%;
      top: 15%;
      /* With One-stop's mark and pills gone, the widest thing left in any
         lead scene is a 23-character title, so the frame comes in ~40px.
         Depth is set by scene 04 — eyebrow, title, and a row of faces that
         cannot go below 26px and still read as people. That is the box that
         cannot be made thinner, so it sets the height for all five. */
      width: clamp(216px, 33%, 236px);
      height: clamp(88px, 17.5%, 94px);
      --z: 74px;
    }

    /* 5%, not 2%: translateZ scales the card about the frame's centre, which
       pushes its far edge outward and spends most of a small inset. At 2% the
       card landed 1px from the photograph's right edge — the same accidental
       alignment the lead card had on the left. */
    .hx-card.trail {
      right: 5%;
      bottom: 13%;
      /* Two text rows beside a 26px mark, which is as thin as a legible card
         of this shape gets: 18px title, 17px line beneath, 22px of padding.
         All five trail scenes are that same shape, so none is padded out to
         meet a taller sibling. Width follows the longest title, now "All 3
         Nationwide 5G Carriers" at 28 characters rather than 31, which holds
         one line at the capped 14px — that is what retired the two-line
         allowance the old height was carrying. */
      width: clamp(258px, 41%, 282px);
      height: clamp(62px, 13%, 70px);
      --z: 56px;
    }

    /* ---------- hx-scene furniture ---------- */
    /* live waveform (VoIP) */
    .hx-eq {
      display: flex;
      align-items: flex-end;
      gap: 3px;
      height: 22px;
      margin-top: 4px;
    }

    .hx-eq i {
      width: 3px;
      border-radius: 2px;
      background: linear-gradient(180deg, var(--blue), var(--magenta));
      animation: hx-wave 1.15s ease-in-out var(--warm) infinite;
    }

    @keyframes hx-wave {
      0%, 100% { height: 22%; }
      50% { height: 100%; }
    }

    /* ---------- 01 · VoIP ----------
       Everything here is scoped to .voip. The other four scenes keep the
       shared card furniture exactly as it was. */

    /* "Live call" reads as a state, not a heading, so it takes a pulsing
       green marker and the ink colour the rest of the card uses. */
    .voip .hx-card.lead .k {
      --live: #2eb872;
      display: flex;
      align-items: center;
      gap: 6px;
      color: var(--ink);
    }

    .voip .hx-card.lead .k i {
      flex: none;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--live);
      animation: voip-live 2.2s ease-out infinite;
    }

    /* the ring expands and fades rather than the dot itself moving — a dot
       that scales next to 10.5px type reads as a wobble */
    @keyframes voip-live {
      0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--live) 50%, transparent); }
      70%, 100% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--live) 0%, transparent); }
    }

    /* one instrument, one colour: at 3px wide the blue-to-magenta ramp only
       muddied each bar rather than reading as a gradient */
    .voip .hx-eq i {
      background: var(--magenta);
    }

    /* the device line takes a mark, so the two cards are not the same shape
       twice — icon and copy side by side instead of stacked */
    .voip .hx-card.trail .hx-card-in {
      grid-template-columns: auto minmax(0, 1fr);
      align-items: center;
      /* matched to .hx-ico-row, so the headset sits on the same rhythm as the
         four marks in the other trail scenes */
      gap: 9px;
    }

    .voip-ico {
      display: grid;
      place-items: center;
      width: 26px;
      height: 26px;
      border-radius: 9px;
      color: var(--magenta);
      background: color-mix(in srgb, var(--magenta) 10%, transparent);
    }

    .voip-ico svg {
      width: 15px;
      height: 15px;
      fill: none;
      stroke: currentColor;
      stroke-width: 1.7;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    /* height is left to the viewBox so the curve keeps its shape at every
       frame width instead of being squashed by a percentage box */
    .voip-thread {
      position: absolute;
      left: 0;
      top: 32%;
      width: 24%;
      overflow: visible;
      pointer-events: none;
    }

    .voip-thread path {
      stroke: var(--magenta);
      stroke-width: 1.6;
      stroke-linecap: round;
      stroke-dasharray: 3 6;
      opacity: .5;
      animation: voip-thread 30s linear infinite;
    }

    /* the dot keeps more of the colour than the line does — it is the anchor,
       and at 11px across it needs the weight the dashes can afford to lose */
    .voip-thread circle {
      fill: var(--magenta);
      opacity: .85;
    }

    /* the dashes crawl toward the desk, slowly enough to be felt rather than
       watched — the card is the subject, this is only its tether */
    @keyframes voip-thread {
      to { stroke-dashoffset: -270; }
    }

    /* the headset-to-device link. Solid rather than dashed: it crosses the
       photograph, and a dashed line over a busy image reads as broken. */
    .voip-link {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      overflow: visible;
      pointer-events: none;
      /* the shot is dark behind the vertical run — the same edge the 5G
         hairlines need to survive the window and the desk */
      filter: drop-shadow(0 1px 2px rgba(4, 40, 62, .45));
    }

    .voip-link path {
      fill: none;
      stroke: var(--magenta);
      stroke-width: 1.2;
      stroke-linecap: round;
      stroke-linejoin: round;
      opacity: .64;
    }

    /* the dots stay ahead of the line, as on the dashed thread — they are the
       two things the line exists to name, and at 4.6 units they thin out
       faster than a stroke does */
    /* a pulse runs the line headset-to-device, the same way the 5G layer
       shows traffic on its links. pathLength normalises the path to 100
       units, so the dash numbers below are read as percentages of the run
       rather than as user units that would need retuning if the route
       changes again. */
    .voip-flow {
      fill: none;
      stroke: var(--magenta);
      stroke-width: 1.6;
      stroke-linecap: round;
      stroke-dasharray: 8 100;
      opacity: 0;
      animation: voip-flow var(--flow) ease-in-out infinite;
    }

    /* the travel takes the first two thirds; the rest is a pause, so the line
       is mostly still and the pulse reads as an event rather than a conveyor */
    @keyframes voip-flow {
      0% { stroke-dashoffset: 0; opacity: 0; }
      10% { opacity: .88; }
      54% { opacity: .88; }
      64% { stroke-dashoffset: -108; opacity: 0; }
      100% { stroke-dashoffset: -108; opacity: 0; }
    }

    /* ---- the handset line ----
       This scene used to override the shared pulse with a run of its own that
       arrived at 20% of the cycle — against 56% everywhere else, which read as
       one line in the set moving at nearly three times the speed of the other
       four. The override is gone: the handset run is the house pulse, so it
       travels for exactly as long as every other trace does. What is still
       this scene's own is what happens on arrival — the card rings rather
       than sparking — and the rings below hang off the shared 56% stop. */

    /* ---- the handset line rings ----
       Every other scene moves something along a line. This one deliberately
       does not: the card itself rings, two beats and a rest, the cadence a
       desk phone actually uses. It keeps every other part of the vocabulary
       — the same box, the same mark, the same brand colour, a pause far
       longer than the movement — so it reads as this hero speaking, not as a
       different component. Not every scene needing a line is what keeps the
       set from feeling formulaic. */
    .ring-ico {
      position: relative;
    }

    .ring-ico i {
      position: absolute;
      inset: 0;
      border-radius: 9px;
      border: 1.5px solid var(--magenta);
      opacity: 0;
      pointer-events: none;
    }

    /* two rings 420ms apart, then the rest of the cycle quiet. The .56 and the
       240ms are the shared pulse's arrival — its 240ms start delay plus the
       -92 stop at 56% — so the first ring sounds on the frame the line lands.
       Both numbers have to move if hx-trace-flow's arrival ever does. */
    .hx-scene.is-on .ring-ico i {
      animation: hx-handset var(--flow) ease-out calc(var(--flow) * .56 + 240ms) infinite;
    }

    /* the second beat, 420ms after the first — the only absolute number
       left in the set, because a ring cadence is a fixed human interval and
       does not scale with the length of the run that triggered it */
    .hx-scene.is-on .ring-ico i:nth-child(3) {
      animation-delay: calc(var(--flow) * .56 + 660ms);
    }

    @keyframes hx-handset {
      0% {
        opacity: .6;
        transform: scale(1);
      }

      20% {
        opacity: 0;
        transform: scale(2.05);
      }

      100% {
        opacity: 0;
        transform: scale(2.05);
      }
    }

    /* the glyph gives a little on each beat, the way a handset does when it
       sounds. Its own beats sit at 20% and 35% of the keyframes below, so the
       delay carries the first of them onto the arrival the rings use: .56 of
       the run, less the 20% the tap already waits, plus the pulse's 240ms. */
    .hx-scene.is-on .ring-ico svg {
      animation: hx-handset-tap var(--flow) ease-out calc(var(--flow) * .36 + 240ms) infinite;
    }

    @keyframes hx-handset-tap {

      0%,
      20% {
        transform: scale(1);
      }

      23% {
        transform: scale(1.14);
      }

      30%,
      32% {
        transform: scale(1);
      }

      35% {
        transform: scale(1.14);
      }

      43%,
      100% {
        transform: scale(1);
      }
    }

    /* ================= scene traces =================
       The voip link generalised to the rest of the rail. Same frame-space
       400x315 viewBox, so a route can be pinned to a real point in the
       photograph rather than to a guessed percentage; same pathLength="100"
       so the dash numbers read as percentages of the run whatever the route.

       What changes per scene is the route and the colour, both declared on
       the scene itself (--trace), so the movement belongs to the capability
       being read rather than being one house animation played five times.

       Every route keeps to the shelf, the desk or the background. None of
       them crosses the agent — she is the subject, not a surface to draw on. */
    .hx-trace {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      overflow: visible;
      pointer-events: none;
      /* the same edge the 5G hairlines need to survive the bright window and
         the dark desk in one line */
      filter: drop-shadow(0 1px 2px rgba(4, 40, 62, .45));
    }

    .hx-trace path {
      fill: none;
      stroke: var(--trace, var(--blue));
      stroke-width: 1.2;
      stroke-linecap: round;
      stroke-linejoin: round;
      opacity: .62;
    }

    /* The route draws itself in as the scene arrives, so the connector is
       part of the change rather than something that fades up beside it. It
       runs under the card entrance and finishes just before the first pulse
       is due, which is what makes the line feel like it brought the pulse
       with it. */
    .hx-scene.is-on .hx-trace path:not(.t-flow),
    .hx-scene.is-on .voip-link path:not(.voip-flow) {
      animation: hx-draw .82s var(--e) 160ms both;
    }

    @keyframes hx-draw {
      from {
        stroke-dasharray: 0 101;
      }

      to {
        stroke-dasharray: 100 0;
      }
    }

    .hx-trace circle {
      fill: var(--trace, var(--blue));
      opacity: .82;
    }

    /* the pulse is declared on .is-on, not on the element, so it starts from
       the top every time the scene arrives — on a click and on the rail's own
       rotation alike, which is what ties the two together */
    .hx-scene.is-on .hx-trace .t-flow {
      stroke-width: 1.7;
      stroke-dasharray: 8 100;
      opacity: 0;
      animation: hx-trace-flow var(--flow) ease-in-out 240ms infinite;
    }

    /* travel occupies two thirds, the rest is rest: the line is mostly still,
       so the pulse reads as an event rather than as a conveyor belt */
    @keyframes hx-trace-flow {
      0% { stroke-dashoffset: 0; opacity: 0; }
      10% { opacity: .88; }
      /* Arrival, stated rather than inferred. The dash is 8 units of a
         100-unit path, so its leading edge touches the far end when the
         offset reaches -92 — and declaring that here fixes the moment at
         56% of the cycle no matter what easing runs either side of it.
         Everything that reacts to the arrival hangs off this number.

         Which is also what caps the duration. A scene is up for CYCLE/6 =
         6000ms, and the ring is still fading at 76% of the cycle, so
         240ms + .76d must stay under that. The tighter cap is the handset
         scene's second ring, which lands at .76d + 660ms: that puts the
         ceiling at 7026ms. 6.6s lands it at 5676ms and fits. To run the
         travel slower than that, raise CYCLE first. */
      56% { stroke-dashoffset: -92; opacity: .88; }
      66% { stroke-dashoffset: -108; opacity: 0; }
      100% { stroke-dashoffset: -108; opacity: 0; }
    }

    /* ---- arrival ----
       The pulse reaching the far end is the whole point of the trace, so it
       is given a moment rather than being left to fade out. Spark, ring and
       the box's own answer all run on the flow's clock — same 4.8s, same
       240ms delay — and all three are hung off the 56% arrival keyframe
       above. Sharing one clock is what keeps them in step: nothing here is
       timed independently, so nothing can drift out of sync with the dot.

       The order is deliberate. The spark lands first and hardest, the ring
       opens a beat behind it, and the box answers last and slowest — impact,
       then report, then response. All of it is over inside half a second. */
    .hx-scene.is-on .hx-trace .t-spark {
      fill: var(--trace, var(--blue));
      transform-box: fill-box;
      transform-origin: center;
      opacity: 0;
      animation: hx-spark var(--flow) ease-out 240ms infinite;
    }

    @keyframes hx-spark {

      0%,
      53% {
        opacity: 0;
        transform: scale(.3);
      }

      /* one frame past arrival: the flare is the contact, not the approach */
      57% {
        opacity: .95;
        transform: scale(1.1);
      }

      63% {
        opacity: .3;
        transform: scale(1.55);
      }

      70%,
      100% {
        opacity: 0;
        transform: scale(1.8);
      }
    }

    .hx-scene.is-on .hx-trace .t-ring {
      fill: none;
      stroke: var(--trace, var(--blue));
      stroke-width: 1.1;
      transform-box: fill-box;
      transform-origin: center;
      opacity: 0;
      animation: hx-ring var(--flow) cubic-bezier(.16, 1, .3, 1) 240ms infinite;
    }

    @keyframes hx-ring {

      0%,
      55% {
        opacity: 0;
        transform: scale(.55);
      }

      59% {
        opacity: .5;
      }

      76%,
      100% {
        opacity: 0;
        transform: scale(3.3);
      }
    }

    /* the box answers: a rim light around the whole card for the activation,
       and a small bloom at the corner the line actually touched, so the
       reaction reads as located rather than as the card simply flashing */
    .hx-scene.has-impact .hx-card.trail::before {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: 14px;
      pointer-events: none;
      opacity: 0;
      /* Two blooms, not one: a tight hot spot exactly where the line lands,
         and a wider wash behind it. Both are kept inside the padding band at
         the card's edge — the body text was measured to 5.09:1 on this shot
         and tinting over it to make a flourish visible would be a poor trade.
         The rim carries most of the weight instead: it reads clearly against
         a busy photograph and costs the text nothing. */
      background:
        radial-gradient(26px 19px at var(--impact, 50% 100%),
          color-mix(in srgb, var(--trace, var(--blue)) 52%, transparent),
          transparent 74%),
        radial-gradient(62px 34px at var(--impact, 50% 100%),
          color-mix(in srgb, var(--trace, var(--blue)) 24%, transparent),
          transparent 76%);
      box-shadow:
        0 0 0 1.2px color-mix(in srgb, var(--trace, var(--blue)) 46%, transparent),
        0 0 20px 2px color-mix(in srgb, var(--trace, var(--blue)) 26%, transparent);
    }

    .hx-scene.has-impact.is-on .hx-card.trail::before {
      animation: hx-impact var(--flow) cubic-bezier(.16, 1, .3, 1) 240ms infinite;
    }

    /* in and straight back out: the card is briefly lit, never left glowing */
    @keyframes hx-impact {

      0%,
      54% {
        opacity: 0;
      }

      59% {
        opacity: 1;
      }

      74%,
      100% {
        opacity: 0;
      }
    }

    /* ---- the mark answers when its scene arrives ----
       One ring, twice, then silence. A mark that pulsed forever would compete
       with the trace it is meant to introduce. */
    .hx-ico {
      position: relative;
    }

    .hx-ico::after {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: 50%;
      border: 1px solid currentColor;
      opacity: 0;
      pointer-events: none;
    }

    .hx-scene.is-on .hx-ico::after {
      animation: hx-ping 2.4s cubic-bezier(.22, 1, .36, 1) 400ms 2;
    }

    @keyframes hx-ping {
      0% { transform: scale(1); opacity: .5; }
      60%, 100% { transform: scale(2.2); opacity: 0; }
    }

    /* ---- and the card it belongs to lights once ----
       On the outer element: the inner one clips its overflow, so a ring drawn
       there would be cut off at the card's own edge. */
    .hx-card::after {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: 14px;
      opacity: 0;
      pointer-events: none;
    }

    .hx-scene.is-on .hx-card::after {
      animation: hx-bloom 1.7s cubic-bezier(.22, 1, .36, 1) 220ms both;
    }

    @keyframes hx-bloom {
      0% {
        opacity: 0;
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--trace, var(--blue)) 42%, transparent);
      }

      26% {
        opacity: 1;
      }

      100% {
        opacity: 0;
        box-shadow: 0 0 0 11px color-mix(in srgb, var(--trace, var(--blue)) 0%, transparent);
      }
    }

    .voip-link circle {
      fill: var(--magenta);
      /* raised with the line, not independently: the dots are only legible as
         endpoints while they stay ahead of the stroke, and at .52 against a
         .44 line they had stopped reading as separate marks */
      opacity: .84;
    }

    /* carrier hx-chips */
    .hx-chips {
      display: flex;
      /* the three chips are a fixed 150px of nowrap content; where the card is
         capped narrower than that — the 5G scene at laptop widths — an
         unwrappable row sets the card's min-content width and it overflows the
         photograph instead of obeying the cap */
      flex-wrap: wrap;
      gap: 6px;
      margin-top: 7px;
    }

    .hx-chips span {
      padding: 4px 9px;
      border-radius: 20px;
      background: color-mix(in srgb, var(--blue) 9%, var(--surface));
      border: 1px solid color-mix(in srgb, var(--blue) 20%, transparent);
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .02em;
      color: var(--blue-ink);
      white-space: nowrap;
    }

    /* team hx-faces */
    /* The faces now lead somewhere. The arrow is the affordance, so the row
       becomes faces + link rather than faces alone, and the row owns the
       top margin the faces used to carry. */
    .hx-faces-row {
      display: flex;
      align-items: center;
      gap: 9px;
      margin-top: 5px;
    }

    .hx-faces {
      display: flex;
    }

    /* ---- stat card with a mark ----
       The team scene's second card leads with the same people mark the team
       page's 42+ badge carries, in the same magenta as the arrow beside it,
       so the three read as one component family rather than three ideas. */
    .hx-card-in.hx-ico-row {
      grid-template-columns: auto minmax(0, 1fr);
      align-items: center;
      /* 9px, not 11: the mark and its gap are 35px of the trail card's width
         before a letter is set, and that width is what the longest title has
         to live inside */
      gap: 9px;
    }

    .hx-ico {
      flex: none;
      display: grid;
      place-items: center;
      width: 26px;
      height: 26px;
      border-radius: 50%;
      color: var(--magenta-ink);
      background: color-mix(in srgb, var(--magenta) 12%, transparent);
    }

    .hx-ico svg {
      display: block;
      width: 17px;
      height: 17px;
      fill: none;
      stroke: currentColor;
      stroke-width: 1.7;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .hx-go {
      flex: none;
      display: grid;
      place-items: center;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      color: var(--magenta-ink);
      background: color-mix(in srgb, var(--magenta) 12%, transparent);
      transition: transform .25s var(--e), background .25s, color .25s;
    }

    .hx-go svg {
      display: block;
      width: 16px;
      height: 16px;
      fill: none;
      stroke: currentColor;
      stroke-width: 2.2;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .hx-go:hover {
      transform: translateX(3px);
      background: var(--magenta-ink);
      color: #fff;
    }

    .hx-go:focus-visible {
      outline: 2px solid var(--blue);
      outline-offset: 2px;
    }

    /* 26px, not 34: this row is what sets how deep every lead card has to be,
       and below 26 a face stops reading as a person */
    .hx-faces img {
      width: 26px;
      height: 26px;
      border-radius: 50%;
      object-fit: cover;
      object-position: 50% 22%;
      border: 2px solid var(--surface);
      box-shadow: 0 1px 4px rgba(10, 40, 60, .22);
    }

    .hx-faces img+img {
      margin-left: -9px;
    }

    /* hx-stars — the rating starts empty and is earned on arrival, so the
       off state is a real colour rather than a faded one: a star nobody has
       filled yet still has to read as a star. */
    .hx-stars {
      --star-on: #f5a623;
      --star-off: color-mix(in srgb, #f5a623 28%, var(--surface));
      display: flex;
      gap: 3px;
      margin-top: 5px;
      color: var(--star-on);
    }

    .hx-stars svg {
      --sd: 0ms;
      width: 17px;
      height: 17px;
      fill: var(--star-off);
    }

    /* ---------- HBE 5G — the technology layer ----------
       The hero now reads in two layers: the photograph is the real world,
       and this is the technology sitting on top of it. It is deliberately
       outside the five rotating scenes — the rail only reaches 5G six
       seconds in, and the offer has to land on the first second.

       Everything is sized in percentages of the frame so the whole system
       scales with the shot rather than drifting off the objects it points
       at. It reveals in the order the eye should read it: hub, then waves,
       then links, then traffic. */
    /* The layer belongs to rail point 02 and nothing else. It is shown by
       .is-5g on the frame, which the rail sets, and every animation below is
       scoped to that class — so the sequence replays from the top each time
       point 02 comes round, rather than having run once at page load while
       the layer was still hidden.

       Appearing is instant (the children's own entrances do the reveal);
       leaving is a fade, so the layer does not simply blink out. */
    .hx-5g {
      position: absolute;
      inset: 0;
      pointer-events: none;
      opacity: 0;
      visibility: hidden;
      transition: opacity .4s var(--e), visibility .4s;
    }

    .hx-frame.is-5g .hx-5g {
      opacity: 1;
      visibility: visible;
      transition-duration: .01s, .01s;
    }

    /* ---- the network: three links onto real objects in the shot ---- */
    .g5-net {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      overflow: visible;
      /* the shot is bright on the left and dark on the right; without an edge
         the hairlines simply vanish over the window and the desk */
      filter: drop-shadow(0 1px 2px rgba(4, 40, 62, .6));
    }

    .g5-link {
      fill: none;
      stroke: rgba(255, 255, 255, .62);
      stroke-width: .85;
      stroke-linecap: round;
      opacity: 0;
    }

    @keyframes g5-fade {
      to {
        opacity: 1;
      }
    }

    /* the traffic. pathLength normalises all three to 100 units, so one set
       of dash numbers moves at the same speed down links of different
       lengths instead of racing on the short one. */
    .g5-flow {
      fill: none;
      stroke: rgba(255, 255, 255, .7);
      stroke-width: 1.5;
      stroke-linecap: round;
      stroke-dasharray: 7 100;
      stroke-dashoffset: 0;
      opacity: 0;
    }

    @keyframes g5-flow {
      0% {
        stroke-dashoffset: 0;
        opacity: 0;
      }

      8% {
        opacity: .95;
      }

      58% {
        opacity: .95;
      }

      66% {
        stroke-dashoffset: -100;
        opacity: 0;
      }

      100% {
        stroke-dashoffset: -100;
        opacity: 0;
      }
    }

    .g5-end {
      fill: rgba(255, 255, 255, .88);
      opacity: 0;
    }

    /* scaled rather than r-animated: transform is the property every engine
       has always interpolated on an SVG shape */
    .g5-halo {
      fill: none;
      stroke: rgba(255, 255, 255, .68);
      stroke-width: .8;
      transform-box: fill-box;
      transform-origin: center;
      opacity: 0;
    }

    @keyframes g5-halo {
      0% {
        transform: scale(.6);
        opacity: 0;
      }

      14% {
        opacity: .75;
      }

      70%,
      100% {
        transform: scale(3.6);
        opacity: 0;
      }
    }

    /* ---- the source ---- */
    .g5-hub {
      position: absolute;
      left: 34%;
      top: 44%;
      width: 15.5%;
      aspect-ratio: 1;
      translate: -50% -50%;
      display: grid;
      place-items: center;
    }

    .g5-wave {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      border: 1px solid rgba(255, 255, 255, .85);
      translate: -50% -50%;
      filter: drop-shadow(0 0 3px rgba(4, 40, 62, .5));
      opacity: 0;
    }

    /* one ring in brand magenta, so the system reads as HBE's and not as a
       generic signal graphic. One is the whole budget. */
    .g5-wave:nth-child(2) {
      border-color: color-mix(in srgb, var(--magenta) 62%, transparent);
    }

    @keyframes g5-wave {
      0% {
        transform: scale(.62);
        opacity: 0;
      }

      12% {
        opacity: .72;
      }

      100% {
        transform: scale(2.6);
        opacity: 0;
      }
    }

    .g5-core {
      position: relative;
      z-index: 2;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      display: grid;
      place-items: center;
      align-content: center;
      gap: 1px;
      text-align: center;
      color: #fff;
      /* the disc sits back a stop: alpha on the fill rather than on the
         element, so the white HBE 5G mark on top stays fully opaque
         (4.83:1 against the disc at .74; below about .72 the small HBE
         caps drop under the 4.5:1 line, so this is the floor) */
      background: linear-gradient(150deg, rgba(11, 111, 158, .74) 0%, rgba(7, 90, 131, .74) 52%, rgba(6, 64, 94, .74) 100%);
      border: 1px solid rgba(255, 255, 255, .3);
      box-shadow:
        0 18px 40px -14px rgba(4, 40, 62, .85),
        inset 0 1px 0 rgba(255, 255, 255, .22);
      opacity: 0;
    }

    @keyframes g5-core-in {
      from {
        opacity: 0;
        transform: scale(.84);
      }

      to {
        opacity: 1;
        transform: none;
      }
    }

    .g5-core i {
      font-style: normal;
      font-size: clamp(7.5px, .72vw, 10px);
      font-weight: 800;
      letter-spacing: .2em;
      opacity: .82;
    }

    .g5-core b {
      font-family: var(--serif);
      font-size: clamp(20px, 2.5vw, 34px);
      font-weight: 600;
      line-height: .92;
      letter-spacing: -.01em;
    }

    .g5-meter {
      display: flex;
      align-items: flex-end;
      gap: 3.5px;
      height: 22px;
      margin-top: 1px;
    }

    .g5-meter i {
      width: 6px;
      border-radius: 1.5px;
      background: linear-gradient(180deg, var(--blue), var(--magenta));
    }

    .g5-meter i:nth-child(1) { height: 28%; animation-delay: 0ms; }
    .g5-meter i:nth-child(2) { height: 46%; animation-delay: 110ms; }
    .g5-meter i:nth-child(3) { height: 64%; animation-delay: 220ms; }
    .g5-meter i:nth-child(4) { height: 82%; animation-delay: 330ms; }
    .g5-meter i:nth-child(5) { height: 100%; animation-delay: 440ms; }

    @keyframes g5-meter {

      0%,
      12% {
        opacity: .24;
      }

      28%,
      74% {
        opacity: 1;
      }

      90%,
      100% {
        opacity: .24;
      }
    }

    /* The whole sequence, timed from the moment point 02 becomes active
       rather than from page load: assembled inside 1.6s of a 6s dwell.
       .g5-meter takes longhands, not the shorthand — the shorthand would
       reset the per-bar animation-delay set on the nth-child rules above. */
    .hx-frame.is-5g .g5-core {
      animation: g5-core-in .7s var(--e) 120ms both;
    }

    .hx-frame.is-5g .g5-wave {
      animation: g5-wave 4.5s ease-out calc(380ms + var(--w, 0ms)) infinite;
    }

    .hx-frame.is-5g .g5-link {
      animation: g5-fade .7s var(--e) 520ms both;
    }

    .hx-frame.is-5g .g5-end {
      animation: g5-fade .6s var(--e) 640ms both;
    }

    .hx-frame.is-5g .g5-flow {
      animation: g5-flow var(--flow) linear calc(820ms + var(--fl, 0ms)) infinite;
    }

    .hx-frame.is-5g .g5-halo {
      animation: g5-halo var(--flow) ease-out calc(1000ms + var(--el, 0ms)) infinite;
    }

    .hx-frame.is-5g .g5-meter i {
      animation-name: g5-meter;
      animation-duration: 2.4s;
      animation-timing-function: ease-in-out;
      animation-iteration-count: infinite;
      animation-delay: var(--warm);
    }

    /* ---- the offer, in scene 02's lead card ----
       The card the rail already put here used to read "Signal / 5G fixed
       wireless"; it now carries the offer itself, at badge weight rather than
       card weight, so point 02 makes its case in one block instead of two. */
    /* Same metrics as every other card in the stage — padding, radius, gap,
       type sizes all inherited. The only thing it needs of its own is a width
       to wrap inside: its title is long enough to hold one line at 236px,
       half again as wide as the cards it sits among. Capped, the title breaks
       after "Wireless" and the card lands at the same size as the rest. */
    /* The 202px cap and the nowrap that used to live here sized the 5G lead
       card differently from the other four. The frame is fixed per position
       now, so both are gone — a box that changed when the scene changed is
       exactly what this is meant to prevent. */

    /* ---------- the instruments ----------
       Scene 01's waveform was the only thing in the stage that kept moving
       once the entrance had finished; the other four scenes were completely
       still, which is why the hero read as static. Each card now carries one
       slow, always-on movement that belongs to the thing it describes — the
       meter fills, the chips light in turn, the faces greet one at a time,
       the stars catch the light. Nothing here travels more than 3px. */

    /* 02 & 03 · the chips light in turn */
    .hx-scene.is-on .hx-chips span {
      animation: hx-chip 4.5s ease-in-out var(--warm) infinite;
    }

    .hx-chips span:nth-child(2) { animation-delay: calc(var(--warm) + .55s); }
    .hx-chips span:nth-child(3) { animation-delay: calc(var(--warm) + 1.1s); }

    @keyframes hx-chip {

      0%,
      52%,
      100% {
        background: color-mix(in srgb, var(--blue) 9%, var(--surface));
        border-color: color-mix(in srgb, var(--blue) 20%, transparent);
      }

      14%,
      30% {
        background: color-mix(in srgb, var(--blue) 18%, var(--surface));
        border-color: color-mix(in srgb, var(--blue) 44%, transparent);
      }
    }

    /* 04 · the faces greet one at a time */
    .hx-scene.is-on .hx-faces img {
      animation: hx-face 5.4s ease-in-out var(--warm) infinite;
    }

    .hx-faces img:nth-child(2) { animation-delay: calc(var(--warm) + .16s); }
    .hx-faces img:nth-child(3) { animation-delay: calc(var(--warm) + .32s); }
    .hx-faces img:nth-child(4) { animation-delay: calc(var(--warm) + .48s); }
    .hx-faces img:nth-child(5) { animation-delay: calc(var(--warm) + .64s); }

    @keyframes hx-face {

      0%,
      66%,
      100% {
        transform: translateY(0);
      }

      12%,
      22% {
        transform: translateY(-3px);
      }
    }

    /* 05 · the rating earns itself, over and over. One infinite cycle per
       star on a 120ms left-to-right stagger, so the row fills as a wave,
       holds its five gold, catches the light once, and empties to be earned
       again. Folding the old shimmer into this one keyframe set is what
       keeps it coherent — two loops on different periods would drift apart
       and read as noise. */
    .hx-scene.is-on .hx-stars svg {
      animation: hx-star-fill 3s ease-in-out calc(var(--warm) + var(--sd)) infinite;
    }

    .hx-stars svg:nth-child(2) { --sd: 120ms; }
    .hx-stars svg:nth-child(3) { --sd: 240ms; }
    .hx-stars svg:nth-child(4) { --sd: 360ms; }
    .hx-stars svg:nth-child(5) { --sd: 480ms; }

    @keyframes hx-star-fill {

      /* empty, waiting */
      0% {
        fill: var(--star-off);
        scale: .64;
        opacity: .8;
        /* the snappy curve on the fill segment only — the rest stays even */
        animation-timing-function: var(--e);
      }

      /* the gold arrives, overshooting the way a tapped rating lands */
      7% {
        fill: var(--star-on);
        scale: 1.26;
        opacity: 1;
      }

      12%,
      46% {
        fill: var(--star-on);
        scale: 1;
        opacity: .82;
      }

      /* mid-cycle, the light passes back across the row */
      54% {
        scale: 1.09;
        opacity: 1;
      }

      62%,
      90% {
        fill: var(--star-on);
        scale: 1;
        opacity: .82;
      }

      /* and it empties again */
      97%,
      100% {
        fill: var(--star-off);
        scale: .64;
        opacity: .8;
      }
    }

    /* ---------- reduced motion ---------- */
    @media (prefers-reduced-motion:reduce) {

      .hx-scene.is-on .hx-eq,
      .hx-scene.is-on .hx-chips,
      .hx-scene.is-on .hx-faces,
      .hx-scene.is-on .hx-stars,
      .hx-frame.is-5g .hx-5g .g5-meter {
        animation: none;
        opacity: 1;
      }

      .hx-eyebrow i,
      .hx-eq i,
      .voip .hx-card.lead .k i,
      .voip-thread path,
      .voip-flow {
        animation: none;
      }

      /* the ring is set on .hx-scene.is-on, so it has to be unset there too —
         a bare .ring-ico selector loses to it and the handset keeps ringing */
      .hx-scene.is-on .hx-trace path:not(.t-flow),
      .hx-scene.is-on .voip-link path:not(.voip-flow),
      .hx-scene.is-on .ring-ico i,
      .hx-scene.is-on .ring-ico svg {
        animation: none;
        opacity: 0;
      }

      .hx-scene.is-on .ring-ico svg {
        opacity: 1;
      }

      /* the traces stay drawn; only their traffic and the two one-shot
         flourishes are dropped */
      .hx-scene.is-on .hx-trace .t-spark,
      .hx-scene.is-on .hx-trace .t-ring,
      .hx-scene.has-impact.is-on .hx-card.trail::before,
      .hx-scene.is-on .hx-trace .t-flow,
      .hx-scene.is-on .hx-ico::after,
      .hx-scene.is-on .hx-card::after {
        animation: none;
        opacity: 0;
      }

      /* the instruments are set on .hx-scene.is-on, so switching them off here
         has to carry the same weight or the rule below simply loses */
      .hx-scene.is-on .hx-chips span,
      .hx-scene.is-on .hx-faces img {
        animation: none;
      }

      /* nothing to fill in without motion — the rating is simply already earned */
      .hx-scene.is-on .hx-stars svg {
        animation: none;
        fill: var(--star-on);
      }

      /* the 5G system holds its finished state: hub, one ring, the links and
         their endpoints all drawn, the meter at full strength */
      .hx-frame.is-5g .g5-link,
      .hx-frame.is-5g .g5-end,
      .hx-frame.is-5g .g5-core,
      .hx-frame.is-5g .g5-meter i,
      .hx-frame.is-5g .g5-wave,
      .hx-frame.is-5g .g5-halo,
      .hx-frame.is-5g .g5-flow {
        animation: none;
        opacity: 1;
        transform: none;
      }

      .hx-frame.is-5g .g5-flow,
      .hx-frame.is-5g .g5-halo {
        opacity: 0;
      }

      .hx-frame.is-5g .g5-wave {
        opacity: .34;
        translate: -50% -50%;
      }

      .hx-frame.is-5g .g5-wave:nth-child(1),
      .hx-frame.is-5g .g5-wave:nth-child(3) {
        opacity: 0;
      }

      .hx-5g {
        transition: none;
      }

      /* the bars take their height from the waveform keyframes, so stopping
         the animation empties the card. Frozen at a plausible spectrum, the
         card still reads as a live call. */
      .hx-eq i:nth-child(3n+1) { height: 38%; }
      .hx-eq i:nth-child(3n+2) { height: 76%; }
      .hx-eq i:nth-child(3n+3) { height: 55%; }

      .hx-frame {
        transition: none;
        transform: none;
      }

      .hx-scene,
      .hx-scene .hx-card,
      .hx-card-in,
      .hx-line>span,
      .hx-plate,
      .hx-plate img,
      .hero.mag h1 .hl-i,
      .hx-eyebrow,
      .hx-cta,
      ul.hero-points li {
        transition: none;
        animation: none;
      }

      /* no rotation without motion, so the first row simply shows a full bar */
      ul.hero-points li.is-on .hp-bar i {
        animation: none;
        transform: scaleX(1);
      }

      .hx-scene .hx-card,
      .hero.mag h1 .hl-i,
      .hx-eyebrow,
      .hx-cta,
      ul.hero-points li,
      .hx-plate {
        opacity: 1;
        transform: none;
      }

      .hx-pillars button[aria-selected="true"] .pr-bar i {
        animation: none;
        transform: scaleX(1);
      }
    }

    /* ---------- responsive ---------- */
    @media (max-width:1180px) {
      .hero.mag .wrap.mag-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 30px;
      }

      .hx-card .v { font-size: 14.5px; }
    }

    /* Between 901px and 1180px the frame shrinks but the scene cards do not —
       their text is nowrap, so they hold their desktop pixel width and end up
       eating two thirds of the photograph, straight through the 5G system.
       Both sides give ground here: the cards get a width they must wrap
       inside, and the badge moves down into the corner the trail card left. */
    @media (min-width:901px) and (max-width:1180px) {

      /* The cap here used to sit on the 5G scene alone. It now sizes both
         frames in every scene: the photograph is only ~330px wide at the foot
         of this band, and two boxes that changed size as the rotation stepped
         would be the most visible thing in the hero. The type comes down with
         them so the copy still fits the smaller box. */
      .hx-card.lead {
        width: 200px;
        height: 84px;
      }

      .hx-card.trail {
        width: 246px;
        height: 60px;
      }

      .hx-card-in {
        padding: 10px 12px;
        border-radius: 13px;
      }

      .hx-card .v {
        font-size: 13px;
      }

      .hx-card .s {
        font-size: 11px;
      }

      /* The text is a container in its own right, not a set of rows the frame
       happens to hold. That separation is what lets the copy be centred,
       nudged or re-stacked without any of it reaching the box — and it gives
       the entrance something to move that is not the frame. */
    .hx-txt {
      display: grid;
      gap: 2px;
      min-width: 0;
    }

    .hx-card .k {
        font-size: 9.5px;
      }

      /* Where the card is capped this narrow, a mark in its own column costs
         41px of the 152px the content has left — enough to force the carrier
         chips onto three lines. Stacked, the mark costs height instead and the
         chips keep their single row. */
      /* No longer scoped to .is-5g: that combination could never match, since
         the ico-row lives in scene 03 and .is-5g only ever sits on scene 02.
         Stacking the mark costs height instead of a 41px column, which is what
         keeps the three chips on one row inside the narrower frame. */
      .hx-card-in.hx-ico-row {
        grid-template-columns: minmax(0, 1fr);
        gap: 8px;
      }
    }

    @media (max-width:900px) {
      .hero.mag .wrap.mag-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 28px;
        padding: 30px 26px 44px;
      }

      .hero.mag h1 {
        max-width: 18ch;
      }

      .hx-line {
        min-height: 0;
        max-width: none;
      }

      /* one column: the rows are free to wrap, so the bar spans whatever the
         line actually occupies rather than forcing a single line */
      ul.hero-points {
        margin-top: 20px;
        gap: 12px;
      }

      ul.hero-points li {
        gap: 11px;
        font-size: 15.5px;
      }

      ul.hero-points li>span:last-child {
        white-space: normal;
      }

      .hp-ico {
        width: 25px;
        height: 25px;
        border-radius: 7px;
      }

      .hp-ico svg {
        width: 13px;
        height: 13px;
      }

      .hx-art {
        order: -1;
      }

      .hx-frame {
        aspect-ratio: 4 / 3;
        transform: none;
      }

      .hx-plate {
        inset: 0;
      }

      /* the column is narrower here, so the longest line needs four rows
         rather than three, and the floor has to match or the rail steps down
         whenever the longest line comes round */
      .hx-line {
        min-height: 6.6em;
      }

      /* 5% for the same reason as the wide layout: translateZ scales each
         card outward, so a 3% inset all but disappears against the edge */
      .hx-card.lead { top: 8%; left: 5%; }
      .hx-card.trail { bottom: 7%; right: 5%; }

      /* Below this width the plate fills the frame and the shot is recropped,
         so the three links no longer land on the objects they were measured
         against. The hub and the badge carry the offer on their own. */
      .g5-net {
        display: none;
      }

      /* One message on a small photograph. At this size the frame is barely
         340px wide and the two rotating cards, the hub and the badge simply
         cannot share it — everything lands on everything. The rail still
         drives the line under the headline, so it keeps its job; what it
         loses is its overlay, and the 5G system gets the shot to itself. */
      /* The lead card is the offer now, so it stays. Only the trail card
         steps aside, and the hub drops to the corner it frees rather than
         sitting on the card or on the agent's face. */
      .hx-frame.is-5g .hx-scene .hx-card.trail {
        display: none;
      }

      .g5-hub {
        left: 76%;
        top: 72%;
        width: 20%;
      }
    }

    @media (max-width:560px) {
      .hx-card-in {
        padding: 10px 13px;
        border-radius: 13px;
      }

      .hx-card .v { font-size: 13px; }
      .hx-card .s { font-size: 11px; }
      .hx-card .k { font-size: 9.5px; }

      .hx-faces img { width: 28px; height: 28px; }

      .hx-pillars button {
        grid-template-columns: 26px minmax(0, 1fr) 16px;
        gap: 10px;
        padding: 11px 2px;
      }
    }

    /* pill filter tabs (Ooma signature) */
    .hero-tabs {
      display: flex;
      gap: 10px;
      justify-content: center;
      flex-wrap: wrap;
      margin: 0 0 34px;
    }

    .hero-tabs a {
      display: inline-flex;
      align-items: center;
      text-decoration: none;
      font-size: 12.5px;
      font-weight: 700;
      letter-spacing: .06em;
      text-transform: uppercase;
      color: var(--ink-soft);
      background: var(--surface);
      border: 1px solid var(--line);
      padding: 11px 20px;
      border-radius: 40px;
      transition: border-color .16s, color .16s, transform .16s, box-shadow .16s;
    }

    .hero-tabs a:hover {
      color: var(--blue);
      border-color: var(--blue);
      transform: translateY(-2px);
      box-shadow: var(--shadow-sm);
    }

    .hero .actions {
      display: flex;
      gap: 14px;
      flex-wrap: wrap;
      justify-content: center;
      margin-bottom: 8px;
    }

    .hero .btn-ghost {
      color: var(--ink);
      border-color: var(--line);
      background: var(--surface);
    }

    .hero .btn-ghost:hover {
      background: var(--surface-2);
      border-color: var(--ink-faint);
    }

    /* twin photo cards under the hero (Ooma signature) */
    .twin-wrap {
      padding-top: 44px;
      padding-bottom: 0;
    }

    .twin {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0;
      border-radius: 14px;
      overflow: hidden;
      box-shadow: var(--shadow-md);
    }

    @media (max-width:760px) {
      .twin {
        grid-template-columns: 1fr;
      }
    }

    .twincard {
      display: flex;
      flex-direction: column;
      text-decoration: none;
      background: var(--surface);
      transition: transform .25s cubic-bezier(.22, .61, .36, 1);
    }

    .twincard:hover {
      transform: translateY(-4px);
    }

    .tw-photo {
      height: 230px;
      display: grid;
      place-items: center;
      position: relative;
      overflow: hidden;
    }

    .tw-biz .tw-photo {
      background: linear-gradient(150deg, #c9453a, #a5342b);
    }

    .tw-res .tw-photo {
      background: linear-gradient(150deg, #4b7f9e, #33607a);
    }

    .tw-photo svg {
      width: 82px;
      height: 82px;
      color: rgba(255, 255, 255, .92);
      transition: transform .35s cubic-bezier(.22, .61, .36, 1);
    }

    .twincard:hover .tw-photo svg {
      transform: scale(1.08);
    }

    .tw-body {
      padding: 26px 30px 30px;
      text-align: center;
    }

    .tw-body h3 {
      font-family: var(--serif);
      font-size: 24px;
      font-weight: 600;
      margin: 0 0 8px;
      color: var(--ink);
    }

    .tw-body p {
      font-size: 14.5px;
      color: var(--ink-soft);
      margin: 0 0 12px;
      max-width: 40ch;
      margin-left: auto;
      margin-right: auto;
    }

    .tw-go {
      font-size: 13.5px;
      font-weight: 750;
      color: var(--blue);
    }

    .tw-res .tw-go {
      color: var(--magenta-ink);
    }

    /* ===== Ooma-style colored promo band ===== */

    .btn-primary {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      background: var(--magenta);
      color: #fff;
      text-decoration: none;
      font-weight: 700;
      padding: 5px 16px;
      border-radius: 44px;
      font-size: 14.5px;
      box-shadow: 0 12px 30px -8px rgba(235, 0, 139, .7);
      transition: transform .12s, background .12s;
    }

    .btn-primary:hover {
      transform: translateY(-2px);
      background: var(--magenta-deep);
    }

    .btn-ghost {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      color: #fff;
      text-decoration: none;
      font-weight: 600;
      padding: 5px 16px;
      border-radius: 44px;
      font-size: 14.5px;
      border: 1.5px solid rgba(255, 255, 255, .35);
      transition: background .12s, border-color .12s;
    }

    .btn-ghost:hover {
      background: rgba(255, 255, 255, .1);
      border-color: #fff;
    }

    /* "View product" button (variation C style) for phone + hardware cards */
    .viewbtn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 7px;
      background: var(--blue);
      color: #fff;
      text-decoration: none;
      font-weight: 700;
      font-size: 13px;
      letter-spacing: .01em;
      padding: 9px 18px;
      border-radius: 10px;
      box-shadow: 0 8px 20px -8px var(--blue);
      transition: transform .12s, background .12s, box-shadow .12s;
      border-bottom: 0;
    }

    .viewbtn:hover {
      transform: translateY(-2px);
      background: var(--blue-deep);
      box-shadow: 0 12px 26px -8px var(--blue);
    }

    .prod .links a.viewbtn {
      color: #fff;
      text-decoration: none;
    }

    .prod .links a.viewbtn:hover {
      color: #fff;
      text-decoration: none;
    }

    .btn-primary svg,
    .btn-ghost svg {
      width: 17px;
      height: 17px;
    }

    /* hero visual: speech bubble motif */
    .hero-art {
      position: relative;
      display: grid;
      place-items: center;
      min-height: 300px;
    }

    .hero-art .bubbles {
      width: min(360px, 80%);
      filter: drop-shadow(0 20px 40px rgba(0, 0, 0, .35));
    }

    .hero-art .ring {
      position: absolute;
      border: 1.5px solid rgba(255, 255, 255, .16);
      border-radius: 50%;
    }

    .hero-art .r1 {
      width: 340px;
      height: 340px;
      animation: spin 40s linear infinite;
    }

    .hero-art .r2 {
      width: 440px;
      height: 440px;
      border-style: dashed;
      animation: spin 60s linear infinite reverse;
    }

    @keyframes spin {
      to {
        transform: rotate(360deg);
      }
    }

    @media (prefers-reduced-motion:reduce) {
      .hero-art .ring {
        animation: none;
      }
    }

    @media (max-width:880px) {
      .hero .wrap {
        grid-template-columns: 1fr;
        padding: 56px 26px 60px;
      }

      .hero-art {
        order: -1;
        min-height: 220px;
      }

      .hero-art .bubbles {
        width: 190px;
      }

      .hero-art .r1 {
        width: 240px;
        height: 240px;
      }

      .hero-art .r2 {
        width: 310px;
        height: 310px;
      }
    }

    /* trust strip */
    .trust {
      background: var(--surface);
      border-bottom: 1px solid var(--line);
    }

    .trust .wrap {
      display: flex;
      align-items: center;
      gap: 14px 40px;
      flex-wrap: wrap;
      padding: 20px 26px;
    }

    .trust .lbl {
      font-size: 12px;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--ink-faint);
      font-weight: 700;
    }

    .trust .carriers {
      display: flex;
      gap: 26px;
      align-items: center;
      flex-wrap: wrap;
      margin-left: auto;
    }

    .trust .carriers b {
      font-size: 19px;
      font-weight: 800;
      color: var(--ink-soft);
      letter-spacing: -.02em;
    }

    .trust .carriers b.att {
      color: #00a8e0;
    }

    .trust .carriers b.vz {
      color: #ee0000;
    }

    .trust .carriers b.tm {
      color: #e20074;
    }

    @media (prefers-color-scheme:dark) {
      .trust .carriers b.att {
        color: #4fc3ee;
      }

      .trust .carriers b.vz {
        color: #ff5b5b;
      }

      .trust .carriers b.tm {
        color: #ff4fab;
      }
    }

    /* ============ generic section ============ */
    .band {
      padding: 94px 0;
    }

    .band.alt {
      background: var(--surface);
    }

    .sec-eyebrow {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      font-size: 22px;
      letter-spacing: .11em;
      text-transform: uppercase;
      font-weight: 800;
      color: var(--magenta-ink);
      margin: 0 0 16px;
      background: color-mix(in srgb, var(--magenta) 12%, transparent);
      padding: 6px 14px 6px 12px;
      border-radius: 30px;
    }

    .sec-eyebrow::before {
      content: "";
      width: 7px;
      height: 7px;
      background: var(--magenta);
      border-radius: 50%;
      box-shadow: 0 0 0 3px color-mix(in srgb, var(--magenta) 22%, transparent);
    }

    .band h2 {
      font-size: clamp(28px, 3.6vw, 40px);
      margin: 0 0 16px;
      font-weight: 800;
      color: var(--ink);
    }

    .band h2 em {
      color: var(--magenta-ink);
      font-style: italic;
    }

    .band .intro {
      font-size: 17px;
      color: var(--ink-soft);
      max-width: 60ch;
      margin: 0 0 40px;
    }

    .center {
      text-align: center;
    }

    .center .sec-eyebrow {
      justify-content: center;
    }

    .center .sec-eyebrow::before {
      display: none;
    }

    .center .intro {
      margin-left: auto;
      margin-right: auto;
    }

    /* ===== WHY HBE — everything you need, one provider (variation C content, Ooma coloring) ===== */
    .f3 {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 22px;
      max-width: 1080px;
      margin: 0 auto 32px;
    }

    @media (max-width:820px) {
      .f3 {
        grid-template-columns: 1fr;
      }
    }

    .fc {
      background: var(--bg);
      border: 1px solid var(--line);
      border-radius: 16px;
      padding: 18px 20px;
      box-shadow: var(--shadow-sm);
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      column-gap: 13px;
      align-items: center;
    }

    .fc .ic {
      width: 38px;
      height: 38px;
      border-radius: 11px;
      display: grid;
      place-items: center;
      background: color-mix(in srgb, var(--blue) 12%, var(--surface));
      color: var(--blue);
      margin-bottom: 0;
      grid-column: 1;
      grid-row: 1;
    }

    .fc .ic svg {
      width: 26px;
      height: 26px;
    }

    .fc h3 {
      margin: 0;
      font-size: 17.2px;
      letter-spacing: -.01em;
      color: var(--ink);
      grid-column: 2;
      grid-row: 1;
    }

    .fc p {
      margin: 7px 0 0;
      color: var(--ink-soft);
      font-size: 14.5px;
      line-height: 1.6;
      grid-column: 2;
      grid-row: 2;
    }

    .provstats {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 18px;
      max-width: 1080px;
      margin: 0 auto;
    }

    @media (max-width:820px) {
      .provstats {
        grid-template-columns: 1fr 1fr;
      }
    }

    .provstats .st {
      text-align: center;
      padding: 24px 12px;
      border: 1px solid var(--line);
      border-radius: 14px;
      background: var(--bg);
    }

    .provstats .st b {
      display: block;
      font-size: 30px;
      font-weight: 700;
      color: var(--magenta-ink);
      letter-spacing: -.02em;
      font-family: var(--serif);
      line-height: 1;
    }

    .provstats .st span {
      display: block;
      margin-top: 8px;
      font-size: 12.5px;
      color: var(--ink-faint);
      letter-spacing: .02em;
    }

    /* ===== SOLUTIONS 2×2 (Ooma-style) ===== */
    .solgrid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 24px;
    }

    @media (max-width:760px) {
      .solgrid {
        grid-template-columns: 1fr;
      }
    }

    .solcard {
      display: flex;
      gap: 22px;
      align-items: flex-start;
      text-decoration: none;
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 16px;
      padding: 30px 30px;
      box-shadow: var(--shadow-sm);
      position: relative;
      overflow: hidden;
      transition: transform .22s cubic-bezier(.22, .61, .36, 1), box-shadow .22s, border-color .22s;
    }

    .solgrid-band {
      background: var(--surface);
    }

    .solgrid-band .solcard {
      background: var(--bg);
    }

    .solcard::before {
      content: "";
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      width: 4px;
      background: var(--blue);
      opacity: 0;
      transition: opacity .2s;
    }

    .solcard:hover {
      transform: translateY(-5px);
      box-shadow: var(--shadow-md);
      border-color: color-mix(in srgb, var(--blue) 35%, var(--line));
    }

    .solcard:hover::before {
      opacity: 1;
    }

    .sc-res::before {
      background: var(--magenta);
    }

    .sc-5g::before {
      background: var(--blue);
    }

    .sc-net::before {
      background: var(--ink-soft);
    }

    .sc-icon {
      flex: none;
      width: 56px;
      height: 56px;
      border-radius: 14px;
      display: grid;
      place-items: center;
      background: color-mix(in srgb, var(--blue) 12%, transparent);
      color: var(--blue);
    }

    .sc-icon svg {
      width: 28px;
      height: 28px;
    }

    .sc-res .sc-icon {
      background: color-mix(in srgb, var(--magenta) 12%, transparent);
      color: var(--magenta-ink);
    }

    .sc-body {
      flex: 1;
    }

    .sc-k {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      font-size: 12px;
      font-weight: 800;
      letter-spacing: .06em;
      text-transform: uppercase;
      color: var(--blue);
    }

    .sc-res .sc-k {
      color: var(--magenta-ink);
    }

    .sc-new {
      font-style: normal;
      font-size: 9px;
      color: #fff;
      background: var(--magenta);
      padding: 2px 6px;
      border-radius: 20px;
      letter-spacing: .04em;
    }

    .sc-body h3 {
      font-size: 19px;
      margin: 8px 0 8px;
      color: var(--ink);
      font-weight: 750;
    }

    .sc-body p {
      font-size: 14.5px;
      color: var(--ink-soft);
      margin: 0 0 14px;
    }

    .sc-go {
      font-size: 14px;
      font-weight: 750;
      color: var(--blue);
      transition: letter-spacing .15s;
    }

    .sc-res .sc-go {
      color: var(--magenta-ink);
    }

    .solcard:hover .sc-go {
      letter-spacing: .02em;
    }

    /* ===== TESTIMONIALS ===== */
    /* Ooma layout: heading column left, review cards right */

    /* ===== PAIN → SOLUTION transformation ledger ===== */
    .switch {
      position: relative;
      overflow: hidden;
    }

    /* attention-grabbing tinted glow behind the section */
    .switch::before {
      content: "";
      position: absolute;
      top: -120px;
      left: 50%;
      transform: translateX(-50%);
      width: 680px;
      height: 340px;
      border-radius: 50%;
      pointer-events: none;
      z-index: 0;
      background: radial-gradient(closest-side, color-mix(in srgb, var(--magenta) 22%, transparent), transparent 72%);
      opacity: .5;
    }

    .switch .wrap {
      position: relative;
      z-index: 1;
    }

    .switch-head {
      text-align: center;
      margin-bottom: 34px;
    }

    .switch-head .sec-eyebrow {
      justify-content: center;
    }

    .switch-head .sec-eyebrow::before {
      display: none;
    }

    .switch-title {
      font-size: clamp(26px, 3vw, 36px);
      margin: 0 auto 12px;
      font-weight: 800;
      letter-spacing: -.02em;
    }

    /* "Your pain points" is the focal phrase — highlighted */
    .switch-title .focus {
      position: relative;
      color: var(--magenta-ink);
      white-space: nowrap;
    }

    .switch-title .focus::after {
      content: "";
      position: absolute;
      left: -4px;
      right: -4px;
      bottom: 2px;
      height: 38%;
      z-index: -1;
      background: color-mix(in srgb, var(--magenta) 22%, transparent);
      border-radius: 4px;
    }

    .switch-sub {
      font-size: clamp(15px, 1.7vw, 18px);
      color: var(--ink-soft);
      margin: 0 auto 22px;
      max-width: 52ch;
      font-weight: 500;
    }

    .switch-sub em {
      color: var(--magenta-ink);
      font-style: italic;
      font-weight: 700;
    }

    .switch-sub .muted {
      color: var(--ink-faint);
    }

    .switch-legend {
      display: inline-flex;
      align-items: center;
      gap: 14px;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: .06em;
      text-transform: uppercase;
    }

    .switch-legend .lg {
      padding: 6px 14px;
      border-radius: 30px;
    }

    .switch-legend .lg-pain {
      background: color-mix(in srgb, var(--warn) 14%, transparent);
      color: var(--warn);
    }

    .switch-legend .lg-sol {
      background: color-mix(in srgb, var(--good) 15%, transparent);
      color: var(--good);
      text-transform: none;
      letter-spacing: 0;
    }

    .switch-legend .lg-sol .brandface {
      color: var(--good);
    }

    .switch-legend .lg-arrow {
      width: 38px;
      color: var(--magenta);
    }

    .ledger {
      max-width: 920px;
      margin: 0 auto;
      display: flex;
      flex-direction: column;
      gap: 14px;
    }

    .trade {
      display: grid;
      grid-template-columns: 1fr 54px 1fr;
      align-items: stretch;
      gap: 0;
      border: 1px solid var(--line);
      border-radius: 16px;
      overflow: hidden;
      background: var(--surface);
      box-shadow: var(--shadow-sm);
      transition: transform .22s cubic-bezier(.22, .61, .36, 1), box-shadow .22s;
    }

    .band.alt .trade {
      background: var(--bg);
    }

    .trade:hover {
      transform: translateY(-3px);
      box-shadow: var(--shadow-md);
    }

    .trade .from,
    .trade .to {
      display: flex;
      align-items: center;
      gap: 13px;
      padding: 18px 22px;
      font-size: 15.5px;
    }

    .trade .from {
      background: color-mix(in srgb, var(--warn) 5%, transparent);
      color: var(--ink-faint);
    }

    .trade .from span {
      text-decoration: line-through;
      text-decoration-color: color-mix(in srgb, var(--warn) 55%, transparent);
      text-decoration-thickness: 1.5px;
    }

    .trade .from b {
      color: var(--warn-ink);
      font-weight: 600;
    }

    .trade .from svg {
      width: 20px;
      height: 20px;
      color: var(--warn);
      flex: none;
      opacity: .85;
    }

    .trade .to {
      color: var(--ink);
      font-weight: 500;
    }

    .trade .to b {
      color: var(--good-ink);
      font-weight: 750;
    }

    .trade .to svg {
      width: 20px;
      height: 20px;
      color: var(--good);
      flex: none;
    }

    .trade .pivot {
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--hero-grad);
    }

    .trade .pivot svg {
      width: 22px;
      height: 22px;
      color: #fff;
      transition: transform .25s;
    }

    .trade:hover .pivot svg {
      transform: translateX(3px);
    }

    .switch-foot {
      max-width: 920px;
      margin: 26px auto 0;
      display: flex;
      align-items: center;
      gap: 16px;
      padding: 18px 24px;
      border-radius: 16px;
      background: var(--surface-2);
      border: 1px dashed var(--line);
    }

    .switch-foot svg {
      flex: none;
    }

    .switch-foot span {
      font-size: 15px;
      color: var(--ink-soft);
    }

    .switch-foot b {
      color: var(--ink);
      font-weight: 750;
    }

    @media (max-width:720px) {
      .trade {
        grid-template-columns: 1fr;
      }

      .trade .pivot {
        padding: 8px 0;
      }

      .trade .pivot svg {
        transform: rotate(90deg);
      }

      .trade:hover .pivot svg {
        transform: rotate(90deg) translateX(3px);
      }

      .trade .from span {
        text-decoration-color: color-mix(in srgb, var(--warn) 55%, transparent);
      }

      .switch-foot {
        flex-direction: column;
        text-align: center;
        gap: 10px;
      }
    }

    /* ===== design-option label (comparison scaffolding) ===== */
    .opt-label {
      display: inline-flex;
      align-items: center;
      gap: 10px;
      font-size: 13px;
      color: var(--ink-faint);
      font-weight: 600;
      margin: 0 auto 18px;
      padding: 7px 16px;
      border: 1px dashed var(--line);
      border-radius: 30px;
      background: var(--surface);
    }

    .opt-label span {
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .06em;
      text-transform: uppercase;
      color: #fff;
      background: var(--blue);
      padding: 3px 9px;
      border-radius: 20px;
    }

    .optvar {
      text-align: center;
    }

    .optvar .switch-head {
      margin-bottom: 30px;
    }

    .optvar .ledger,
    .optvar .flipgrid,
    .optvar .splitpanel {
      text-align: left;
    }

    /* ===== PAIN POINTS — folded-corner flip cards (flip on hover; tap on touch) ===== */
    .flipgrid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 20px;
      max-width: 1080px;
      margin: 0 auto;
    }

    @media (max-width:900px) {
      .flipgrid {
        grid-template-columns: 1fr 1fr;
      }
    }

    @media (max-width:520px) {
      .flipgrid {
        grid-template-columns: 1fr;
      }
    }

    .flip {
      perspective: 1400px;
      cursor: pointer;
    }

    .flip-in {
      position: relative;
      display: grid;
      transition: transform .62s cubic-bezier(.3, .7, .3, 1);
      transform-style: preserve-3d;
    }

    .flip.flipped .flip-in {
      transform: rotateY(180deg);
    }

    @media (hover:hover) and (pointer:fine) {

      .flip:hover .flip-in,
      .flip:focus-visible .flip-in {
        transform: rotateY(180deg);
      }
    }

    .flip-front,
    .flip-back {
      grid-area: 1/1;
      backface-visibility: hidden;
      -webkit-backface-visibility: hidden;
      border-radius: 16px;
      padding: 20px 22px;
      min-height: 150px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;
      gap: 8px;
      box-shadow: var(--shadow-sm);
      overflow: hidden;
    }

    .flip-front svg,
    .flip-back svg {
      width: 30px;
      height: 30px;
    }

    .flip-front b,
    .flip-back b {
      font-size: 17px;
      line-height: 1.25;
    }

    .flip-front span,
    .flip-back span {
      font-size: 13.5px;
    }

    /* front = mid blush rose (same gradient on all four cards) */
    .flip-front {
      background: linear-gradient(150deg, #fef2f8 0%, #f9d3e6 34%, #f0b0cf 68%, #e58ab6 100%);
      border: 1px solid #e187b3;
      color: #7a4a3d;
    }

    .flip-front svg {
      color: #c0563a;
    }

    .flip-front b {
      color: #a23c22;
    }

    .flip-front span {
      opacity: .86;
    }

    @media (prefers-color-scheme:dark) {
      .flip-front {
        background: linear-gradient(150deg, #3b2430 0%, #341f2a 55%, #2c1a24 100%);
        border-color: #54313f;
        color: #e7c3b8;
      }

      .flip-front b {
        color: #f0a68c;
      }

      .flip-front svg {
        color: #e0805f;
      }
    }

    :root[data-theme="dark"] .flip-front {
      background: linear-gradient(150deg, #3b2430 0%, #341f2a 55%, #2c1a24 100%);
      border-color: #54313f;
      color: #e7c3b8;
    }

    :root[data-theme="dark"] .flip-front b {
      color: #f0a68c;
    }

    :root[data-theme="dark"] .flip-front svg {
      color: #e0805f;
    }

    /* magenta folded corner — signals "more on the back" */
    .flip-front .fold {
      position: absolute;
      top: 0;
      right: 0;
      width: 0;
      height: 0;
      border-left: 42px solid transparent;
      border-top: 42px solid var(--magenta-deep);
      filter: drop-shadow(-2px 2px 2px rgba(0, 0, 0, .14));
    }

    .flip-front .fold::after {
      content: "⤶";
      position: absolute;
      top: -39px;
      right: 3px;
      color: #fff;
      font-size: 16px;
      font-weight: 900;
      line-height: 1;
    }

    /* back = blue gradient */
    .flip-back {
      transform: rotateY(180deg);
      background: var(--hero-grad);
      color: #eaf6ff;
      border: 1px solid transparent;
    }

    .flip-back svg {
      color: #8fe0ff;
    }

    .flip-back b {
      color: #fff;
    }

    .flip-back span {
      color: #cfe6f4;
    }

    @media (prefers-reduced-motion:reduce) {
      .flip-in {
        transition: none;
      }

      .flip {
        min-height: auto;
      }

      .flip-in {
        min-height: auto;
      }

      .flip-front,
      .flip-back {
        grid-area: auto;
        backface-visibility: visible;
        transform: none;
      }

      .flip-back {
        margin-top: 12px;
      }
    }

    /* ===== OPTION C — split panel ===== */
    .splitpanel {
      display: grid;
      grid-template-columns: 1fr 64px 1fr;
      align-items: stretch;
      max-width: 960px;
      margin: 0 auto;
      border-radius: 20px;
      overflow: hidden;
      box-shadow: var(--shadow-md);
      border: 1px solid var(--line);
    }

    .sp-pain,
    .sp-sol {
      padding: 34px 32px;
    }

    .sp-pain {
      background: linear-gradient(160deg, #26333c, #1a252d);
      color: #c6d2da;
    }

    :root[data-theme="light"] .sp-pain {
      background: linear-gradient(160deg, #2b3941, #1c272f);
    }

    .sp-sol {
      background: var(--hero-grad);
      color: #eaf6ff;
    }

    .sp-tag {
      font-size: 12px;
      font-weight: 800;
      letter-spacing: .1em;
      text-transform: uppercase;
      margin: 0 0 18px;
    }

    .sp-pain .sp-tag {
      color: #ff9d78;
    }

    .sp-sol .sp-tag {
      color: #8fe0ff;
      text-transform: none;
      letter-spacing: 0;
      font-size: 14px;
    }

    .sp-sol .sp-tag .brandface {
      color: #fff;
    }

    .splitpanel ul {
      list-style: none;
      margin: 0;
      padding: 0;
    }

    .splitpanel li {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 13px 0;
      border-bottom: 1px solid rgba(255, 255, 255, .1);
      font-size: 15.5px;
    }

    .splitpanel li:last-child {
      border-bottom: 0;
    }

    .splitpanel li svg {
      width: 20px;
      height: 20px;
      flex: none;
    }

    .sp-pain li {
      color: #aab8c1;
    }

    .sp-pain li svg {
      color: #ff9d78;
    }

    .sp-sol li {
      color: #fff;
      font-weight: 500;
    }

    .sp-sol li svg {
      color: #8fe0ff;
    }

    .sp-mid {
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--magenta);
    }

    .sp-mid svg {
      width: 26px;
      height: 26px;
      color: #fff;
    }

    @media (max-width:720px) {
      .splitpanel {
        grid-template-columns: 1fr;
      }

      .sp-mid {
        padding: 10px 0;
      }

      .sp-mid svg {
        transform: rotate(90deg);
      }
    }

    /* business / residential split */

    /* ===== SOFT PHONE — two alternating blocks (variation C style) ===== */
    .soft2 .s2row {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 48px;
      align-items: center;
      margin-bottom: 56px;
    }

    .soft2 .s2row:last-child {
      margin-bottom: 0;
    }

    .soft2 .s2row.rev .s2txt {
      order: 2;
    }

    @media (max-width:820px) {
      .soft2 .s2row {
        grid-template-columns: 1fr;
        gap: 26px;
      }

      .soft2 .s2row.rev .s2txt {
        order: 0;
      }
    }

    .s2k {
      display: inline-block;
      font-size: 21px;
      font-weight: 800;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--magenta-ink);
      margin-bottom: 12px;
    }

    .soft2 .s2txt h3 {
      font-size: clamp(22px, 2.4vw, 28px);
      margin: 0 0 12px;
      letter-spacing: -.02em;
      color: var(--ink);
    }

    .soft2 .s2txt>p {
      color: var(--ink-soft);
      font-size: 19px;
      margin: 0 0 18px;
      line-height: 1.6;
    }

    .s2list {
      list-style: none;
      padding: 0;
      margin: 0 0 22px;
      display: flex;
      flex-direction: column;
      gap: 11px;
    }

    .s2list li {
      position: relative;
      padding-left: 30px;
      font-size: 14.5px;
      color: var(--ink);
    }

    .s2list li::before {
      content: "";
      position: absolute;
      left: 0;
      top: 1px;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: color-mix(in srgb, var(--good) 20%, transparent);
    }

    .s2list li::after {
      content: "";
      position: absolute;
      left: 6px;
      top: 7px;
      width: 8px;
      height: 5px;
      border-left: 2px solid var(--good-ink);
      border-bottom: 2px solid var(--good-ink);
      transform: rotate(-45deg);
    }

    .s2media {
      margin: 0;
      border-radius: 18px;
      overflow: hidden;
      box-shadow: var(--shadow-md);
      background: var(--surface-2);
      min-height: 280px;
    }

    .s2media img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    /* feature rows (softphone / mobile) */
    .frow {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 48px;
      align-items: center;
    }

    .frow+.frow {
      margin-top: 64px;
    }

    .frow.rev .txt {
      order: 2;
    }

    .frow .txt h3 {
      font-size: 24px;
      margin: 0 0 14px;
      font-weight: 800;
      color: var(--blue);
    }

    .frow .feat {
      list-style: none;
      margin: 0;
      padding: 0;
    }

    .frow .feat li {
      position: relative;
      padding: 9px 0 9px 30px;
      font-size: 15.5px;
      color: var(--ink-soft);
    }

    .frow .feat li svg {
      position: absolute;
      left: 0;
      top: 11px;
      width: 19px;
      height: 19px;
      color: var(--magenta);
    }

    .device {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 20px;
      box-shadow: var(--shadow-md);
      padding: 22px;
      position: relative;
      overflow: hidden;
    }

    .band.alt .device {
      background: var(--bg);
    }

    .device .chip {
      position: absolute;
      top: 16px;
      right: 16px;
      z-index: 2;
      font-size: 11px;
      font-weight: 700;
      letter-spacing: .08em;
      text-transform: uppercase;
      color: var(--blue);
      background: color-mix(in srgb, var(--blue) 14%, var(--surface));
      padding: 4px 10px;
      border-radius: 20px;
      box-shadow: var(--shadow-sm);
    }

    /* real screenshot devices */
    .device.shot {
      padding: 14px;
      display: flex;
    }

    .device.shot img {
      width: 100%;
      height: auto;
      border-radius: 12px;
      display: block;
      box-shadow: 0 8px 24px rgba(15, 45, 65, .14);
    }

    .device.mobileshot {
      background: linear-gradient(160deg, color-mix(in srgb, var(--blue) 10%, var(--surface)), var(--surface));
      justify-content: center;
    }

    .device.mobileshot img {
      max-width: 320px;
      box-shadow: none;
    }

    /* ===== MOBILE — composed bento ===== */
    .mobile {
      background: var(--hero-grad);
      color: #eef7fd;
      padding: 84px 0;
    }

    .mobile-head {
      max-width: 64ch;
      margin: 0 0 44px;
    }

    .mobile-head h2 {
      font-size: clamp(28px, 3.6vw, 42px);
      margin: 0 0 14px;
      font-weight: 800;
      color: #fff;
    }

    .mobile-head h2 em {
      color: #ff5cae;
      font-style: italic;
    }

    .bento {
      display: grid;
      grid-template-columns: 1.5fr 1fr;
      grid-template-rows: auto auto;
      gap: 22px;
    }

    .cell {
      position: relative;
      border-radius: 20px;
      overflow: hidden;
      background: rgba(255, 255, 255, .06);
      border: 1px solid rgba(255, 255, 255, .12);
    }

    /* hero cell: image with gradient scrim + overlaid copy */
    .cell-hero {
      grid-row: span 2;
      display: flex;
      align-items: flex-end;
      min-height: 420px;
    }

    .cell-hero img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: center top;
      transition: transform .8s cubic-bezier(.22, .61, .36, 1);
    }

    .cell-hero:hover img {
      transform: scale(1.05);
    }

    .cell-hero::after {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(180deg, rgba(7, 41, 60, .05) 30%, rgba(7, 41, 60, .92) 92%);
    }

    .cell-hero-body {
      position: relative;
      z-index: 1;
      padding: 32px;
    }

    .cell-hero-body h3 {
      font-size: 26px;
      margin: 8px 0 10px;
      color: #fff;
      font-weight: 800;
    }

    .cell-hero-body p {
      margin: 0;
      color: #dbeefb;
      font-size: 15.5px;
      max-width: 44ch;
    }

    .tagnum {
      display: inline-block;
      font-size: 11px;
      font-weight: 700;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: #0a3d5a;
      background: #8fe0ff;
      padding: 4px 12px;
      border-radius: 20px;
    }

    /* device cell */
    .cell-device {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 24px;
      background: linear-gradient(150deg, rgba(143, 224, 255, .16), rgba(235, 0, 139, .14));
      min-height: 200px;
    }

    .cell-device img {
      max-width: 170px;
      height: auto;
      border-radius: 14px;
      filter: drop-shadow(0 16px 34px rgba(0, 0, 0, .4));
      transform: rotate(-3deg);
      transition: transform .3s;
    }

    .cell-device:hover img {
      transform: rotate(0);
    }

    .cell-device .chip {
      position: absolute;
      top: 16px;
      left: 16px;
      z-index: 2;
      background: #fff;
      color: var(--blue);
      box-shadow: var(--shadow-sm);
    }

    /* specs cell */
    .cell-specs {
      display: flex;
      flex-direction: column;
      justify-content: center;
      gap: 0;
      padding: 6px 26px;
    }

    .cell-specs .spec {
      padding: 16px 0;
      border-bottom: 1px solid rgba(255, 255, 255, .14);
    }

    .cell-specs .spec:last-child {
      border-bottom: 0;
    }

    .cell-specs .k {
      font-size: 11px;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: #8fe0ff;
      font-weight: 700;
    }

    .cell-specs .spec b {
      display: block;
      font-size: 19px;
      color: #fff;
      margin: 3px 0 2px;
    }

    .cell-specs .spec small {
      color: #b9d4e6;
      font-size: 13px;
    }

    /* team cell — wide closing strip */
    .cell-team {
      grid-column: 1 / -1;
      display: grid;
      grid-template-columns: .85fr 1.15fr;
      align-items: stretch;
      min-height: 300px;
    }

    .cell-team {
      overflow: hidden;
    }

    .cell-team img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      object-position: center top;
      transition: transform .8s cubic-bezier(.22, .61, .36, 1);
    }

    .cell-team:hover img {
      transform: scale(1.05);
    }

    .cell-team-body {
      padding: 38px 40px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      gap: 14px;
    }

    .cell-team-body h3 {
      font-size: 26px;
      margin: 0;
      color: #fff;
      font-weight: 800;
    }

    .cell-team-body h3 em {
      color: #ff5cae;
      font-style: italic;
    }

    .cell-team-body p {
      margin: 0;
      color: #cfe6f4;
      font-size: 15.5px;
      max-width: 52ch;
    }

    .cell-team-body .btn-ghost {
      align-self: flex-start;
      margin-top: 6px;
    }

    @media (max-width:860px) {
      .bento {
        grid-template-columns: 1fr;
      }

      .cell-hero {
        grid-row: auto;
        min-height: 360px;
      }

      .cell-team {
        grid-column: auto;
        grid-template-columns: 1fr;
      }

      .cell-team img {
        max-height: 240px;
      }
    }

    /* ===== SOFTPHONE / DESKTOP — composed showcase ===== */
    .soft-head {
      display: grid;
      grid-template-columns: 1.3fr 1fr;
      gap: 36px;
      align-items: end;
      margin-bottom: 30px;
    }

    .soft-head h2 {
      font-size: clamp(26px, 3.4vw, 38px);
      margin: 0;
      font-weight: 800;
    }

    @media (max-width:820px) {
      .soft-head {
        grid-template-columns: 1fr;
        gap: 14px;
      }
    }

    .soft-banner {
      margin: 0 0 26px;
      border-radius: 18px;
      overflow: hidden;
      box-shadow: var(--shadow-md);
      line-height: 0;
    }

    .soft-banner img {
      width: 100%;
      height: auto;
      display: block;
    }

    .soft-stage {
      display: grid;
      grid-template-columns: 1.55fr 1fr;
      gap: 26px;
      align-items: stretch;
    }

    .soft-screen {
      position: relative;
      background: var(--surface-2);
      border: 1px solid var(--line);
      border-radius: 18px;
      padding: 20px;
      box-shadow: var(--shadow-sm);
    }

    .soft-screen>img {
      width: 100%;
      height: auto;
      border-radius: 12px;
      display: block;
      box-shadow: 0 10px 30px rgba(15, 45, 65, .16);
    }

    .soft-screen .chip {
      position: absolute;
      top: 14px;
      left: 14px;
      z-index: 3;
      background: #fff;
      color: var(--blue);
      box-shadow: var(--shadow-sm);
    }

    .soft-inset {
      position: absolute;
      right: -14px;
      bottom: -18px;
      width: 46%;
      margin: 0;
      border-radius: 12px;
      overflow: hidden;
      border: 4px solid var(--surface);
      box-shadow: 0 14px 34px rgba(15, 45, 65, .28);
      line-height: 0;
    }

    .soft-inset img {
      width: 100%;
      height: auto;
      display: block;
    }

    .soft-rail {
      display: flex;
      flex-direction: column;
      gap: 14px;
      justify-content: center;
    }

    .statbox {
      background: var(--surface);
      border: 1px solid var(--line);
      border-left: 3px solid var(--magenta);
      border-radius: 12px;
      padding: 16px 18px;
      box-shadow: var(--shadow-sm);
      transition: transform .2s cubic-bezier(.22, .61, .36, 1), box-shadow .2s, border-left-width .2s;
    }

    .statbox:hover {
      transform: translateX(5px);
      box-shadow: var(--shadow-md);
      border-left-width: 6px;
    }

    .statbox b {
      display: block;
      font-size: 20px;
      color: var(--blue);
      font-weight: 800;
      letter-spacing: -.01em;
    }

    .statbox span {
      font-size: 14px;
      color: var(--ink-soft);
      display: block;
      margin-top: 3px;
    }

    .soft-rail .btn-primary {
      margin-top: 4px;
    }

    @media (max-width:820px) {
      .soft-stage {
        grid-template-columns: 1fr;
      }

      .soft-inset {
        width: 44%;
        right: 8px;
        bottom: -14px;
      }
    }

    /* softphone gallery strip */
    .spgallery {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 22px;
      margin-top: 52px;
    }

    .spgallery figure {
      margin: 0;
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: var(--r);
      overflow: hidden;
      box-shadow: var(--shadow-sm);
    }

    .band.alt .spgallery figure {
      background: var(--bg);
    }

    .spgallery img {
      width: 100%;
      height: auto;
      display: block;
    }

    .spgallery figcaption {
      padding: 12px 18px;
      font-size: 13.5px;
      color: var(--ink-soft);
      border-top: 1px solid var(--line-soft);
    }

    .spgallery figcaption b {
      color: var(--ink);
    }

    @media (max-width:720px) {
      .spgallery {
        grid-template-columns: 1fr;
      }
    }

    /* product real images */
    .prod .ph {
      padding: 18px;
    }

    .prod .ph img {
      max-width: 100%;
      max-height: 134px;
      width: auto;
      object-fit: contain;
      mix-blend-mode: multiply;
    }

    @media (prefers-color-scheme:dark) {
      .prod .ph img {
        mix-blend-mode: normal;
        border-radius: 8px;
      }

      .prod .ph {
        background: #fff;
      }
    }

    :root[data-theme="dark"] .prod .ph {
      background: #fff;
    }

    :root[data-theme="dark"] .prod .ph img {
      mix-blend-mode: normal;
    }

    :root[data-theme="light"] .prod .ph img {
      mix-blend-mode: multiply;
    }

    :root[data-theme="light"] .prod .ph {
      background: linear-gradient(135deg, #eef5fd, #dfeafb);
    }

    /* carrier strip image */
    .trust .carrier-img {
      height: 34px;
      width: auto;
      margin-left: auto;
      border-radius: 6px;
      background: #fff;
      padding: 3px 8px;
    }

    /* faux softphone UI */
    .sp {
      display: grid;
      grid-template-columns: 64px 1fr;
      gap: 0;
      border-radius: 14px;
      overflow: hidden;
      border: 1px solid var(--line);
      background: var(--surface);
    }

    .band.alt .sp {
      background: var(--bg);
    }

    .sp .rail {
      background: var(--hero-grad);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 16px;
      padding: 16px 0;
      color: rgba(255, 255, 255, .85);
    }

    .sp .rail svg {
      width: 20px;
      height: 20px;
    }

    .sp .rail .on {
      color: #fff;
    }

    .sp .body {
      padding: 16px 18px;
    }

    .sp .caller {
      display: flex;
      align-items: center;
      gap: 11px;
      margin-bottom: 14px;
    }

    .sp .av {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      background: linear-gradient(135deg, var(--magenta), var(--blue));
      display: grid;
      place-items: center;
      color: #fff;
      font-weight: 700;
      font-size: 15px;
    }

    .sp .caller b {
      display: block;
      font-size: 15px;
    }

    .sp .caller span {
      font-size: 12.5px;
      color: var(--ink-faint);
    }

    .sp .caller .live {
      margin-left: auto;
      font-size: 11px;
      font-weight: 700;
      color: var(--good);
      display: flex;
      align-items: center;
      gap: 5px;
    }

    .sp .caller .live::before {
      content: "";
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: var(--good);
      animation: pulse 1.6s infinite;
    }

    @keyframes pulse {

      0%,
      100% {
        opacity: 1;
      }

      50% {
        opacity: .3;
      }
    }

    @media (prefers-reduced-motion:reduce) {
      .sp .caller .live::before {
        animation: none;
      }
    }

    .keypad {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px;
      margin: 4px 0 14px;
    }

    .keypad div {
      background: var(--surface-2);
      border-radius: 9px;
      text-align: center;
      padding: 9px 0;
      font-weight: 600;
      font-size: 15px;
      color: var(--ink);
    }

    .keypad div small {
      display: block;
      font-size: 8px;
      color: var(--ink-faint);
      letter-spacing: .1em;
    }

    .callbar {
      display: flex;
      gap: 10px;
      justify-content: center;
    }

    .callbar .k {
      width: 44px;
      height: 44px;
      border-radius: 50%;
      display: grid;
      place-items: center;
    }

    .callbar .k svg {
      width: 19px;
      height: 19px;
      color: #fff;
    }

    .callbar .k.g {
      background: var(--good);
    }

    .callbar .k.r {
      background: #e0463a;
    }

    .callbar .k.n {
      background: var(--ink-faint);
    }

    @media (max-width:820px) {
      .frow {
        grid-template-columns: 1fr;
        gap: 28px;
      }

      .frow.rev .txt {
        order: 0;
      }
    }

    /* 5G carriers band */
    .fiveg {
      background: var(--hero-grad);
      color: #eef7fd;
      padding: 80px 0;
    }

    .fiveg .sec-eyebrow {
      color: #bdefff;
      background: rgba(143, 224, 255, .16);
    }

    .fiveg .sec-eyebrow::before {
      background: #8fe0ff;
      box-shadow: 0 0 0 3px rgba(143, 224, 255, .25);
    }

    .sec-eyebrow.eb-dark {
      color: #bdefff;
      background: rgba(143, 224, 255, .16);
    }

    .sec-eyebrow.eb-dark::before {
      background: #8fe0ff;
      box-shadow: 0 0 0 3px rgba(143, 224, 255, .25);
    }

    .fiveg h2 {
      color: #fff;
      font-size: 25px;
      letter-spacing: .18em;
    }

    .fiveg h2 em {
      color: #ff5cae;
    }

    .fiveg .intro {
      color: #cfe6f4;
      font-size: 19px;
    }

    .carrier-band {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 32px;
      flex-wrap: wrap;
      background: #fdf7e1;
      border-radius: 16px;
      padding: 20px 34px;
      margin: 0 auto 24px;
      max-width: 780px;
      box-shadow: 0 18px 40px rgba(0, 0, 0, .22);
    }

    .carrier-band .cb-label {
      flex: 0 1 auto;
      max-width: 430px;
      min-width: 0;
      margin: 0;
      text-align: left;
      text-wrap: balance;
      color: #0a3d5a;
    }

    .carrier-band .cb-lead {
      display: block;
      font-size: 22px;
      line-height: 1.28;
      font-weight: 800;
      letter-spacing: .005em;
    }

    .carrier-band .cb-sub {
      display: block;
      margin-top: 10px;
      padding-top: 10px;
      border-top: 1px solid rgba(10, 61, 90, .18);
      font-size: 16px;
      line-height: 1.45;
      font-weight: 600;
      color: #2d5f7c;
    }

    /* The three carrier credential marks, stacked. Order follows the copy:
       the two licensed partners, then T-Mobile, who is named but never called
       a partner. All three are set to the 40px the footer row uses, so the
       mark renders exactly as designed rather than at a second scale. */
    .carrier-band .cb-marks {
      display: flex;
      flex-direction: column;
      align-items: stretch;
      gap: 8px;
      flex: 0 0 auto;
    }

    /* ---------- carrier credential plate ----------
       The AT&T badge is a fixed raster — its frame, tile, padding and type are
       all baked in and cannot be restyled — so it sets the pattern and the
       other two are rebuilt to it. Measured off the artwork: a square brand
       tile occupying the left 26% of the plate, then three text rows in a
       small-lead / bold-name / fine-italic-qualifier hierarchy. The plate
       carries the badge's own 4:1 ratio, so AT&T fills it edge to edge with no
       letterboxing and no second frame drawn around a mark that has one.
       The lockup itself is unscoped: the 5G band and the footer carrier row
       both build their marks from it, so the two rows cannot drift apart. */
    .carrier-band .cb-marks {
      width: 160px;
    }

    .carrier-band .cb-mark {
      height: 40px;
    }

    .carrier-band .cb-mark img {
      display: block;
      width: 100%;
      height: 100%;
    }

    /* AT&T's frame lives in its raster; these two get the CSS equivalent —
       the badge's 8px-on-200px edge and 28px corner, scaled to this plate. */
    .cb-cred {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      align-items: stretch;
      width: 160px;
      height: 40px;
      background: #fff;
      border: 1.5px solid #e6e0d6;
      border-radius: 6px;
      overflow: hidden;
    }

    /* square-ish and 26% of the plate, the proportion the AT&T globe block
       occupies in its own artwork, so the three text columns start level */
    .cb-sig {
      display: grid;
      place-items: center;
      width: 41px;
      color: #fff;
    }

    /* the official glow V is red-on-transparent, so it cannot sit on the red
       tile the recreated white V used. It gets a warm off-white instead —
       light enough for the mark to read, but still a filled block with a hard
       edge against the text panel, which is the structure AT&T's own raster
       and the T-Mobile tile both use. Without it the V floated on the plate
       and the lockup read as one undivided block. */
    .cb-sig-vzn {
      background: #f6f2ec;
      border-right: 1.5px solid #e6e0d6;
    }

    .cb-sig-tmo {
      background: linear-gradient(158deg, #0b4368 0%, #07304a 55%, #04222f 100%);
    }

    .cb-sig svg {
      display: block;
      height: 26px;
      width: auto;
    }

    /* the V is a solid mass where the globe and the tower are open forms, so
       it is set smaller to carry the same weight in its tile. The official
       file carries a 15.7% clear-space band on all four sides, so the box runs
       larger than the mark. 30px lands the V itself at ~21px — a shade up on
       the 18px the old silhouette used, because that one was solid white on
       saturated red and this one is red on the plate's own white, which
       carries less weight at the same size. */
    .cb-sig img {
      display: block;
      height: 30px;
      width: auto;
    }

    .cb-txt {
      display: grid;
      align-content: center;
      gap: 1px;
      padding: 0 8px;
    }

    .cb-c1 {
      font-size: 8px;
      font-weight: 600;
      line-height: 1.2;
      color: #79828a;
    }

    .cb-c2 {
      font-size: 11px;
      font-weight: 800;
      letter-spacing: -.02em;
      line-height: 1.1;
      white-space: nowrap;
      color: #1d2328;
    }

    /* required beside the carrier name, but must not compete with it */
    .cb-c2 .reg {
      font-size: .5em;
      font-weight: 700;
      letter-spacing: 0;
      vertical-align: .62em;
    }

    .cb-c3 {
      font-size: 6.5px;
      font-style: italic;
      line-height: 1.2;
      white-space: nowrap;
      color: #4d565e;
    }

    /* ---------- hero variant ----------
       On a carrier page the mark is a page-level statement, so it runs at the
       size the AT&T badge beside it uses: that badge is clamped to 46px, which
       is 184px on its 4:1 box. Everything inside steps up by the same 1.15 so
       the lockup scales rather than just stretching. */
    .carrier-mark .cb-cred {
      width: 184px;
      height: 46px;
    }

    .carrier-mark .cb-sig {
      width: 47px;
    }

    .carrier-mark .cb-sig svg {
      height: 30px;
    }

    .carrier-mark .cb-txt {
      padding: 0 9px;
    }

    .carrier-mark .cb-c1 {
      font-size: 9px;
    }

    .carrier-mark .cb-c2 {
      font-size: 12.5px;
    }

    .carrier-mark .cb-c3 {
      font-size: 7.5px;
    }
    @media (max-width:760px) {
      .carrier-band {
        flex-direction: column;
        gap: 16px;
        padding: 20px 24px;
      }

      .carrier-band .cb-label {
        flex: 0 1 auto;
        text-align: center;
      }

      .carrier-band .cb-lead {
        font-size: 20px;
      }

      .carrier-band .cb-marks {
        gap: 7px;
      }
    }

    .fiveg .grid5 {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 20px;
      margin-top: 14px;
    }

    .fiveg .cell {
      background: rgba(255, 255, 255, .07);
      border: 1px solid rgba(255, 255, 255, .14);
      border-radius: var(--r);
      padding: 17px 19px;
    }

    .fiveg .cell b {
      display: block;
      font-size: 16px;
      color: #fff;
      margin-bottom: 8px;
    }

    .fiveg .cell span {
      font-size: 14.5px;
      color: #cfe6f4;
    }

    .fiveg .cell .num {
      font-size: 13px;
      font-weight: 800;
      color: #ff8fc9;
      letter-spacing: .1em;
    }

    @media (max-width:760px) {
      .fiveg .grid5 {
        grid-template-columns: 1fr;
      }
    }

    /* nav "New" badge */
    .nav-badge {
      font-size: 9px;
      font-weight: 800;
      letter-spacing: .06em;
      text-transform: uppercase;
      color: #fff;
      background: var(--magenta);
      padding: 2px 6px;
      border-radius: 20px;
      margin-left: -2px;
      vertical-align: middle;
    }

    /* ===== 5G PRODUCTS showcase ===== */
    .g5cta {
      color: var(--blue);
      font-weight: 750;
      font-size: 14.5px;
      text-decoration: none;
    }

    .g5cta:hover {
      text-decoration: underline;
    }

    .g5sheet {
      color: var(--ink-faint);
      font-weight: 600;
      font-size: 13.5px;
      text-decoration: none;
      display: inline-flex;
      align-items: center;
      gap: 5px;
    }

    .g5sheet::before {
      content: "↓";
      font-weight: 800;
    }

    .g5sheet:hover {
      color: var(--blue);
    }

    /* phone showcase */
    /* two-up hardware photos under the section intro */
    .hwshots {
      display: grid;
      grid-template-columns: 602fr 772fr;
      gap: 22px;
      align-items: stretch;
      max-width: 1120px;
      margin: 0 auto 34px;
    }

    @media (max-width:820px) {
      .hwshots {
        grid-template-columns: 1fr;
      }
    }

    .hwshot {
      margin: 0;
      border-radius: 18px;
      overflow: hidden;
      background: #f4f5f7;
      min-height: 180px;
    }

    .hwshot img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    :root[data-theme="dark"] .hwshot {
      background: #20272e;
    }

    @media (prefers-color-scheme:dark) {
      .hwshot {
        background: #20272e;
      }
    }

    .products {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 22px;
    }

    .prod {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: var(--r);
      overflow: hidden;
      box-shadow: var(--shadow-sm);
      transition: transform .22s cubic-bezier(.22, .61, .36, 1), box-shadow .22s, border-color .22s;
    }

    .band.alt .prod {
      background: #eaf3fb;
      border-color: #cddff2;
    }

    /* The tinted card is a light-theme treatment. In dark mode it kept the tint
       while the type flipped to light ink, which left the title at 1.04:1
       against its own card — invisible. Sit it on the raised surface so it
       still separates from the .band.alt behind it and the ink reads.

       --blue also lightens to #4fb0e0 in dark mode, so white button text fell
       to 2.44:1; dark ink on that same fill is 7.57:1 and keeps the button on
       the brand colour rather than darkening it.

       Both go in three parts, the way the rest of this sheet handles dark: the
       media query covers an OS-level preference, the [data-theme="dark"] rules
       cover the explicit toggle, and the [data-theme="light"] rules undo the
       media query for someone whose OS is dark but who has forced light. */
    @media (prefers-color-scheme:dark) {
      .band.alt .prod {
        background: var(--surface-2);
        border-color: var(--line);
      }

      .viewbtn,
      .prod .links a.viewbtn {
        color: #0c151b;
      }
    }

    :root[data-theme="dark"] .band.alt .prod {
      background: var(--surface-2);
      border-color: var(--line);
    }

    :root[data-theme="dark"] .viewbtn,
    :root[data-theme="dark"] .prod .links a.viewbtn {
      color: #0c151b;
    }

    :root[data-theme="light"] .band.alt .prod {
      background: #eaf3fb;
      border-color: #cddff2;
    }

    :root[data-theme="light"] .viewbtn,
    :root[data-theme="light"] .prod .links a.viewbtn {
      color: #fff;
    }

    .prod:hover {
      transform: translateY(-6px);
      box-shadow: var(--shadow-md);
      border-color: color-mix(in srgb, var(--magenta) 40%, var(--line));
    }

    .prod .ph img {
      transition: transform .4s cubic-bezier(.22, .61, .36, 1);
    }

    .prod:hover .ph img {
      transform: scale(1.07) rotate(-1deg);
    }

    .prod .cat,
    .prod h3 {
      transition: color .2s;
    }

    .prod:hover h3 {
      color: var(--blue);
    }

    .prod .ph {
      height: 170px;
      background: linear-gradient(135deg, #eef5fd, #dfeafb);
      display: grid;
      place-items: center;
    }

    .prod .ph svg {
      width: 74px;
      height: 74px;
      color: var(--blue);
      opacity: .85;
    }

    .prod .body {
      padding: 20px 22px 22px;
    }

    .prod .cat {
      font-size: 11px;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--magenta);
      font-weight: 700;
    }

    .prod h3 {
      font-size: 18px;
      margin: 6px 0 8px;
    }

    .prod p {
      font-size: 14px;
      color: var(--ink-soft);
      margin: 0 0 14px;
    }

    .prod .links {
      display: flex;
      gap: 14px;
      font-size: 13.5px;
      font-weight: 700;
    }

    .prod .links a {
      color: var(--blue);
      text-decoration: none;
      display: inline-flex;
      align-items: center;
      gap: 5px;
    }

    .prod .links a:hover {
      text-decoration: underline;
    }

    .prod .links a.sheet {
      color: var(--ink-soft);
    }

    @media (max-width:820px) {
      .products {
        grid-template-columns: 1fr 1fr;
      }
    }

    @media (max-width:560px) {
      .products {
        grid-template-columns: 1fr;
      }
    }

    /* SALES REQUEST cta band */
    .srband {
      padding: 90px 0;
    }

    .srcard {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 22px;
      box-shadow: var(--shadow-md);
      padding: 34px;
      display: grid;
      grid-template-columns: 1.1fr .9fr;
      gap: 30px;
      align-items: center;
      position: relative;
      overflow: hidden;
    }

    .srcard::before {
      content: "";
      position: absolute;
      right: -80px;
      top: -80px;
      width: 280px;
      height: 280px;
      background: radial-gradient(circle, var(--magenta), transparent 62%);
      opacity: .16;
    }

    .srcard .sec-eyebrow {
      margin-bottom: 12px;
    }

    .srcard h2 {
      font-size: clamp(26px, 3.4vw, 38px);
      margin: 0 0 14px;
      font-weight: 800;
    }

    .srcard p {
      font-size: 16.5px;
      color: var(--ink-soft);
      margin: 0 0 26px;
      max-width: 44ch;
    }

    .srcard .btn-primary {
      box-shadow: 0 12px 30px -8px rgba(235, 0, 139, .55);
    }

    /* mini stepper preview */
    .stepper {
      position: relative;
      z-index: 1;
    }

    .step {
      display: flex;
      gap: 14px;
      align-items: flex-start;
      padding: 14px 0;
      border-bottom: 1px dashed var(--line);
    }

    .step:last-child {
      border-bottom: 0;
    }

    .step .n {
      flex: none;
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background: var(--blue);
      color: #fff;
      display: grid;
      place-items: center;
      font-weight: 700;
      font-size: 14px;
    }

    .step .n.done {
      background: var(--good);
    }

    .step .n.now {
      background: var(--magenta);
      box-shadow: 0 0 0 4px color-mix(in srgb, var(--magenta) 22%, transparent);
    }

    .step b {
      font-size: 15px;
      display: block;
    }

    .step span {
      font-size: 13.5px;
      color: var(--ink-faint);
    }

    .step .opts {
      display: flex;
      gap: 8px;
      margin-top: 8px;
      flex-wrap: wrap;
    }

    .step .opts em {
      font-style: normal;
      font-size: 12.5px;
      padding: 5px 12px;
      border: 1px solid var(--line);
      border-radius: 20px;
      color: var(--ink-soft);
    }

    .step .opts em.sel {
      background: color-mix(in srgb, var(--magenta) 12%, transparent);
      border-color: var(--magenta);
      color: var(--magenta-deep);
      font-weight: 600;
    }

    @media (max-width:820px) {
      .srcard {
        grid-template-columns: 1fr;
        padding: 24px 20px;
      }
    }

    /* footer */
    /* ===== Ooma-style charcoal footer ===== */
    footer.site {
      background: var(--charcoal);
      color: #b6bec5;
      padding: 0 0 30px;
    }

    /* trust badge row across the top of the footer */
    .foot-trust {
      border-bottom: 1px solid rgba(255, 255, 255, .1);
      padding: 26px 0;
    }

    .foot-trust .wrap {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 20px 44px;
      flex-wrap: wrap;
    }

    .foot-trust .b {
      display: inline-flex;
      align-items: center;
      gap: 9px;
      font-size: 13px;
      font-weight: 700;
      color: #e4e8ec;
      letter-spacing: .02em;
    }

    .foot-trust .b svg {
      width: 18px;
      height: 18px;
      color: #8fe0ff;
    }

    /* ---------- footer carrier row ----------
       The order is deliberate and is the whole point of the layout: the
       T-Mobile mark stands on its own ahead of the wording, so "Partner with"
       governs only AT&T and Verizon, who are the licensed partners. T-Mobile is
       named in plain text with its ® and is never called a partner. */
    .foot-trust .foot-carriers {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
      /* No gap of its own: the row rides .foot-trust .wrap's 20px/44px rhythm.
         The tighter 26px here existed only to fit a seventh item on one line. */
    }

    .foot-carriers .fc-lead {
      font-size: 13px;
      font-weight: 700;
      letter-spacing: .02em;
      color: #e4e8ec;
    }

    .foot-carriers img {
      display: block;
      width: auto;
      height: 40px;
    }

    /* ---------- footer carrier row marks ----------
       The row is built from the same .cb-cred lockup the 5G band uses, so all
       three marks carry the AT&T badge's 4:1 box, tile proportion and type
       hierarchy here too. AT&T's own raster is 40px tall, which is 160px wide,
       and the two lockups are held to that. */
    /* beats .foot-carriers img, which sizes the AT&T badge to the row height.
       30px matches the 5G band: the official V carries its clear space inside
       the file, so an 18px box left the mark itself at ~12px and it read as a
       speck next to the AT&T globe. */
    .foot-carriers .cb-sig img {
      height: 30px;
      width: auto;
    }

    footer.site .cols {
      display: grid;
      grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;
      gap: 30px;
      padding: 48px 0 34px;
      border-bottom: 1px solid rgba(255, 255, 255, .1);
    }

    footer.site .wm {
      font-size: 22px;
      font-weight: 800;
      color: #fff;
    }

    footer.site .wm em {
      color: #ff5cae;
      font-style: italic;
    }

    footer.site p {
      font-size: 14px;
      color: #9aa3ab;
      max-width: 34ch;
      margin: 12px 0 16px;
    }

    footer.site .fcontact {
      font-size: 14px;
    }

    footer.site .fcontact a {
      color: #e4e8ec;
      display: block;
      padding: 3px 0;
    }

    footer.site h5 {
      font-size: 12px;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: #8fe0ff;
      margin: 0 0 14px;
    }

    footer.site a {
      display: block;
      color: #b6bec5;
      text-decoration: none;
      font-size: 14px;
      padding: 5px 0;
    }

    footer.site a:hover {
      color: #fff;
    }

    footer.site .legal {
      display: flex;
      gap: 16px;
      flex-wrap: wrap;
      justify-content: space-between;
      align-items: center;
      padding-top: 22px;
      font-size: 12.5px;
      color: #8b949c;
    }

    footer.site .fbadge {
      display: flex;
      gap: 20px;
      align-items: center;
    }

    footer.site .fbadge a {
      display: inline;
      padding: 0;
      font-size: 12.5px;
      color: #9aa3ab;
    }

    footer.site .fbadge a:hover {
      color: #fff;
    }

    @media (max-width:900px) {
      footer.site .cols {
        grid-template-columns: 1fr 1fr 1fr;
      }

      footer.site .fbrand {
        grid-column: 1 / -1;
      }
    }

    @media (max-width:520px) {
      footer.site .cols {
        grid-template-columns: 1fr 1fr;
      }

      .foot-trust .wrap {
        gap: 14px 24px;
      }
    }

    .visually-hidden {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
    }

    a:focus-visible,
    button:focus-visible {
      outline: 3px solid var(--magenta);
      outline-offset: 2px;
      border-radius: 4px;
    }

    /* ---- every action button is the same height as the Sales Request pill.
       The container-scoped rules above set padding with a shorthand and out-rank a
       bare .viewbtn, so those containers are named here to reset it cleanly. ---- */
    .pcta .viewbtn,
    .pcta .btn-outline,
    .sw-actions .viewbtn,
    .sw-actions .btn-outline,
    .ab-cta .viewbtn,
    .ab-cta .btn-outline,
    .ds-actions .viewbtn,
    .ds-actions .btn-outline,
    .prod .links a.viewbtn,
    .viewbtn,
    .btn-outline,
    a.buybtn {
      height: 30px;
      padding-top: 0;
      padding-bottom: 0;
      align-items: center;
    }

    /* ---------------------------------------------------------------
       Shared-header fix, kept here so it is easy to lift into the other
       pages: between 1016px and 1360px the About Us panel is centred on a
       trigger that sits close to the right edge, so the hidden panel pushes
       the document sideways and the whole page gains a horizontal scrollbar.
       Right-aligning it to the trigger keeps it on-screen at every width.
       --------------------------------------------------------------- */
    @media (min-width:1016px) and (max-width:1360px) {
      header.site .mega.mega-sm.ab-menu {
        left: auto;
        right: 0;
        transform: translateY(-8px);
      }

      header.site .has-mega.ab:hover .ab-menu,
      header.site .has-mega.ab:focus-within .ab-menu,
      header.site .has-mega.ab.open .ab-menu {
        transform: none;
      }
    }

    /* Same story one tier down: between the 1030px stop and 1150px the nav
       still uses the roomy 1180px sizing, so the last item runs past the
       viewport on smaller laptops. Borrow the compact tier for that band. */
    @media (min-width:1031px) and (max-width:1150px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding: 0 5px;
        font-size: 12.6px;
        gap: 4px;
      }

      .nav-badge {
        margin-left: 2px;
        padding: 2px 5px;
        font-size: 9px;
      }
    }

    /* "View product" is a secondary link on a card, not a primary CTA — it runs
       a size below the Sales Request / Buy Now buttons */
    .prod .links a.viewbtn,
    .phone-cta a.viewbtn,
    .sw-card .row a.viewbtn,
    .row a.viewbtn {
      height: 25px;
      padding: 0 13px;
      font-size: 11.5px;
      border-radius: 8px;
      box-shadow: 0 5px 14px -7px var(--blue);
    }

    /* ---- "Videos" makes ten top-level items. The one-line ladder above was
       tuned for nine, so from the hamburger breakpoint up to 1250px the row is
       re-interpolated a little tighter instead of stepped, which is where the
       nine items were already closest to the Sales Request button. ---- */
    @media (min-width:1011px) and (max-width:1250px) {

      nav.main>a,
      nav.main .has-mega>a {
        padding-left: clamp(3px, calc(1.05vw - 8.6px), 6px);
        padding-right: clamp(3px, calc(1.05vw - 8.6px), 6px);
        font-size: clamp(11.2px, calc(0.62vw + 4.4px), 12.8px);
        gap: 3px;
      }

      nav.main .caret {
        width: 9px;
      }

      .nav-badge {
        margin-left: 2px;
        padding: 1px 4px;
        font-size: 8.5px;
      }
    }
  
    /* ============================================================
       VIDEO FEATURE
       ------------------------------------------------------------
       The composition is the one the carrier pages already use for
       #partner-video: copy in the narrower left column, player in the
       wider right column, the two centred on each other so they read
       as a single block rather than a picture next to a paragraph.

       Two containers use it. A product page carries one video, so it
       gets the full-bleed band — the same treatment as the carrier
       pages. The library carries nine, so each one is a panel on the
       page ground; nine bands would be unreadable.

       .vplay is the player: a static poster that swaps itself for the
       YouTube embed on click, so a page costs one JPEG rather than a
       third-party player. The posters are designed artwork with type
       set to their own edges, so nothing crops or dims them beyond
       the small play badge.
       ============================================================ */
    .vsec {
      --vcols: minmax(0, .86fr) minmax(0, 1.14fr);
      --vgap: clamp(28px, 3.4vw, 58px);
    }

    .vplay {
      position: relative;
      margin: 0;
      aspect-ratio: 16 / 9;
      border-radius: 14px;
      overflow: hidden;
      background: #0a1219;
      border: 1px solid var(--line);
      box-shadow: var(--shadow-md);
    }

    .vplay-btn {
      position: absolute;
      inset: 0;
      display: block;
      text-decoration: none;
      color: #fff;
      cursor: pointer;
    }

    /* No crop and no zoom: the poster is artwork with type set to its own
       edges, so anything that scales it eats the headline. */
    .vplay-btn img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
      transition: filter .3s ease;
    }

    .vplay-btn:hover img,
    .vplay-btn:focus-visible img {
      filter: brightness(.9);
    }

    .vplay-ico {
      position: absolute;
      left: 50%;
      top: 50%;
      z-index: 1;
      transform: translate(-50%, -50%);
      display: grid;
      place-items: center;
      /* the whole poster is the link, so this is an affordance rather than a
         hit target — kept small so it sits on the artwork, not over it */
      width: clamp(42px, 3.9vw, 56px);
      height: clamp(42px, 3.9vw, 56px);
      border-radius: 50%;
      background: color-mix(in srgb, var(--magenta) 92%, #000);
      border: 2px solid rgba(255, 255, 255, .9);
      box-shadow: 0 12px 34px rgba(3, 10, 16, .5);
      transition: transform .18s ease, background .18s ease;
    }

    .vplay-btn:hover .vplay-ico,
    .vplay-btn:focus-visible .vplay-ico {
      transform: translate(-50%, -50%) scale(1.08);
      background: var(--magenta);
    }

    .vplay-ico svg {
      display: block;
      width: 38%;
      height: 38%;
      margin-left: 8%;
      fill: #fff;
    }

    .vplay-btn:focus-visible {
      outline: 3px solid #fff;
      outline-offset: -4px;
    }

    .vplay iframe {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      border: 0;
      display: block;
    }

    /* the same poster runs at ~360px on a phone and ~700px in a feature, so the
       badge is sized against the poster rather than the viewport where the
       browser can do it. The clamp above stays as the fallback. */
    @supports (container-type: inline-size) {
      .vplay {
        container-type: inline-size;
      }

      .vplay-ico {
        width: clamp(40px, 9.5cqw, 62px);
        height: clamp(40px, 9.5cqw, 62px);
      }
    }

    @media (prefers-reduced-motion:reduce) {

      .vplay-btn img,
      .vplay-ico {
        transition: none;
      }
    }

    /* ---- section head: headline left, lead right against a rule, so the head
       uses the full measure instead of leaving half the row empty ---- */
    .vhead {
      display: grid;
      grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
      column-gap: clamp(32px, 4.5vw, 72px);
      align-items: start;
      margin-bottom: clamp(26px, 3vw, 40px);
    }

    .vhead .sec-eyebrow {
      justify-self: start;
      font-size: 13px;
      margin: 0 0 16px;
    }

    .vhead h2 {
      font-family: var(--serif);
      font-weight: 600;
      margin: 0;
      max-width: 26ch;
      font-size: clamp(26px, 2.9vw, 38px);
      line-height: 1.12;
      letter-spacing: -.02em;
      color: var(--ink);
      text-wrap: balance;
    }

    /* the lead centres on the headline, not on the eyebrow + headline stack */
    .vhead-lead {
      align-self: center;
      margin-top: 22px;
      padding-left: clamp(24px, 2.6vw, 40px);
      border-left: 1px solid var(--line);
    }

    .vhead-lead p {
      margin: 0;
      font-size: clamp(15.5px, 1.05vw, 17px);
      line-height: 1.78;
      color: var(--ink-soft);
      text-align: justify;
      text-justify: inter-word;
      -webkit-hyphens: auto;
      hyphens: auto;
    }

    /* ---- the feature ---- */
    .vfeat {
      display: grid;
      grid-template-columns: var(--vcols);
      column-gap: var(--vgap);
      align-items: center;
    }

    .vfeat>.vfeat-copy {
      grid-column: 1;
      min-width: 0;
    }

    /* poster and caption are one column item, so the caption stays attached to
       the poster while the pair centres against the copy */
    .vfeat>.vfeat-media {
      grid-column: 2;
      min-width: 0;
    }

    .vfeat-meta {
      display: flex;
      align-items: baseline;
      gap: 9px;
      margin: 0 0 10px;
    }

    .vfeat-cat {
      font-size: 11px;
      font-weight: 800;
      letter-spacing: .11em;
      text-transform: uppercase;
      color: var(--magenta-ink);
    }

    .vfeat-dur {
      font-size: 11.5px;
      font-weight: 700;
      color: var(--ink-faint);
      font-variant-numeric: tabular-nums;
    }

    .vfeat-dur::before {
      content: "";
      display: inline-block;
      width: 3px;
      height: 3px;
      margin-right: 9px;
      border-radius: 50%;
      background: currentColor;
      vertical-align: middle;
    }

    .vfeat-title {
      margin: 0;
      font-size: clamp(19px, 1.6vw, 24px);
      line-height: 1.24;
      letter-spacing: -.018em;
      font-weight: 700;
      color: var(--ink);
      text-wrap: balance;
    }

    .vfeat-desc {
      margin: 12px 0 0;
      font-size: clamp(15px, 1.05vw, 16.5px);
      line-height: 1.74;
      color: var(--ink-soft);
    }

    /* what the video covers, in the words on the video's own artwork */
    .vfeat-points {
      list-style: none;
      margin: 16px 0 0;
      padding: 0;
      display: grid;
      gap: 8px;
    }

    .vfeat-points li {
      position: relative;
      padding-left: 20px;
      font-size: 14.2px;
      line-height: 1.55;
      color: var(--ink-soft);
    }

    .vfeat-points li::before {
      content: "";
      position: absolute;
      left: 2px;
      top: .52em;
      width: 7px;
      height: 7px;
      border-radius: 50%;
      background: color-mix(in srgb, var(--magenta) 55%, transparent);
    }

    .vfeat-link {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      margin-top: 18px;
      font-size: 14px;
      font-weight: 700;
      color: var(--blue);
      text-decoration: none;
    }

    .vfeat-link:hover {
      text-decoration: underline;
    }

    .vfeat-link svg {
      width: 14px;
      height: 14px;
      transition: transform .16s;
    }

    .vfeat-link:hover svg {
      transform: translateX(3px);
    }

    /* ---- container A: the panel, for the library's stacked list ---- */
    .vlist {
      display: grid;
      gap: clamp(16px, 1.8vw, 24px);
    }

    .vfeat.is-panel {
      background: var(--surface);
      border: 1px solid var(--line);
      border-radius: 20px;
      padding: clamp(22px, 2.4vw, 34px);
      box-shadow: var(--shadow-sm);
    }

    /* the carrier clips are the carriers' own, so their panels take the deep
       field the carrier pages use — the collection around them stays light */
    .vfeat.is-panel.is-dark {
      position: relative;
      overflow: hidden;
      background: linear-gradient(150deg, #10222e 0%, #0d3448 42%, #082a3e 100%);
      border-color: rgba(255, 255, 255, .12);
      box-shadow: var(--shadow-md);
    }

    .vfeat.is-panel.is-dark::after {
      content: "";
      position: absolute;
      inset: 0;
      border-radius: inherit;
      background:
        radial-gradient(560px 260px at 96% 0%, rgba(0, 118, 175, .34), transparent 62%),
        radial-gradient(420px 220px at 2% 106%, rgba(235, 0, 139, .18), transparent 64%);
      pointer-events: none;
    }

    .vfeat.is-panel.is-dark>* {
      position: relative;
      z-index: 1;
    }

    /* ---- the section a video sits in — the page ground, with the panels
       carrying the rhythm. One class for the library's collections and for a
       product page's single video, so both read identically. ---- */
    .vband {
      /* the section ends in a panel that carries its own padding and shadow,
         and whatever follows brings its own generous top padding. A symmetric
         band stacked the two and left a hole under the card, so the bottom is
         only a hair — the next section's padding does the separating. */
      padding: clamp(46px, 5vw, 76px) 0 clamp(10px, 1.2vw, 18px);
      background: var(--bg);
      scroll-margin-top: 76px;
    }

    /* the deep field now belongs to the carrier panels alone */
    .vfeat.is-dark .vfeat-title {
      color: #fff;
    }

    .vfeat.is-dark .vfeat-desc {
      color: rgba(255, 255, 255, .82);
    }

    .vfeat.is-dark .vfeat-points li {
      color: rgba(255, 255, 255, .78);
    }

    .vfeat.is-dark .vfeat-points li::before {
      background: #ff8ac8;
    }

    .vfeat.is-dark .vfeat-link {
      color: #9fd6ef;
    }

    .vfeat.is-dark .vfeat-cat {
      color: #ff8ac8;
    }

    .vfeat.is-dark .vfeat-dur {
      color: rgba(255, 255, 255, .6);
    }

    .vfeat.is-dark .vplay {
      border-color: rgba(255, 255, 255, .18);
    }

    /* ---- stacked ---- */
    @media (max-width:980px) {
      .vhead {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 18px;
      }

      .vhead-lead {
        align-self: start;
        margin-top: 0;
        padding-left: 0;
        border-left: 0;
      }

      .vhead-lead p {
        text-align: left;
        max-width: 68ch;
      }

      .vhead h2 {
        max-width: none;
      }

      .vfeat {
        grid-template-columns: minmax(0, 1fr);
        row-gap: clamp(18px, 2.6vw, 24px);
      }

      .vfeat>.vfeat-copy,
      .vfeat>.vfeat-media {
        grid-column: 1;
      }

      /* stacked, the poster leads */
      .vfeat>.vfeat-media {
        order: -1;
      }

      .vfeat-desc,
      .vfeat-points {
        max-width: 64ch;
      }
    }

  

    /* Floating chrome: brand blue at rest, brand magenta on hover. Kept on the
       literal brand hexes rather than --blue/--magenta so the white arrow keeps
       its contrast in both the light and dark themes. */
    .to-top {
      position: fixed;
      right: 22px;
      bottom: 22px;
      z-index: 45;
      width: 46px;
      height: 46px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 0;
      border: 0;
      border-radius: 50%;
      cursor: pointer;
      color: #fff;
      background: #0076af;
      /* hairline magenta ring: brand pink at rest, and it keeps the edge
         defined where the button floats over the site's blue bands */
      box-shadow: 0 0 0 1.5px rgba(235, 0, 139, .5), 0 10px 24px -8px rgba(0, 118, 175, .7), 0 2px 6px rgba(20, 30, 40, .12);
      opacity: 0;
      visibility: hidden;
      transform: translateY(10px) scale(.94);
      /* visibility flips instantly on the way in, and only after the fade on the
         way out, so the button never fades in while still invisible */
      transition: opacity .22s ease, transform .22s ease, background .14s ease, box-shadow .14s ease, visibility 0s linear .22s;
    }

    .to-top.is-on {
      opacity: 1;
      visibility: visible;
      transform: none;
      transition: opacity .22s ease, transform .22s ease, background .14s ease, box-shadow .14s ease, visibility 0s;
    }

    .to-top:hover {
      background: #eb008b;
      transform: translateY(-3px);
      /* the two brand colours swap on hover: magenta fill, blue ring */
      box-shadow: 0 0 0 1.5px rgba(0, 118, 175, .55), 0 14px 28px -8px rgba(235, 0, 139, .65), 0 2px 6px rgba(20, 30, 40, .12);
    }

    .to-top:active {
      transform: translateY(-1px);
    }

    .to-top svg {
      display: block;
      width: 19px;
      height: 19px;
    }

    @media (max-width:720px) {
      .to-top {
        right: 14px;
        bottom: 14px;
        width: 42px;
        height: 42px;
      }
    }

    @media (prefers-reduced-motion:reduce) {
      .to-top,
      .to-top.is-on {
        transition: opacity .01s linear, background .14s ease, visibility 0s;
      }

      .to-top,
      .to-top:hover,
      .to-top:active {
        transform: none;
      }
    }

    /* ==== small-screen corrections — scripts/mobile-fixes.py ==== */

    /* Below the width where anything sits side by side, a sideways reveal has
       nowhere to come from: it starts 34px outside a wrap that has 26px of
       padding, and the document is wider than the screen until the element
       lands. The rise is the right motion on a stacked layout anyway. */
    @media (max-width: 900px) {

      [data-reveal="left"],
      [data-reveal="right"] {
        transform: translateY(26px);
      }
    }

    /* The highlighted phrase in a switch title is nowrap, so its underlay — an
       absolute ::after — cannot break across lines. The phrase is wider than a
       phone, so here it wraps and the underlay becomes an inline background
       cloned onto every line fragment instead. */
    @media (max-width: 700px) {
      .switch-title .focus {
        white-space: normal;
        padding: 0 4px;
        border-radius: 4px;
        background: color-mix(in srgb, var(--magenta) 22%, transparent);
        -webkit-box-decoration-break: clone;
        box-decoration-break: clone;
      }

      .switch-title .focus::after {
        display: none;
      }
    }

    /* One class, so the 13px eyebrows the inner section heads set still win and
       only the 22px base — which the centred heads on the home page take —
       comes down to something a 320px column can hold. */
    @media (max-width: 560px) {
      .sec-eyebrow {
        font-size: 15px;
        letter-spacing: .09em;
        padding: 5px 12px 5px 10px;
      }

      .sec-eyebrow::before {
        width: 6px;
        height: 6px;
      }
    }


    /* Each hero point is nowrap so its animated underline spans one line. As a
       flex item that cannot shrink below its content, on a phone the rows were
       cut off mid-word inside the hero's clipped box. The underline is a
       block-level flex item already, so it survives the wrap. */
    @media (max-width: 900px) {

      .hp-row>span:last-child,
      ul.hero-points li.hp-warranty>span:last-child {
        white-space: normal;
        min-width: 0;
      }
    }

    /* Justified copy is tidy at a desktop measure and is rivers of white and a
       hyphen every other line at forty characters. Ragged right on a phone. */
    @media (max-width: 700px) {

      .cap p,
      .cd-hero .lead,
      .cd-lead p,
      .cprose p,
      .prose p,
      .prime-ab-card p,
      .vhead-lead p,
      .fd-block>p,
      .pf-copy>p:not(.role),
      .fs-lead>p,
      .bio-body>p {
        text-align: left;
        hyphens: manual;
      }
    }


    /* The utility bar runs out of room before the phone does.

       At 360px the logo plate takes 142 of the 360, leaving 218 for the
       controls on its right — and they want 241: the account button (38),
       the cart (30) and Contact Us (121). The bar is overflow:hidden, so
       nothing scrolls sideways and the excess is simply cut: "Contact Us"
       reaches a phone as "Conta". It fits from about 440px up, which is
       above every common phone width and below every tablet.

       Contact Us loses its label and becomes the third circle in the row,
       drawn exactly like the two beside it. The destination is unchanged and
       the label is hidden from the eye rather than removed, so the link is
       still called "Contact Us" by a screen reader — and the anchor's title,
       which carries the phone number and the address, stays as it was. */
    @media (max-width: 460px) {
      .util-right .contact-us {
        width: 34px;
        height: 34px;
        gap: 0;
        padding: 0;
        justify-content: center;
        box-sizing: border-box;
        border: 1px solid rgba(255, 255, 255, .38);
        border-radius: 50%;
        background: rgba(255, 255, 255, .08);
      }

      .util-right .contact-us span {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
      }

      .util-right .contact-us svg {
        width: 18px;
        height: 18px;
        margin: 0;
      }
    }

    /* ==== end small-screen corrections ==== */
  


/* --- link state restore, generated by port_page.py ---
   Cancels Odoo's `a:hover,a:active,a:focus{color:#004868!important}`.
   See restore_link_states() for why this cannot be done any other way. */
.cart-btn.cart-mini:hover { color: #fff !important; text-decoration: none !important; }
.cart-btn.cart-mini:active { color: #fff !important; text-decoration: none !important; }
.cart-btn.cart-mini:focus { color: #fff !important; text-decoration: none !important; }
.cart-btn.cart-mini:hover:hover { color: #fff !important; }
.cart-btn.cart-mini:hover:active { color: #fff !important; }
.cart-btn.cart-mini:hover:focus { color: #fff !important; }
.cart-btn.cart-mini:focus-visible:hover { color: #fff !important; }
.cart-btn.cart-mini:focus-visible:active { color: #fff !important; }
.cart-btn.cart-mini:focus-visible:focus { color: #fff !important; }
.cart-btn.cart-mini .cart-count:hover { color: #fff !important; }
.cart-btn.cart-mini .cart-count:active { color: #fff !important; }
.cart-btn.cart-mini .cart-count:focus { color: #fff !important; }
.acct-menu a:hover { color: var(--ink-soft, #4d565e) !important; text-decoration: none !important; }
.acct-menu a:active { color: var(--ink-soft, #4d565e) !important; text-decoration: none !important; }
.acct-menu a:focus { color: var(--ink-soft, #4d565e) !important; text-decoration: none !important; }
.acct-menu a:hover:hover { color: var(--blue, #0076af) !important; }
.acct-menu a:hover:active { color: var(--blue, #0076af) !important; }
.acct-menu a:hover:focus { color: var(--blue, #0076af) !important; }
.acct-menu a:focus-visible:hover { color: var(--blue, #0076af) !important; }
.acct-menu a:focus-visible:active { color: var(--blue, #0076af) !important; }
.acct-menu a:focus-visible:focus { color: var(--blue, #0076af) !important; }
.acct-menu-cta a.buybtn:hover { color: #fff !important; }
.acct-menu-cta a.buybtn:active { color: #fff !important; }
.acct-menu-cta a.buybtn:focus { color: #fff !important; }
.acct-menu-cta a.buybtn:hover:hover { color: #fff !important; }
.acct-menu-cta a.buybtn:hover:active { color: #fff !important; }
.acct-menu-cta a.buybtn:hover:focus { color: #fff !important; }
.acct-menu-cta a.btn-outline:hover { color: var(--ink, #1d2328) !important; }
.acct-menu-cta a.btn-outline:active { color: var(--ink, #1d2328) !important; }
.acct-menu-cta a.btn-outline:focus { color: var(--ink, #1d2328) !important; }
.acct-menu-cta a.btn-outline:hover:hover { color: var(--blue, #0076af) !important; }
.acct-menu-cta a.btn-outline:hover:active { color: var(--blue, #0076af) !important; }
.acct-menu-cta a.btn-outline:hover:focus { color: var(--blue, #0076af) !important; }
a:hover { color: inherit !important; }
a:active { color: inherit !important; }
a:focus { color: inherit !important; }
.vswitch a:hover { text-decoration: none !important; color: #cfd6dc !important; }
.vswitch a:active { text-decoration: none !important; color: #cfd6dc !important; }
.vswitch a:focus { text-decoration: none !important; color: #cfd6dc !important; }
.vswitch a:hover:hover { color: #fff !important; }
.vswitch a:hover:active { color: #fff !important; }
.vswitch a:hover:focus { color: #fff !important; }
.vswitch a.on:hover { color: #141a1f !important; }
.vswitch a.on:active { color: #141a1f !important; }
.vswitch a.on:focus { color: #141a1f !important; }
.contact-us:hover { color: #fff !important; text-decoration: none !important; }
.contact-us:active { color: #fff !important; text-decoration: none !important; }
.contact-us:focus { color: #fff !important; text-decoration: none !important; }
.contact-us em:hover { color: #ff8ac8 !important; }
.contact-us em:active { color: #ff8ac8 !important; }
.contact-us em:focus { color: #ff8ac8 !important; }
.logo .wm .n:hover { color: var(--blue) !important; }
.logo .wm .n:active { color: var(--blue) !important; }
.logo .wm .n:focus { color: var(--blue) !important; }
.logo .wm .n em:hover { color: var(--magenta) !important; }
.logo .wm .n em:active { color: var(--magenta) !important; }
.logo .wm .n em:focus { color: var(--magenta) !important; }
.logo .wm .t:hover { color: var(--ink-faint) !important; }
.logo .wm .t:active { color: var(--ink-faint) !important; }
.logo .wm .t:focus { color: var(--ink-faint) !important; }
nav.main>a:hover { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main>a:active { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main>a:focus { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main .has-mega>a:hover { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main .has-mega>a:active { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main .has-mega>a:focus { text-decoration: none !important; color: var(--ink-soft) !important; }
nav.main>a:hover:hover { color: var(--blue) !important; }
nav.main>a:hover:active { color: var(--blue) !important; }
nav.main>a:hover:focus { color: var(--blue) !important; }
nav.main .has-mega:hover>a:hover { color: var(--blue) !important; }
nav.main .has-mega:hover>a:active { color: var(--blue) !important; }
nav.main .has-mega:hover>a:focus { color: var(--blue) !important; }
nav.main .has-mega:focus-within>a:hover { color: var(--blue) !important; }
nav.main .has-mega:focus-within>a:active { color: var(--blue) !important; }
nav.main .has-mega:focus-within>a:focus { color: var(--blue) !important; }
.cta-btn:hover { color: #fff !important; text-decoration: none !important; }
.cta-btn:active { color: #fff !important; text-decoration: none !important; }
.cta-btn:focus { color: #fff !important; text-decoration: none !important; }
.mega.g5-menu .mm-acc .mm-cat:hover { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega.g5-menu .mm-acc .mm-cat:active { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega.g5-menu .mm-acc .mm-cat:focus { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega.g5-menu .mm-acc .mm-cat:hover:hover { color: var(--blue) !important; }
.mega.g5-menu .mm-acc .mm-cat:hover:active { color: var(--blue) !important; }
.mega.g5-menu .mm-acc .mm-cat:hover:focus { color: var(--blue) !important; }
.mega.g5-menu .mm-acc .mm-prod-meta:hover { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega.g5-menu .mm-acc .mm-prod-meta:active { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega.g5-menu .mm-acc .mm-prod-meta:focus { color: color-mix(in srgb, var(--ink-faint) 55%, var(--ink-soft)) !important; }
.mega .col a:hover { text-decoration: none !important; color: var(--ink-soft) !important; }
.mega .col a:active { text-decoration: none !important; color: var(--ink-soft) !important; }
.mega .col a:focus { text-decoration: none !important; color: var(--ink-soft) !important; }
.mega .col a:hover:hover { color: var(--blue) !important; }
.mega .col a:hover:active { color: var(--blue) !important; }
.mega .col a:hover:focus { color: var(--blue) !important; }
.mega .mm-item .ds:hover { color: var(--ink-faint) !important; }
.mega .mm-item .ds:active { color: var(--ink-faint) !important; }
.mega .mm-item .ds:focus { color: var(--ink-faint) !important; }
.mega .hp-desc .ds:hover { color: var(--ink-faint) !important; }
.mega .hp-desc .ds:active { color: var(--ink-faint) !important; }
.mega .hp-desc .ds:focus { color: var(--ink-faint) !important; }
.mega .mm-item .ds:hover:hover { color: #fff !important; }
.mega .mm-item .ds:hover:active { color: #fff !important; }
.mega .mm-item .ds:hover:focus { color: #fff !important; }
.mega .hp-desc .ds:hover:hover { color: #fff !important; }
.mega .hp-desc .ds:hover:active { color: #fff !important; }
.mega .hp-desc .ds:hover:focus { color: #fff !important; }
.hp-desc a.hp-title:hover { color: var(--ink) !important; text-decoration: none !important; }
.hp-desc a.hp-title:active { color: var(--ink) !important; text-decoration: none !important; }
.hp-desc a.hp-title:focus { color: var(--ink) !important; text-decoration: none !important; }
.hp-desc a.hp-title:hover:hover { color: var(--blue) !important; }
.hp-desc a.hp-title:hover:active { color: var(--blue) !important; }
.hp-desc a.hp-title:hover:focus { color: var(--blue) !important; }
.mega .hp-all:hover { color: var(--magenta-ink) !important; text-decoration: none !important; }
.mega .hp-all:active { color: var(--magenta-ink) !important; text-decoration: none !important; }
.mega .hp-all:focus { color: var(--magenta-ink) !important; text-decoration: none !important; }
.mega .promo a:hover { color: var(--blue-ink) !important; text-decoration: none !important; }
.mega .promo a:active { color: var(--blue-ink) !important; text-decoration: none !important; }
.mega .promo a:focus { color: var(--blue-ink) !important; text-decoration: none !important; }
.hx-go:hover { color: var(--magenta-ink) !important; }
.hx-go:active { color: var(--magenta-ink) !important; }
.hx-go:focus { color: var(--magenta-ink) !important; }
.hx-go:hover:hover { color: #fff !important; }
.hx-go:hover:active { color: #fff !important; }
.hx-go:hover:focus { color: #fff !important; }
.hero-tabs a:hover { text-decoration: none !important; color: var(--ink-soft) !important; }
.hero-tabs a:active { text-decoration: none !important; color: var(--ink-soft) !important; }
.hero-tabs a:focus { text-decoration: none !important; color: var(--ink-soft) !important; }
.hero-tabs a:hover:hover { color: var(--blue) !important; }
.hero-tabs a:hover:active { color: var(--blue) !important; }
.hero-tabs a:hover:focus { color: var(--blue) !important; }
.hero .btn-ghost:hover { color: var(--ink) !important; }
.hero .btn-ghost:active { color: var(--ink) !important; }
.hero .btn-ghost:focus { color: var(--ink) !important; }
.btn-primary:hover { color: #fff !important; text-decoration: none !important; }
.btn-primary:active { color: #fff !important; text-decoration: none !important; }
.btn-primary:focus { color: #fff !important; text-decoration: none !important; }
.btn-ghost:hover { color: #fff !important; text-decoration: none !important; }
.btn-ghost:active { color: #fff !important; text-decoration: none !important; }
.btn-ghost:focus { color: #fff !important; text-decoration: none !important; }
.viewbtn:hover { color: #fff !important; text-decoration: none !important; }
.viewbtn:active { color: #fff !important; text-decoration: none !important; }
.viewbtn:focus { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:hover { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:active { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:focus { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:hover:hover { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:hover:active { color: #fff !important; text-decoration: none !important; }
.prod .links a.viewbtn:hover:focus { color: #fff !important; text-decoration: none !important; }
@media (prefers-color-scheme:dark) {
  .viewbtn:hover { color: #0c151b !important; }
  .viewbtn:active { color: #0c151b !important; }
  .viewbtn:focus { color: #0c151b !important; }
  .prod .links a.viewbtn:hover { color: #0c151b !important; }
  .prod .links a.viewbtn:active { color: #0c151b !important; }
  .prod .links a.viewbtn:focus { color: #0c151b !important; }
}
:root[data-theme="dark"] .viewbtn:hover { color: #0c151b !important; }
:root[data-theme="dark"] .viewbtn:active { color: #0c151b !important; }
:root[data-theme="dark"] .viewbtn:focus { color: #0c151b !important; }
:root[data-theme="dark"] .prod .links a.viewbtn:hover { color: #0c151b !important; }
:root[data-theme="dark"] .prod .links a.viewbtn:active { color: #0c151b !important; }
:root[data-theme="dark"] .prod .links a.viewbtn:focus { color: #0c151b !important; }
:root[data-theme="light"] .viewbtn:hover { color: #fff !important; }
:root[data-theme="light"] .viewbtn:active { color: #fff !important; }
:root[data-theme="light"] .viewbtn:focus { color: #fff !important; }
:root[data-theme="light"] .prod .links a.viewbtn:hover { color: #fff !important; }
:root[data-theme="light"] .prod .links a.viewbtn:active { color: #fff !important; }
:root[data-theme="light"] .prod .links a.viewbtn:focus { color: #fff !important; }
.prod .links a:hover { color: var(--blue) !important; text-decoration: none !important; }
.prod .links a:active { color: var(--blue) !important; text-decoration: none !important; }
.prod .links a:focus { color: var(--blue) !important; text-decoration: none !important; }
.prod .links a.sheet:hover { color: var(--ink-soft) !important; }
.prod .links a.sheet:active { color: var(--ink-soft) !important; }
.prod .links a.sheet:focus { color: var(--ink-soft) !important; }
footer.site .fcontact a:hover { color: #e4e8ec !important; }
footer.site .fcontact a:active { color: #e4e8ec !important; }
footer.site .fcontact a:focus { color: #e4e8ec !important; }
footer.site a:hover { color: #b6bec5 !important; text-decoration: none !important; }
footer.site a:active { color: #b6bec5 !important; text-decoration: none !important; }
footer.site a:focus { color: #b6bec5 !important; text-decoration: none !important; }
footer.site a:hover:hover { color: #fff !important; }
footer.site a:hover:active { color: #fff !important; }
footer.site a:hover:focus { color: #fff !important; }
footer.site .fbadge a:hover { color: #9aa3ab !important; }
footer.site .fbadge a:active { color: #9aa3ab !important; }
footer.site .fbadge a:focus { color: #9aa3ab !important; }
footer.site .fbadge a:hover:hover { color: #fff !important; }
footer.site .fbadge a:hover:active { color: #fff !important; }
footer.site .fbadge a:hover:focus { color: #fff !important; }
.vplay-btn:hover { text-decoration: none !important; color: #fff !important; }
.vplay-btn:active { text-decoration: none !important; color: #fff !important; }
.vplay-btn:focus { text-decoration: none !important; color: #fff !important; }
.vfeat-link:hover { color: var(--blue) !important; text-decoration: none !important; }
.vfeat-link:active { color: var(--blue) !important; text-decoration: none !important; }
.vfeat-link:focus { color: var(--blue) !important; text-decoration: none !important; }
.vfeat.is-dark .vfeat-link:hover { color: #9fd6ef !important; }
.vfeat.is-dark .vfeat-link:active { color: #9fd6ef !important; }
.vfeat.is-dark .vfeat-link:focus { color: #9fd6ef !important; }


/* --- contain the reveal offsets, generated by port_page.py ---
   See contain_reveal_offsets() for why this is clip and not hidden. */
.hbe-site { overflow-x: clip; }


/* --- small-screen containment, generated by port_page.py ---
   See responsive_fixes(). Desktop is untouched: every rule here is
   inside a max-width query. */
@media (max-width: 700px) {
  .hp-row > span:last-child,
  ul.hero-points li.hp-warranty > span:last-child { white-space: normal; }
}
@media (max-width: 860px) {
  /* Thumbnails are a grid sized for a desktop track and overflow
     their strip by 48px on a phone; let it fit the room there is.
     The spec tables are deliberately left alone — the design wraps
     them in .tscroll, which is overflow-x: auto with a 480px
     min-width on the table, so they are meant to be swiped. */
  ul.gal-thumbs { grid-template-columns: repeat(auto-fit, minmax(54px, 1fr)); }
}
}
