/* ==========================================================================
   NetTop - site stylesheet (nettop.app).

   Built on Kettle's stylesheet (Kettle/web, kettle.css, October 2026), itself
   the Metromedya app site family's (HeicConverter/web, heica.css): the same
   fonts, link rule, language picker, sub page heads, prose and footer, and
   Kettle's landing: one narrow column, a big headline, the app on a desktop,
   a feature grid and a dark download button. The demo (menu bar, popover,
   usage and speed test panels, export form, banners, PDF report) is NetTop's,
   drawn at the app's own points; see _dev/demo.js for where each value comes from.

   Loaded after Bootstrap 5.2.0, the one external dependency, used for nothing
   visible; everything with a look of its own is written here.
   ========================================================================== */

/* ── Fonts ───────────────────────────────────────────────
   Self hosted, licence files next to the files themselves:
   ZalandoSans-OFL.txt, ZalandoSansExpanded-OFL.txt, IBMPlexMono-OFL.txt.
   Same files and same pairing as the rest of the family: Zalando Sans for
   body copy, Zalando Sans Expanded for headings, IBM Plex Mono for labels.
   ─────────────────────────────────────────────────────── */

@font-face {
  font-family: 'Zalando Sans';
  src: url('../assets/fonts/ZalandoSans-VariableFont_wdth_wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-stretch: 75% 125%;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Zalando Sans';
  src: url('../assets/fonts/ZalandoSans-Italic-VariableFont_wdth_wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-stretch: 75% 125%;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Zalando Sans Expanded';
  src: url('../assets/fonts/ZalandoSansExpanded-VariableFont_wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Zalando Sans Expanded';
  src: url('../assets/fonts/ZalandoSansExpanded-Italic-VariableFont_wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../assets/fonts/IBMPlexMono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ── Tokens ────────────────────────────────────────────── */

:root {
  /* A cool light grey, the ground of NetTop's App Store screenshots, a touch bluer. */
  --ground: #ECEEF2;
  --raised: #ffffff;
  --raised-2: #EBEEF3;
  --ink: #0b0b0c;
  --ink-2: #3a3a3e;
  --muted: rgba(11, 11, 12, 0.66);
  --faint: rgba(11, 11, 12, 0.60);
  --rule: rgba(11, 11, 12, 0.12);
  --rule-strong: rgba(11, 11, 12, 0.26);
  --chip-bg: rgba(255, 255, 255, 0.85);
  --pill: #E6EAF0;

  --sans: 'Zalando Sans', -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI',
    'Helvetica Neue', 'Noto Sans', 'Hiragino Sans', 'Yu Gothic', 'Apple SD Gothic Neo',
    'Malgun Gothic', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;
  --font-heading: 'Zalando Sans Expanded', 'Zalando Sans', -apple-system, BlinkMacSystemFont,
    'Helvetica Neue', 'Segoe UI', 'Hiragino Sans', 'Apple SD Gothic Neo', 'PingFang SC',
    Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas,
    'Liberation Mono', monospace;

  --app-icon-size: clamp(7rem, 17vw, 9.75rem);
  --column: 900px;
  --measure: 46rem;
  --gutter: clamp(1.25rem, 5vw, 2.5rem);
  --radius: 14px;
}

/* ── Reset and base ────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
picture,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Links hold their ink and answer the pointer with a heavier rule, the way the
   whole family does. Semibold at rest; the weight never changes on hover. */
a {
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: 0.22em;
  transition: text-decoration-color 0.05s ease, text-decoration-thickness 0.05s ease;
}

/* Bootstrap styles a and a:hover and loads before this file, so every state
   is named here or its blue comes through. */
a,
a:link,
a:visited,
a:hover,
a:focus,
a:active {
  color: var(--ink);
}

a:hover,
a:focus-visible {
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}

/* Links that are already a shape of their own. */
a[aria-label],
a.icon-link,
a.skip-link,
a.footer-name,
a.publisher-link,
a.brand,
a.text-link,
a.pill-btn,
a.dark-btn,
.site-footer a,
.language-selector a,
.language-menu a {
  font-weight: inherit;
  text-decoration: none;
}

/* The publisher's name: a link, but not one the page asks anyone to press.
   No hover response, the family rule. */
a.publisher-link,
a.publisher-link:link,
a.publisher-link:visited,
a.publisher-link:hover,
a.publisher-link:focus {
  color: inherit;
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  a {
    transition: none;
  }
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 3px;
}

hr.trail {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 0;
  opacity: 1;
}

/* Moved out of sight upwards, not sideways: a page laid out right to left (Arabic) would
   widen to reach an element far to the left. */
.skip-link {
  position: absolute;
  left: 0;
  top: 0;
  transform: translateY(-110%);
  background: var(--ink);
  color: var(--ground);
  padding: 0.75rem 1.25rem;
  z-index: 10000;
}

.skip-link:focus {
  transform: none;
  color: var(--ground);
}

/* ── Layout ────────────────────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: clamp(3rem, 8vw, 5.5rem);
}

.wrap--wide {
  max-width: 72rem;
}

.wrap--flush {
  padding-block: 0;
}

/* ── Type ──────────────────────────────────────────────── */

h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2rem, 5.2vw, 3.1rem);
}

h2 {
  font-size: clamp(1.4rem, 3vw, 1.85rem);
}

h3 {
  font-size: 1.125rem;
}

p {
  margin: 0 0 1.1em;
}

p:last-child {
  margin-bottom: 0;
}

.lede {
  font-size: 1.15rem;
  color: var(--muted);
  max-width: 40rem;
  margin-top: 1rem;
}

/* ── Language selector ─────────────────────────────────────
   A <details> element, not a Bootstrap dropdown, and no flag emoji: the
   family picker. On sub pages it floats at the top right. On the front page
   it sits in the header row instead, next to Contact.
   ─────────────────────────────────────────────────────── */

.language-selector {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
}

.site-header .language-selector {
  position: relative;
  top: auto;
  right: auto;
}

.language-selector summary {
  list-style: none;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--muted);
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  white-space: nowrap;
  background: var(--chip-bg);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  transition: border-color 0.18s ease, color 0.18s ease;
}

.language-selector summary::-webkit-details-marker {
  display: none;
}

.language-selector summary:hover,
.language-selector[open] summary {
  color: var(--ink);
  border-color: var(--rule-strong);
}

.language-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 50;
  margin: 0;
  padding: 0.4rem;
  list-style: none;
  min-width: 11rem;
  background: var(--raised);
  border: 1px solid var(--rule);
  border-radius: 12px;
  box-shadow: 0 18px 44px rgba(11, 11, 12, 0.14);
}

.language-menu a {
  display: block;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  font-size: 0.92rem;
  color: var(--muted);
}

.language-menu a:hover,
.language-menu a:focus-visible {
  background: var(--raised-2);
  color: var(--ink);
}

.language-menu a[aria-current='true'] {
  color: var(--ink);
}

/* ── Store buttons ─────────────────────────────────────── */

.pill-btn,
.dark-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  border-radius: 12px;
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.pill-btn,
a.pill-btn,
a.pill-btn:hover {
  background: var(--pill);
  color: var(--ink);
  font-size: 15px;
  padding: 11px 18px;
}

a.pill-btn:hover {
  background: #e6e6e9;
}

.dark-btn,
a.dark-btn,
a.dark-btn:link,
a.dark-btn:visited,
a.dark-btn:hover {
  background: var(--ink);
  color: #ffffff;
  font-size: 17px;
  padding: 16px 26px;
  box-shadow: 0 14px 30px -10px rgba(0, 0, 0, 0.45);
}

a.dark-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 18px 34px -10px rgba(0, 0, 0, 0.5);
}

/* Apple's App Store badge at the family's size (HeicConverter, Faster), and the tour button
   beside it at the same height and corner, so the two read as one pair. */
.hero-actions,
.packshot {
  --cta-h: clamp(56px, 8vw, 76px);
}

.store-badge {
  display: inline-block;
  line-height: 0;
  border-radius: calc(var(--cta-h, 56px) * 0.22);
  transition: transform 0.15s ease;
}

.store-badge img {
  height: var(--cta-h, 56px);
  width: auto;
}

a.store-badge:hover {
  transform: translateY(-1px);
}

a.store-badge:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.store-pending .store-badge {
  opacity: 0.55;
  cursor: default;
}

/* The hero's two calls: download, and the tour that plays the story on its own. */
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 12px 14px;
}

.tour-btn,
a.tour-btn,
a.tour-btn:link,
a.tour-btn:visited {
  /* The app's paywall button, "Start Using Pro" on the thank-you screen (Paywall.swift,
     PaywallAccentButton with PaywallElectricEffect): the icon's navy, nearly flat with a
     slight lift at the top, a faint turquoise top edge and glow, a spark running round the
     edge and a sheen crossing it every few seconds; the label alone, system font,
     semibold, white. BrandColor: navy #001080, navyLight (navy 18% toward electric #3070E0)
     #092191, glow #88D8F8. Its corner is continuous, as SwiftUI's .continuous: site.js
     draws the shape and masks each layer with it, the corner as wide as the App Store
     badge's beside it (data-continuous, a share of the height). */
  --glow: 136, 216, 248;
  /* The app's button is 47 pt tall; its line widths, blur, shadow and sheen grow with
     this one's height, so it is that button enlarged. */
  --u: calc(var(--cta-h) / 47);
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--cta-h);
  /* As wide as the badge (119.664 x 40), so the two make one pair. */
  min-width: calc(var(--cta-h) * 2.9916);
  padding: 0 calc(var(--cta-h) * 0.4);
  border-radius: calc(var(--cta-h) * 0.2384);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', var(--sans);
  font-size: calc(var(--u) * 16);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: #fff;
  text-decoration: none;
  transition: transform 0.15s ease;
  animation: tour-spark 2.6s linear infinite;
}

a.tour-btn:hover { transform: translateY(-1px); }

a.tour-btn:focus-visible {
  outline: 2px solid #001080;
  outline-offset: 3px;
}

.tour-label { position: relative; }

.tour-fx,
.tour-fx span {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.tour-fx { z-index: -1; }

/* Each layer takes the shape from site.js (--sq-*); until then, or with no script, a plain
   rounded fill and no spark. */
.tour-fill,
.tour-sheen {
  -webkit-mask: var(--sq-fill) 0 0 / 100% 100% no-repeat;
  mask: var(--sq-fill) 0 0 / 100% 100% no-repeat;
}

/* A mask does not keep the sheen's band out of the page's scroll width; this does. */
.tour-sheen { overflow: hidden; border-radius: inherit; }

.tour-btn:not(.is-continuous) .tour-fill { border-radius: inherit; }
.tour-btn:not(.is-continuous) :is(.tour-edge, .tour-halo, .tour-spark) { display: none; }

/* SwiftUI .shadow(glow 15%, radius 10, y 4) on the fill and its edge. */
.tour-body { filter: drop-shadow(0 calc(var(--u) * 4) calc(var(--u) * 10) rgba(var(--glow), 0.15)); border-radius: inherit; }
.tour-fill {
  /* The icon's globe: deep navy turning to electric blue where its light is, and the
     stars on it, a fixed scatter of white and glow dots (one tile, 240 x 96) in two
     depths. The stars move with the pointer (site.js sets --px and --py, -1 to 1), the
     near ones more than the far ones, a parallax. */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='96'%3E%3Ccircle cx='132.5' cy='32.9' r='1.0' fill='%23fff' fill-opacity='0.81'/%3E%3Ccircle cx='209.1' cy='10.0' r='0.8' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='238.5' cy='51.5' r='0.7' fill='%23fff' fill-opacity='0.64'/%3E%3Ccircle cx='143.2' cy='14.8' r='0.6' fill='%2388d8f8' fill-opacity='0.47'/%3E%3Ccircle cx='25.2' cy='1.1' r='1.2' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='186.2' cy='10.0' r='1.2' fill='%2388d8f8' fill-opacity='0.78'/%3E%3Ccircle cx='78.3' cy='60.4' r='0.7' fill='%23fff' fill-opacity='0.42'/%3E%3Ccircle cx='48.9' cy='39.5' r='0.8' fill='%23fff' fill-opacity='0.58'/%3E%3Ccircle cx='115.1' cy='78.7' r='1.2' fill='%23fff' fill-opacity='0.52'/%3E%3Ccircle cx='14.8' cy='92.6' r='1.2' fill='%2388d8f8' fill-opacity='0.34'/%3E%3Ccircle cx='164.1' cy='18.7' r='0.8' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='127.2' cy='17.9' r='0.45' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='7.5' cy='81.4' r='0.55' fill='%2388d8f8' fill-opacity='0.81'/%3E%3Ccircle cx='196.3' cy='3.6' r='0.55' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='1.1' cy='13.9' r='1.0' fill='%23fff' fill-opacity='0.51'/%3E%3Ccircle cx='114.2' cy='34.5' r='1.0' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='237.8' cy='24.8' r='1.2' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='87.7' cy='85.3' r='0.55' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='51.1' cy='52.6' r='0.55' fill='%2388d8f8' fill-opacity='0.32'/%3E%3Ccircle cx='27.9' cy='29.3' r='0.8' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='73.3' cy='2.2' r='0.6' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='118.5' cy='32.6' r='0.8' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='6.8' cy='80.4' r='0.6' fill='%23fff' fill-opacity='0.46'/%3E%3Ccircle cx='90.6' cy='64.6' r='0.7' fill='%23fff' fill-opacity='0.44'/%3E%3Ccircle cx='189.0' cy='10.4' r='0.6' fill='%23fff' fill-opacity='0.45'/%3E%3Ccircle cx='130.3' cy='23.0' r='1.2' fill='%23fff' fill-opacity='0.36'/%3E%3Ccircle cx='147.6' cy='33.9' r='0.8' fill='%23fff' fill-opacity='0.71'/%3E%3Ccircle cx='142.7' cy='66.3' r='0.6' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='66.2' cy='2.5' r='1.0' fill='%2388d8f8' fill-opacity='0.46'/%3E%3Ccircle cx='103.0' cy='23.3' r='1.0' fill='%23fff' fill-opacity='0.4'/%3E%3Ccircle cx='166.6' cy='69.5' r='0.7' fill='%2388d8f8' fill-opacity='0.52'/%3E%3Ccircle cx='93.7' cy='13.5' r='0.45' fill='%23fff' fill-opacity='0.43'/%3E%3Ccircle cx='45.2' cy='12.3' r='0.45' fill='%23fff' fill-opacity='0.74'/%3E%3Ccircle cx='29.3' cy='39.7' r='1.0' fill='%23fff' fill-opacity='0.82'/%3E%3Ccircle cx='82.0' cy='74.2' r='0.45' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='207.8' cy='87.2' r='1.0' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='222.0' cy='75.5' r='0.7' fill='%2388d8f8' fill-opacity='0.59'/%3E%3Ccircle cx='52.2' cy='74.9' r='1.0' fill='%2388d8f8' fill-opacity='0.44'/%3E%3Ccircle cx='63.8' cy='28.0' r='0.7' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='136.1' cy='3.9' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='36.3' cy='50.5' r='0.45' fill='%23fff' fill-opacity='0.59'/%3E%3Ccircle cx='135.9' cy='20.1' r='0.45' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='139.3' cy='41.6' r='0.45' fill='%2388d8f8' fill-opacity='0.43'/%3E%3Ccircle cx='203.1' cy='11.6' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='1.2' cy='93.9' r='0.55' fill='%23fff' fill-opacity='0.5'/%3E%3Ccircle cx='182.2' cy='45.1' r='0.6' fill='%23fff' fill-opacity='0.66'/%3E%3C/svg%3E") calc(var(--px, 0) * var(--u) * 9) calc(var(--py, 0) * var(--u) * 6) / calc(var(--u) * 149) auto repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='96'%3E%3Ccircle cx='132.5' cy='32.9' r='1.0' fill='%23fff' fill-opacity='0.81'/%3E%3Ccircle cx='209.1' cy='10.0' r='0.8' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='238.5' cy='51.5' r='0.7' fill='%23fff' fill-opacity='0.64'/%3E%3Ccircle cx='143.2' cy='14.8' r='0.6' fill='%2388d8f8' fill-opacity='0.47'/%3E%3Ccircle cx='25.2' cy='1.1' r='1.2' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='186.2' cy='10.0' r='1.2' fill='%2388d8f8' fill-opacity='0.78'/%3E%3Ccircle cx='78.3' cy='60.4' r='0.7' fill='%23fff' fill-opacity='0.42'/%3E%3Ccircle cx='48.9' cy='39.5' r='0.8' fill='%23fff' fill-opacity='0.58'/%3E%3Ccircle cx='115.1' cy='78.7' r='1.2' fill='%23fff' fill-opacity='0.52'/%3E%3Ccircle cx='14.8' cy='92.6' r='1.2' fill='%2388d8f8' fill-opacity='0.34'/%3E%3Ccircle cx='164.1' cy='18.7' r='0.8' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='127.2' cy='17.9' r='0.45' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='7.5' cy='81.4' r='0.55' fill='%2388d8f8' fill-opacity='0.81'/%3E%3Ccircle cx='196.3' cy='3.6' r='0.55' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='1.1' cy='13.9' r='1.0' fill='%23fff' fill-opacity='0.51'/%3E%3Ccircle cx='114.2' cy='34.5' r='1.0' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='237.8' cy='24.8' r='1.2' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='87.7' cy='85.3' r='0.55' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='51.1' cy='52.6' r='0.55' fill='%2388d8f8' fill-opacity='0.32'/%3E%3Ccircle cx='27.9' cy='29.3' r='0.8' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='73.3' cy='2.2' r='0.6' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='118.5' cy='32.6' r='0.8' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='6.8' cy='80.4' r='0.6' fill='%23fff' fill-opacity='0.46'/%3E%3Ccircle cx='90.6' cy='64.6' r='0.7' fill='%23fff' fill-opacity='0.44'/%3E%3Ccircle cx='189.0' cy='10.4' r='0.6' fill='%23fff' fill-opacity='0.45'/%3E%3Ccircle cx='130.3' cy='23.0' r='1.2' fill='%23fff' fill-opacity='0.36'/%3E%3Ccircle cx='147.6' cy='33.9' r='0.8' fill='%23fff' fill-opacity='0.71'/%3E%3Ccircle cx='142.7' cy='66.3' r='0.6' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='66.2' cy='2.5' r='1.0' fill='%2388d8f8' fill-opacity='0.46'/%3E%3Ccircle cx='103.0' cy='23.3' r='1.0' fill='%23fff' fill-opacity='0.4'/%3E%3Ccircle cx='166.6' cy='69.5' r='0.7' fill='%2388d8f8' fill-opacity='0.52'/%3E%3Ccircle cx='93.7' cy='13.5' r='0.45' fill='%23fff' fill-opacity='0.43'/%3E%3Ccircle cx='45.2' cy='12.3' r='0.45' fill='%23fff' fill-opacity='0.74'/%3E%3Ccircle cx='29.3' cy='39.7' r='1.0' fill='%23fff' fill-opacity='0.82'/%3E%3Ccircle cx='82.0' cy='74.2' r='0.45' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='207.8' cy='87.2' r='1.0' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='222.0' cy='75.5' r='0.7' fill='%2388d8f8' fill-opacity='0.59'/%3E%3Ccircle cx='52.2' cy='74.9' r='1.0' fill='%2388d8f8' fill-opacity='0.44'/%3E%3Ccircle cx='63.8' cy='28.0' r='0.7' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='136.1' cy='3.9' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='36.3' cy='50.5' r='0.45' fill='%23fff' fill-opacity='0.59'/%3E%3Ccircle cx='135.9' cy='20.1' r='0.45' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='139.3' cy='41.6' r='0.45' fill='%2388d8f8' fill-opacity='0.43'/%3E%3Ccircle cx='203.1' cy='11.6' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='1.2' cy='93.9' r='0.55' fill='%23fff' fill-opacity='0.5'/%3E%3Ccircle cx='182.2' cy='45.1' r='0.6' fill='%23fff' fill-opacity='0.66'/%3E%3C/svg%3E") calc(37px + var(--px, 0) * var(--u) * 3.5) calc(23px + var(--py, 0) * var(--u) * 2.5) / calc(var(--u) * 96) auto repeat,
    radial-gradient(120% 150% at 72% 125%, #3070E0 0%, #1A4CC8 32%, #0A2496 62%, #001080 88%);
}

.tour-edge {
  background: linear-gradient(rgba(var(--glow), 0.45), rgba(var(--glow), 0) 50%);
  -webkit-mask: var(--sq-ring1) 0 0 / 100% 100% no-repeat;
  mask: var(--sq-ring1) 0 0 / 100% 100% no-repeat;
}

/* The spark: bright for a short stretch of the edge, fading out on both sides; a 1.5 pt
   line inside the edge and a 5 pt one blurred by 5 pt at 90%. One lap in 2.6 s. */
@property --spark {
  syntax: '<angle>';
  inherits: true;
  initial-value: 0deg;
}

@keyframes tour-spark { to { --spark: 360deg; } }

.tour-spark,
.tour-halo > span {
  background: conic-gradient(from calc(var(--spark) + 90deg),
    rgba(var(--glow), 0) 0, rgba(var(--glow), 0) 62%, rgba(var(--glow), 0.8) 80%,
    #fff 86%, rgba(var(--glow), 0.8) 90%, rgba(var(--glow), 0) 100%);
}

.tour-spark {
  -webkit-mask: var(--sq-ring15) 0 0 / 100% 100% no-repeat;
  mask: var(--sq-ring15) 0 0 / 100% 100% no-repeat;
}

.tour-halo { filter: blur(calc(var(--u) * 5)); opacity: 0.9; }

.tour-halo > span {
  -webkit-mask: var(--sq-ring5) 0 0 / 100% 100% no-repeat;
  mask: var(--sq-ring5) 0 0 / 100% 100% no-repeat;
}

/* The sheen: a 70 pt band, white at 22% in the middle, tilted 18 degrees, crosses in 0.9 s
   every 3.4 s. */
.tour-sheen::before {
  content: "";
  position: absolute;
  top: -50%;
  left: calc(var(--u) * -70);
  width: calc(var(--u) * 70);
  height: 200%;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0));
  transform: rotate(18deg);
  animation: tour-sheen 3.4s linear infinite;
}

@keyframes tour-sheen {
  0% { left: calc(var(--u) * -70); opacity: 1; }
  26.4% { left: calc(100% + var(--u) * 70); opacity: 1; }
  26.5%, 100% { left: calc(100% + var(--u) * 70); opacity: 0; }
}

/* Still under Reduce Motion, as in the app: the spark where it is 0.6 s into its lap, no
   sheen. */
@media (prefers-reduced-motion: reduce) {
  .tour-btn { animation: none; --spark: 83deg; }
  .tour-sheen::before { animation: none; opacity: 0; }
}

.apple {
  width: 15px;
  height: 18px;
  fill: currentColor;
  flex: none;
}

/* No Mac App Store record yet: the button is shown, not linked, and says so.
   Same treatment as the family's pending badge. */
.store-pending {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.packshot .store-pending {
  align-items: center;
}

.store-pending .dark-btn,
.pill-btn--pending {
  opacity: 0.55;
  cursor: default;
}

.store-pending-note {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}

.pending {
  color: var(--faint);
  border-bottom: 1px dashed var(--rule-strong);
}

/* ── Front page: header ────────────────────────────────── */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 28px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.02em;
}

/* Named with its element so it outranks the link exemption list above,
   which resets link weight to inherit. */
.site-header a.brand {
  font-weight: 700;
}

.brand img {
  width: 34px;
  height: 34px;
}

.header-nav {
  display: flex;
  align-items: center;
  gap: 20px;
}

.text-link {
  font-weight: 600;
  font-size: 15px;
}

a.text-link:hover {
  opacity: 0.6;
}

/* ── Front page: hero ──────────────────────────────────── */

.hero {
  max-width: var(--column);
  margin: 0 auto;
  padding: clamp(4.5rem, 9vw, 6.5rem) 28px 56px;
  text-align: center;
}

/* The sub pages' icon, at their size, above the headline. */
.hero-icon {
  display: block;
  width: var(--app-icon-size);
  margin: 0 auto 1.5rem;
}

/* The tour button's look on the icon, on hover: stars on its globe in two depths that
   follow the pointer over the icon (site.js, --px and --py), and Faster's spectrum rim
   round its edge (below). */
/* The icon grows a little under the pointer: the picture, its stars and the rim, each
   scaled about the icon's centre so the rim stays on the edge. Not the whole
   .hero-icon: a transform there would isolate the rim's plus-lighter blend from the
   page, and its glow would stop lighting the ground round the icon. */
.hero-icon {
  --grow: 1.06;
  --grow-ease: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.hero-icon img { position: relative; transition: var(--grow-ease); }
.hero-icon:hover img { transform: scale(var(--grow)); }

.hero-stars {
  position: absolute;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s ease, transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  /* On the globe only: the round area of the icon (512 px icon: centre 258, 250, about
     410 across), its edge faded, white and glow stars as on the button. */
  z-index: 1;
  left: 10.4%;
  top: 9%;
  width: 80%;
  height: 80%;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='96'%3E%3Ccircle cx='132.5' cy='32.9' r='1.0' fill='%23fff' fill-opacity='0.81'/%3E%3Ccircle cx='209.1' cy='10.0' r='0.8' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='238.5' cy='51.5' r='0.7' fill='%23fff' fill-opacity='0.64'/%3E%3Ccircle cx='143.2' cy='14.8' r='0.6' fill='%2388d8f8' fill-opacity='0.47'/%3E%3Ccircle cx='25.2' cy='1.1' r='1.2' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='186.2' cy='10.0' r='1.2' fill='%2388d8f8' fill-opacity='0.78'/%3E%3Ccircle cx='78.3' cy='60.4' r='0.7' fill='%23fff' fill-opacity='0.42'/%3E%3Ccircle cx='48.9' cy='39.5' r='0.8' fill='%23fff' fill-opacity='0.58'/%3E%3Ccircle cx='115.1' cy='78.7' r='1.2' fill='%23fff' fill-opacity='0.52'/%3E%3Ccircle cx='14.8' cy='92.6' r='1.2' fill='%2388d8f8' fill-opacity='0.34'/%3E%3Ccircle cx='164.1' cy='18.7' r='0.8' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='127.2' cy='17.9' r='0.45' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='7.5' cy='81.4' r='0.55' fill='%2388d8f8' fill-opacity='0.81'/%3E%3Ccircle cx='196.3' cy='3.6' r='0.55' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='1.1' cy='13.9' r='1.0' fill='%23fff' fill-opacity='0.51'/%3E%3Ccircle cx='114.2' cy='34.5' r='1.0' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='237.8' cy='24.8' r='1.2' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='87.7' cy='85.3' r='0.55' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='51.1' cy='52.6' r='0.55' fill='%2388d8f8' fill-opacity='0.32'/%3E%3Ccircle cx='27.9' cy='29.3' r='0.8' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='73.3' cy='2.2' r='0.6' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='118.5' cy='32.6' r='0.8' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='6.8' cy='80.4' r='0.6' fill='%23fff' fill-opacity='0.46'/%3E%3Ccircle cx='90.6' cy='64.6' r='0.7' fill='%23fff' fill-opacity='0.44'/%3E%3Ccircle cx='189.0' cy='10.4' r='0.6' fill='%23fff' fill-opacity='0.45'/%3E%3Ccircle cx='130.3' cy='23.0' r='1.2' fill='%23fff' fill-opacity='0.36'/%3E%3Ccircle cx='147.6' cy='33.9' r='0.8' fill='%23fff' fill-opacity='0.71'/%3E%3Ccircle cx='142.7' cy='66.3' r='0.6' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='66.2' cy='2.5' r='1.0' fill='%2388d8f8' fill-opacity='0.46'/%3E%3Ccircle cx='103.0' cy='23.3' r='1.0' fill='%23fff' fill-opacity='0.4'/%3E%3Ccircle cx='166.6' cy='69.5' r='0.7' fill='%2388d8f8' fill-opacity='0.52'/%3E%3Ccircle cx='93.7' cy='13.5' r='0.45' fill='%23fff' fill-opacity='0.43'/%3E%3Ccircle cx='45.2' cy='12.3' r='0.45' fill='%23fff' fill-opacity='0.74'/%3E%3Ccircle cx='29.3' cy='39.7' r='1.0' fill='%23fff' fill-opacity='0.82'/%3E%3Ccircle cx='82.0' cy='74.2' r='0.45' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='207.8' cy='87.2' r='1.0' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='222.0' cy='75.5' r='0.7' fill='%2388d8f8' fill-opacity='0.59'/%3E%3Ccircle cx='52.2' cy='74.9' r='1.0' fill='%2388d8f8' fill-opacity='0.44'/%3E%3Ccircle cx='63.8' cy='28.0' r='0.7' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='136.1' cy='3.9' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='36.3' cy='50.5' r='0.45' fill='%23fff' fill-opacity='0.59'/%3E%3Ccircle cx='135.9' cy='20.1' r='0.45' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='139.3' cy='41.6' r='0.45' fill='%2388d8f8' fill-opacity='0.43'/%3E%3Ccircle cx='203.1' cy='11.6' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='1.2' cy='93.9' r='0.55' fill='%23fff' fill-opacity='0.5'/%3E%3Ccircle cx='182.2' cy='45.1' r='0.6' fill='%23fff' fill-opacity='0.66'/%3E%3C/svg%3E") calc(var(--px, 0) * 10px) calc(var(--py, 0) * 10px) / 110px auto repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='96'%3E%3Ccircle cx='132.5' cy='32.9' r='1.0' fill='%23fff' fill-opacity='0.81'/%3E%3Ccircle cx='209.1' cy='10.0' r='0.8' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='238.5' cy='51.5' r='0.7' fill='%23fff' fill-opacity='0.64'/%3E%3Ccircle cx='143.2' cy='14.8' r='0.6' fill='%2388d8f8' fill-opacity='0.47'/%3E%3Ccircle cx='25.2' cy='1.1' r='1.2' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='186.2' cy='10.0' r='1.2' fill='%2388d8f8' fill-opacity='0.78'/%3E%3Ccircle cx='78.3' cy='60.4' r='0.7' fill='%23fff' fill-opacity='0.42'/%3E%3Ccircle cx='48.9' cy='39.5' r='0.8' fill='%23fff' fill-opacity='0.58'/%3E%3Ccircle cx='115.1' cy='78.7' r='1.2' fill='%23fff' fill-opacity='0.52'/%3E%3Ccircle cx='14.8' cy='92.6' r='1.2' fill='%2388d8f8' fill-opacity='0.34'/%3E%3Ccircle cx='164.1' cy='18.7' r='0.8' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='127.2' cy='17.9' r='0.45' fill='%23fff' fill-opacity='0.8'/%3E%3Ccircle cx='7.5' cy='81.4' r='0.55' fill='%2388d8f8' fill-opacity='0.81'/%3E%3Ccircle cx='196.3' cy='3.6' r='0.55' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='1.1' cy='13.9' r='1.0' fill='%23fff' fill-opacity='0.51'/%3E%3Ccircle cx='114.2' cy='34.5' r='1.0' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='237.8' cy='24.8' r='1.2' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='87.7' cy='85.3' r='0.55' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='51.1' cy='52.6' r='0.55' fill='%2388d8f8' fill-opacity='0.32'/%3E%3Ccircle cx='27.9' cy='29.3' r='0.8' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='73.3' cy='2.2' r='0.6' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='118.5' cy='32.6' r='0.8' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='6.8' cy='80.4' r='0.6' fill='%23fff' fill-opacity='0.46'/%3E%3Ccircle cx='90.6' cy='64.6' r='0.7' fill='%23fff' fill-opacity='0.44'/%3E%3Ccircle cx='189.0' cy='10.4' r='0.6' fill='%23fff' fill-opacity='0.45'/%3E%3Ccircle cx='130.3' cy='23.0' r='1.2' fill='%23fff' fill-opacity='0.36'/%3E%3Ccircle cx='147.6' cy='33.9' r='0.8' fill='%23fff' fill-opacity='0.71'/%3E%3Ccircle cx='142.7' cy='66.3' r='0.6' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='66.2' cy='2.5' r='1.0' fill='%2388d8f8' fill-opacity='0.46'/%3E%3Ccircle cx='103.0' cy='23.3' r='1.0' fill='%23fff' fill-opacity='0.4'/%3E%3Ccircle cx='166.6' cy='69.5' r='0.7' fill='%2388d8f8' fill-opacity='0.52'/%3E%3Ccircle cx='93.7' cy='13.5' r='0.45' fill='%23fff' fill-opacity='0.43'/%3E%3Ccircle cx='45.2' cy='12.3' r='0.45' fill='%23fff' fill-opacity='0.74'/%3E%3Ccircle cx='29.3' cy='39.7' r='1.0' fill='%23fff' fill-opacity='0.82'/%3E%3Ccircle cx='82.0' cy='74.2' r='0.45' fill='%23fff' fill-opacity='0.35'/%3E%3Ccircle cx='207.8' cy='87.2' r='1.0' fill='%23fff' fill-opacity='0.3'/%3E%3Ccircle cx='222.0' cy='75.5' r='0.7' fill='%2388d8f8' fill-opacity='0.59'/%3E%3Ccircle cx='52.2' cy='74.9' r='1.0' fill='%2388d8f8' fill-opacity='0.44'/%3E%3Ccircle cx='63.8' cy='28.0' r='0.7' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='136.1' cy='3.9' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='36.3' cy='50.5' r='0.45' fill='%23fff' fill-opacity='0.59'/%3E%3Ccircle cx='135.9' cy='20.1' r='0.45' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='139.3' cy='41.6' r='0.45' fill='%2388d8f8' fill-opacity='0.43'/%3E%3Ccircle cx='203.1' cy='11.6' r='0.6' fill='%2388d8f8' fill-opacity='0.49'/%3E%3Ccircle cx='1.2' cy='93.9' r='0.55' fill='%23fff' fill-opacity='0.5'/%3E%3Ccircle cx='182.2' cy='45.1' r='0.6' fill='%23fff' fill-opacity='0.66'/%3E%3C/svg%3E") calc(41px + var(--px, 0) * 4px) calc(29px + var(--py, 0) * 4px) / 72px auto repeat;
  -webkit-mask: radial-gradient(closest-side, #000 72%, transparent 100%);
  mask: radial-gradient(closest-side, #000 72%, transparent 100%);
  /* The icon's centre, in this box. */
  transform-origin: 49.5% 51.25%;
  transform: scale(0.97);
}

.hero-icon:hover .hero-stars { opacity: 1; transform: scale(var(--grow)); }

/* Faster's spectrum rim round the icon, on hover (rim.js, a WebGL port of the app's
   Metal shader): the canvas reaches past the icon so the bloom has room. */
.hero-icon canvas {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  /* Added as light, as the app composites its rim (plusLighter). */
  mix-blend-mode: plus-lighter;
  transition: var(--grow-ease);
}

.hero-icon:hover canvas { transform: scale(var(--grow)); }

@media (prefers-reduced-motion: reduce) {
  .hero-icon img, .hero-icon canvas, .hero-stars { transition: opacity 0.2s ease; transform: none !important; }
}

.hero .page-label { margin: 0.85rem 0 36px; }

/* Headings in Zalando Sans Expanded bold, close to the expanded system font of the app's
   title and of the App Store screenshots' headlines. */
.hero h1 {
  font-family: var(--font-heading);
  /* Two lines: sized so the longer one fits the column on a wide screen; narrower windows
     wrap it, balanced. */
  font-size: clamp(28px, 4.2vw, 48px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin: 0;
  text-wrap: balance;
}

/* ── Front page: showcase (the app on a desktop) ───────── */

.showcase {
  /* A wide desktop where the window allows it. Its contents are never scaled up: showcase.js
     keeps the panel and menu at the app's own size and widens the desktop's inside instead. */
  /* As wide as the MacBook's screen at the app's own points (1683, see showcase.js), so the
     panel shows at its own size where the window allows it. */
  max-width: 2109px;
  margin: 0 auto;
  padding: 0 28px;
}

/* A MacBook Pro 16 around the desktop. The frame image (3407 x 2080) is drawn over the
   desktop; its screen opening starts 310 x 44 in and is 2787 x 1804. The desktop reaches 3px
   under the bezel on every side so no seam shows. */
.mac {
  position: relative;
  aspect-ratio: 3407 / 2080;
}

.mac::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/images/macbook-frame.webp") 0 0 / 100% 100% no-repeat;
  pointer-events: none;
}

.desktop {
  position: absolute;
  left: 9.011%;
  top: 1.971%;
  width: 81.978%;
  height: 87.019%;
  overflow: hidden;
  background: var(--night-wallpaper);
}

.menubar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  /* As tall as the MacBook picture's notch (showcase.js sets --mb-h from it), as on a
     notched Mac; 32 where there is no frame (the static steps). */
  height: var(--mb-h, 32px);
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #ffffff;
  font-size: 13px;
  font-weight: 600;
  /* A fixed translucent tint per theme rather than a backdrop blur: browsers
     repaint a backdrop late, so a theme switch left the bar in the old colour. */
  background: rgba(255, 255, 255, 0.12);
}

.menubar .apple {
  width: 13px;
  height: 15px;
}

.mb-right {
  display: inline-flex;
  align-items: center;
  gap: 18px;
}

/* The status item is lit while the popover is open, as on macOS. */
.mb-nt {
  padding: 0 6px;
  border-radius: 5px;
  transition: background-color 0.12s ease-out;
}

.is-open .mb-nt,
.screen.is-open .mb-nt {
  background: rgba(255, 255, 255, 0.22);
}

/* ── Front page: feature grid ──────────────────────────── */

/* After the story: a line that says the story was only part of it, over the feature
   grid, then the download badge at the very end. */
.features-head {
  max-width: var(--column);
  margin: 88px auto 0;
  padding: 0 28px;
  text-align: center;
}
.features-head h2 {
  font-family: var(--font-heading);
  font-size: clamp(30px, 4.2vw, 52px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 0;
  text-wrap: balance;
}
.features-head + .features { margin-top: 56px; }

.download-cta {
  max-width: var(--column);
  margin: 96px auto 112px;
  padding: 0 28px;
  text-align: center;
}

.download-cta h2 {
  font-family: var(--font-heading);
  font-size: clamp(26px, 3.4vw, 38px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin: 0 0 28px;
  text-wrap: balance;
}

.features {
  max-width: var(--column);
  margin: 96px auto 0;
  padding: 0 28px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  row-gap: 56px;
  column-gap: 24px;
  text-align: center;
}

.feature-icon svg {
  width: 40px;
  height: 40px;
  margin: 0 auto;
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.feature h3 {
  font-family: var(--font-heading);
  margin: 14px 0 0;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.01em;
  text-wrap: initial;
}

.soon {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  background: var(--pill);
  border-radius: 999px;
  padding: 2px 10px;
}

/* ── Front page: footer ────────────────────────────────── */

.site-footer {
  text-align: center;
  padding: 0 28px 64px;
  color: var(--muted);
}

.site-footer .heart {
  width: 18px;
  height: 18px;
  margin: 0 auto 4px;
  fill: #8a8a90;
}

.site-footer p {
  margin: 4px 0;
}

.site-footer .made {
  font-weight: 700;
  color: #6e6e74;
  font-size: 16px;
}

.site-footer .sub,
.site-footer .copyright {
  font-size: 14px;
}

.site-footer .copyright {
  margin-top: 18px;
  color: var(--faint);
}

.site-footer .links,
.site-footer .langs {
  font-size: 14px;
  margin-top: 14px;
}

.site-footer a {
  color: #6e6e74;
  font-weight: 600;
}

.site-footer a:hover {
  color: var(--ink);
}

.site-footer .made a.publisher-link {
  font-weight: 700;
}

.site-footer .dot {
  margin: 0 8px;
}

.lang-current {
  color: var(--ink);
  font-weight: 600;
}

/* ── Sub pages: head and prose (the family's) ──────────── */

.app-icon {
  position: relative;
  display: block;
  width: var(--app-icon-size);
  line-height: 0;
}

.app-icon img {
  display: block;
  width: 100%;
  height: auto;
}

.subhead {
  text-align: center;
  padding-top: clamp(4.5rem, 9vw, 6.5rem);
  padding-bottom: 2rem;
}

.subhead-icon {
  display: block;
  width: var(--app-icon-size);
  margin: 0 auto 1.5rem;
}

.page-label {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  margin-top: 0.85rem;
}

.prose h2 {
  margin-top: 2.75rem;
  margin-bottom: 0.85rem;
}

.prose h3 {
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
}

.prose p,
.prose li {
  color: var(--muted);
}

.prose ul {
  margin: 0 0 1.1em;
  padding-left: 1.2rem;
}

.prose li {
  margin-bottom: 0.4rem;
}

.prose strong {
  color: var(--ink);
}

.faq-item {
  padding: 1.35rem 0;
  border-bottom: 1px solid var(--rule);
}

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

.faq-item h3 {
  margin: 0 0 0.5rem;
}

.faq-item p {
  color: var(--muted);
  margin: 0;
}

.faq-item ul {
  margin: 0.6rem 0 0;
}

.faq-item ul + p {
  margin-top: 0.6rem;
}

/* ── Sub pages: footer (the family's) ──────────────────── */

footer.family-footer {
  padding-bottom: 3rem;
}

.footer-inner {
  /* Three columns with equal sides, so the app name sits at the true centre
     whatever the widths of the copyright line and the links. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.5rem;
  padding-top: 2.5rem;
}
.footer-inner > p { justify-self: start; }
.footer-inner > .footer-name { justify-self: center; }
.footer-inner > .footer-nav { justify-self: end; }

.footer-inner p {
  margin: 0;
  color: var(--faint);
  font-size: 0.78rem;
}

.footer-name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.02em;
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-nav a {
  color: var(--faint);
  font-size: 0.78rem;
}

.footer-nav a:hover,
.footer-nav a:focus-visible {
  color: var(--ink);
}

/* ── Responsive ────────────────────────────────────────── */

@media (max-width: 820px) {
  .features {
    grid-template-columns: repeat(2, 1fr);
  }

  .header-nav .text-link {
    display: none;
  }

  .footer-inner {
    grid-template-columns: 1fr;
  }
  .footer-inner > p,
  .footer-inner > .footer-name,
  .footer-inner > .footer-nav { justify-self: start; }
}

@media (max-width: 480px) {
  .site-header {
    padding: 16px 18px;
  }

  .header-nav {
    gap: 10px;
  }

  /* The header carries the brand, the picker and the store pill. At phone
     width the pill gives way; the hero's own button is right below. */
  .header-nav .pill-btn {
    display: none;
  }

  .hero,
  .features,
  .showcase {
    padding-inline: 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* A jump (load, refresh mid story, resize) is placed without transitions; showcase.js. */
.story.is-still .screen,
.story.is-still .screen *,
.story.is-still .phone,
.story.is-still .phone-link,
.story.is-still .phone-link *,
.story.is-still .phone-rim { transition: none !important; }

/* ── The iPhone of the hotspot steps ───────────────────────
   It stands in front of the Mac, over the empty left of the desktop (the popover is on
   the right), at a fifth of the Mac's width, its foot on the table a little in front of
   the Mac's. On the hotspot steps (.story.is-phone, showcase.js) it rises in; Bluetooth
   finds it (two rings); the link draws from it to the menu bar's hotspot icon with data
   flowing along (.is-linked); the clock gets iOS's blue capsule. */

.phone {
  position: absolute;
  left: 2.6%;
  bottom: -1.6%;
  z-index: 3;
  width: 20%;
  aspect-ratio: 430 / 882;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(18%);
  filter: drop-shadow(0 18px 22px rgba(0, 0, 0, 0.32)) drop-shadow(0 3px 5px rgba(0, 0, 0, 0.25));
  transition: opacity 0.3s ease, transform 0.5s cubic-bezier(0.4, 0, 1, 1), visibility 0s 0.5s;
}

.story.is-phone .phone {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.35s ease, transform 0.8s var(--spring), visibility 0s;
}

.phone-body {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The screen: 402 x 862 points, 10 of 430 units in from the body's edges (the viewBox
   carries 4 units each side for the buttons). showcase.js sets --ps, the points' scale. */
.phone-screen {
  position: absolute;
  left: calc(14 / 430 * 100%);
  top: calc(10 / 882 * 100%);
  width: calc(402 / 430 * 100%);
  height: calc(862 / 882 * 100%);
  overflow: hidden;
  -webkit-mask: var(--mask) 0 0 / 100% 100% no-repeat;
  mask: var(--mask) 0 0 / 100% 100% no-repeat;
}

.phone-ui {
  --ios-bg: #000000; --ios-cell: #1c1c1e; --ios-ink: #ffffff; --ios-2nd: rgba(235, 235, 245, 0.6);
  --ios-sep: rgba(84, 84, 88, 0.6); --ios-blue: #0A84FF; --ios-green: #30D158; --ios-off: rgba(120, 120, 128, 0.32);
  position: absolute;
  left: 0;
  top: 0;
  width: 402px;
  height: 862px;
  transform: scale(var(--ps, 0.5));
  transform-origin: 0 0;
  background: var(--ios-bg);
  color: var(--ios-ink);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
  font-size: 17px;
  letter-spacing: -0.02em;
}

.ios-status {
  position: relative;
  height: 54px;
}

.ios-island {
  position: absolute;
  left: 138px;
  top: 11px;
  width: 126px;
  height: 37px;
  border-radius: 999px;   /* capsules stay round: site.js leaves 999px alone */
  background: #000;
}

.ios-time {
  position: absolute;
  left: 32px;
  top: 14px;
  width: 78px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-size: 17px;
  font-weight: 600;
  transition: background-color 0.35s ease, color 0.35s ease;
}

/* Personal Hotspot in use: iOS's blue capsule round the clock; the link leaves from it. */
.story.is-linked .ios-time {
  background: var(--ios-blue);
  color: #fff;
  transition-delay: 0.85s;
}

.ios-right {
  position: absolute;
  right: 30px;
  top: 20px;
  display: flex;
  align-items: center;
  gap: 6px;
  fill: currentColor;
}

.ios-signal { width: 18px; height: 12px; }
.ios-battery { width: 27px; height: 13px; }
.ios-5g { font-size: 15px; font-weight: 600; letter-spacing: 0; }

.ios-nav {
  position: relative;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ios-nav b { font-weight: 600; }

.ios-back {
  position: absolute;
  left: 10px;
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--ios-blue);
}

.ios-chev { width: 12px; height: 21px; }

.ios-group {
  margin: 18px 16px 0;
  border-radius: 12px;
  background: var(--ios-cell);
  overflow: hidden;
}

.ios-row {
  position: relative;
  height: 52px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ios-row + .ios-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 0;
  height: 0.5px;
  background: var(--ios-sep);
}

.ios-value {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ios-2nd);
}

.ios-chev-r { width: 8px; height: 14px; opacity: 0.6; }

.ios-toggle {
  position: relative;
  width: 51px;
  height: 31px;
  border-radius: 999px;
  background: var(--ios-green);
}

.ios-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  right: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), 0 1px 1px rgba(0, 0, 0, 0.16);
}

.ios-toggle.is-off { background: var(--ios-off); }
.ios-toggle.is-off::after { right: auto; left: 2px; }

.ios-foot {
  margin: 8px 32px 0;
  font-size: 13px;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ios-2nd);
}

.ios-home {
  position: absolute;
  left: 134px;
  bottom: 8px;
  width: 134px;
  height: 5px;
  border-radius: 999px;
  background: var(--ios-ink);
}

/* Bluetooth finds the iPhone: two rings out from it, once, as it settles. */
.phone-pulse {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 150%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 2px solid rgba(136, 216, 248, 0.9);
  box-shadow: 0 0 18px rgba(136, 216, 248, 0.55), inset 0 0 18px rgba(136, 216, 248, 0.35);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.4);
}

.story.is-phone .phone-pulse { animation: phone-pulse 1.25s cubic-bezier(0.2, 0.7, 0.3, 1) 0.55s 1 both; }
.story.is-phone .phone-pulse + .phone-pulse { animation-delay: 0.85s; }

@keyframes phone-pulse {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.25); }
}

/* The link in light: Faster's spectrum rim (rim.js, setupLinkRim) on a rounded box laid on
   the Mac's bezel, masked down to its two runs: up the left side from behind the iPhone
   (revealed bottom up), then along the top to the hotspot icon (left to right), each run
   with a soft end. Added to the page as light, as the icon's rim. The dotted line below
   stays only where WebGL is missing (no .has-rim-link). */
@property --rv1 { syntax: '<number>'; inherits: false; initial-value: 0; }
@property --rv2 { syntax: '<number>'; inherits: false; initial-value: 0; }
@property --rv3 { syntax: '<number>'; inherits: false; initial-value: 0; }

.phone-rim {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: plus-lighter;
  --rv1: 0;
  --rv2: 0;
  --rv3: 0;
  -webkit-mask:
    linear-gradient(transparent, #000 18px) 0 calc(var(--lh, 0px) * (1 - var(--rv1))) / var(--lw, 0px) calc(var(--lh, 0px) * var(--rv1)) no-repeat,
    linear-gradient(90deg, #000 calc(100% - 18px), transparent) 0 0 / calc(var(--tw, 0px) * var(--rv2)) var(--th, 0px) no-repeat,
    linear-gradient(#000 calc(100% - 5px), transparent) var(--rx, 0px) 0 / var(--rw, 0px) calc(var(--rh, 0px) * var(--rv3)) no-repeat;
  mask:
    linear-gradient(transparent, #000 18px) 0 calc(var(--lh, 0px) * (1 - var(--rv1))) / var(--lw, 0px) calc(var(--lh, 0px) * var(--rv1)) no-repeat,
    linear-gradient(90deg, #000 calc(100% - 18px), transparent) 0 0 / calc(var(--tw, 0px) * var(--rv2)) var(--th, 0px) no-repeat,
    linear-gradient(#000 calc(100% - 5px), transparent) var(--rx, 0px) 0 / var(--rw, 0px) calc(var(--rh, 0px) * var(--rv3)) no-repeat;
  transition: --rv1 0.25s ease, --rv2 0.25s ease, --rv3 0.25s ease;
}

/* Up from the phone, along the top (the top run ends soft until the drop comes in), then
   down into the hotspot icon. */
.story.is-linked .phone-rim {
  --rv1: 1;
  --rv2: 1;
  --rv3: 1;
  transition: --rv1 0.5s cubic-bezier(0.5, 0, 0.3, 1) 1.3s, --rv2 0.5s cubic-bezier(0.3, 0, 0.3, 1) 1.75s, --rv3 0.2s ease-out 2.2s;
}

/* ExePanel's packets on the route (showcase.js) and the link's first part, out of the
   iPhone's clock: over the Mac and over the phone. Composited normally (light would not
   show on the phone's light screen). */
.phone-packets {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Where the link starts: a glow on the iPhone's "Personal Hotspot" title (its nav bar's
   middle, 201 x 76 in iOS points), there while linked and brighter as each packet leaves
   (--lead, showcase.js). */
.phone-glow {
  position: absolute;
  left: 61px;
  top: 52px;
  width: 280px;
  height: 48px;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(136, 216, 248, 0.75), rgba(48, 112, 224, 0.4) 55%, rgba(48, 112, 224, 0) 100%);
  filter: blur(6px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}

.story.is-linked .phone-glow {
  opacity: calc(0.55 + 0.45 * var(--lead, 0));
  transition: opacity 0.5s ease 0.8s;
}

.story.has-rim-link .phone-link { display: none; }

/* The link: from the iPhone to the menu bar's hotspot icon (showcase.js lays the path).
   It draws in, then data flows along it, phone to Mac, while the Mac is on the hotspot. */
.phone-link {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  fill: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.story.is-linked .phone-link { opacity: 1; transition-delay: 1s; }

.phone-link-draw {
  stroke: #fff;
  stroke-width: 14;
  stroke-linecap: round;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 0.2s ease;
}

.story.is-linked .phone-link-draw {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.75s cubic-bezier(0.5, 0, 0.2, 1) 1s;
}

.phone-link-line {
  stroke: url(#phone-link-g);
  stroke-width: 1.5;
  stroke-opacity: 0.55;
  filter: drop-shadow(0 0 4px rgba(136, 216, 248, 0.8));
}

.phone-link-flow {
  stroke: #fff;
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-dasharray: 0 14;
  filter: drop-shadow(0 0 3px rgba(136, 216, 248, 1));
}

.story.is-linked .phone-link-flow { animation: phone-flow 0.7s linear infinite; }

@keyframes phone-flow { to { stroke-dashoffset: -14; } }

@media (prefers-reduced-motion: reduce) {
  .story.is-linked .phone-link-flow { animation: none; }
}

/* ── Front page: the demo's look, light and dark ───────────
   The visitor's system theme picks the look; the switch under the desktop
   overrides it (data-theme on .showcase, remembered by site.js). NetTop's
   popover follows the system appearance, so both looks are the app's own
   colours (ProcessItemView, UsagePanelView, UsageLimitView, Constants);
   Apple's system colours are their standard dark and light values.
   ─────────────────────────────────────────────────────── */

.showcase {
  /* The app spring, sampled (ProcessItemView hover: stiffness 280, damping 12). */
  --spring: cubic-bezier(0.3, 1.25, 0.5, 1);
  /* A deep blue desktop in the family of the App Store screenshots' wallpaper. */
  --night-wallpaper:
    radial-gradient(120% 90% at 8% 112%, rgba(96, 140, 255, 0.55) 0%, rgba(96, 140, 255, 0) 55%),
    radial-gradient(70% 80% at 96% 4%, rgba(120, 180, 255, 0.5) 0%, rgba(120, 180, 255, 0) 60%),
    radial-gradient(60% 60% at 55% 55%, rgba(40, 70, 200, 0.35) 0%, rgba(40, 70, 200, 0) 70%),
    linear-gradient(155deg, #0b1650 0%, #142a8c 42%, #0a1446 72%, #050b2c 100%);
  --day-wallpaper:
    radial-gradient(120% 90% at 8% 112%, rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 55%),
    radial-gradient(70% 80% at 96% 4%, rgba(255, 255, 255, 0.65) 0%, rgba(255, 255, 255, 0) 60%),
    linear-gradient(155deg, #9fbcff 0%, #6f95f5 42%, #a9c3ff 75%, #dbe6ff 100%);

  /* Dark (the default, as the wallpaper). */
  --p-bg: rgba(34, 34, 36, 0.86);
  --p-edge: rgba(255, 255, 255, 0.14);
  --p-dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Crect width='1' height='1' fill='%23fff' fill-opacity='.16'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23fff' fill-opacity='.16'/%3E%3C/svg%3E");
  --p-drawer: rgba(255, 255, 255, 0.04);
  --p-ink: rgba(255, 255, 255, 0.86);
  --p-name: rgba(255, 255, 255, 0.70);
  --p-2nd: rgba(255, 255, 255, 0.72);
  --p-drawn: rgba(255, 255, 255, 0.62);
  --p-tert: rgba(255, 255, 255, 0.28);
  --p-quat: rgba(255, 255, 255, 0.10);
  --p-card: rgba(255, 255, 255, 0.07);
  --p-card-border: rgba(255, 255, 255, 0.10);
  --p-card-hover: rgba(255, 255, 255, 0.13);
  --p-card-hover-border: rgba(255, 255, 255, 0.24);
  --p-icon: rgba(255, 255, 255, 0.78);
  --p-adv-title: #c7c7c7;
  --p-adv-value: #f5f5f5;
  --p-track: rgba(255, 255, 255, 0.16);
  --p-pace: rgba(255, 255, 255, 0.8);
  --p-chart: rgba(255, 255, 255, 0.03);
  --p-cap-blue: #73B3FF;
  --p-cap-green: #73E07A;
  --p-blue: #0A84FF;
  --p-green: #30D158;
  --p-orange: #FF9F0A;
  --p-red: #FF453A;
  --p-yellow: #FFD60A;
  --p-purple: #BF5AF2;
  --p-seg: rgba(255, 255, 255, 0.08);
  --p-seg-on: rgba(255, 255, 255, 0.24);
  --p-btn: rgba(255, 255, 255, 0.16);
  --p-btn-hover: rgba(255, 255, 255, 0.24);
  --p-tip: rgba(42, 42, 44, 0.96);
  --nb-bg: rgba(44, 44, 46, 0.72);
  --nb-edge: rgba(255, 255, 255, 0.14);
  --mb-ink: #ffffff;
  --mb-bg: rgba(0, 0, 0, 0.18);
  --mb-lit: rgba(255, 255, 255, 0.22);
  --kc-ring: rgba(255, 255, 255, 0.9);
}

@supports (transition-timing-function: linear(0, 1)) {
  .showcase {
    --spring: linear(0, 0.0582, 0.1929, 0.3578, 0.5227, 0.6699, 0.7911, 0.8842, 0.9509, 0.9951, 1.0214, 1.0344, 1.0384, 1.0366, 1.0316, 1.0253, 1.019, 1.0132, 1.0085, 1.0048, 1.0021, 1.0003, 0.9993, 0.9987, 0.9985, 0.9986, 0.9988, 0.999, 0.9992, 0.9995, 1);
  }
}

/* Light. Written twice: for the system's light look, and for the switch. */
@media (prefers-color-scheme: light) {
  .showcase:not([data-theme]) {
    --p-bg: rgba(238, 238, 240, 0.86); --p-edge: rgba(0, 0, 0, 0.12);
    --p-dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Crect width='1' height='1' fill='%23000' fill-opacity='.13'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23000' fill-opacity='.13'/%3E%3C/svg%3E");
    --p-drawer: rgba(0, 0, 0, 0.03); --p-ink: rgba(0, 0, 0, 0.85); --p-name: rgba(0, 0, 0, 0.62);
    --p-2nd: rgba(0, 0, 0, 0.55); --p-drawn: rgba(0, 0, 0, 0.55); --p-tert: rgba(0, 0, 0, 0.30);
    --p-quat: rgba(0, 0, 0, 0.10); --p-card: rgba(0, 0, 0, 0.04); --p-card-border: rgba(0, 0, 0, 0.07);
    --p-card-hover: rgba(0, 0, 0, 0.08); --p-card-hover-border: rgba(0, 0, 0, 0.16); --p-icon: rgba(0, 0, 0, 0.6);
    --p-adv-title: #4d4d4d; --p-adv-value: #1c1c1c; --p-track: rgba(0, 0, 0, 0.10); --p-pace: rgba(0, 0, 0, 0.6);
    --p-chart: rgba(0, 0, 0, 0.025); --p-cap-blue: #0061D9; --p-cap-green: #1A8533;
    --p-blue: #007AFF; --p-green: #34C759; --p-orange: #FF9500; --p-red: #FF3B30; --p-yellow: #D19E00; --p-purple: #AF52DE;
    --p-seg: rgba(0, 0, 0, 0.06); --p-seg-on: #ffffff; --p-btn: #ffffff; --p-btn-hover: #f4f4f4; --p-tip: rgba(246, 246, 246, 0.98);
    --nb-bg: rgba(246, 246, 246, 0.78); --nb-edge: rgba(0, 0, 0, 0.10);
    --mb-ink: #1d1d1f; --mb-bg: rgba(255, 255, 255, 0.45); --mb-lit: rgba(0, 0, 0, 0.1); --kc-ring: rgba(0, 0, 0, 0.55);
  }
  .showcase:not([data-theme]) .desktop,
  .showcase:not([data-theme]) .story-step-shot { background: var(--day-wallpaper); }
}
.showcase[data-theme="light"] {
  --p-bg: rgba(238, 238, 240, 0.86); --p-edge: rgba(0, 0, 0, 0.12);
  --p-dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Crect width='1' height='1' fill='%23000' fill-opacity='.13'/%3E%3Crect x='2' y='2' width='1' height='1' fill='%23000' fill-opacity='.13'/%3E%3C/svg%3E");
  --p-drawer: rgba(0, 0, 0, 0.03); --p-ink: rgba(0, 0, 0, 0.85); --p-name: rgba(0, 0, 0, 0.62);
  --p-2nd: rgba(0, 0, 0, 0.55); --p-drawn: rgba(0, 0, 0, 0.55); --p-tert: rgba(0, 0, 0, 0.30);
  --p-quat: rgba(0, 0, 0, 0.10); --p-card: rgba(0, 0, 0, 0.04); --p-card-border: rgba(0, 0, 0, 0.07);
  --p-card-hover: rgba(0, 0, 0, 0.08); --p-card-hover-border: rgba(0, 0, 0, 0.16); --p-icon: rgba(0, 0, 0, 0.6);
  --p-adv-title: #4d4d4d; --p-adv-value: #1c1c1c; --p-track: rgba(0, 0, 0, 0.10); --p-pace: rgba(0, 0, 0, 0.6);
  --p-chart: rgba(0, 0, 0, 0.025); --p-cap-blue: #0061D9; --p-cap-green: #1A8533;
  --p-blue: #007AFF; --p-green: #34C759; --p-orange: #FF9500; --p-red: #FF3B30; --p-yellow: #D19E00; --p-purple: #AF52DE;
  --p-seg: rgba(0, 0, 0, 0.06); --p-seg-on: #ffffff; --p-btn: #ffffff; --p-btn-hover: #f4f4f4; --p-tip: rgba(246, 246, 246, 0.98);
  --nb-bg: rgba(246, 246, 246, 0.78); --nb-edge: rgba(0, 0, 0, 0.10);
  --mb-ink: #1d1d1f; --mb-bg: rgba(255, 255, 255, 0.45); --mb-lit: rgba(0, 0, 0, 0.1); --kc-ring: rgba(0, 0, 0, 0.55);
}
.showcase[data-theme="light"] .desktop,
.showcase[data-theme="light"] .sp-thumb--1 .sp-pic,
.showcase[data-theme="light"] .story-step-shot { background: var(--day-wallpaper); }

/* The iPhone in iOS's light look, with the demo's. */
.showcase[data-theme="light"] .phone-ui {
  --ios-bg: #f2f2f7; --ios-cell: #ffffff; --ios-ink: #000000; --ios-2nd: rgba(60, 60, 67, 0.6);
  --ios-sep: rgba(60, 60, 67, 0.29); --ios-blue: #007AFF; --ios-green: #34C759; --ios-off: rgba(120, 120, 128, 0.16);
}
@media (prefers-color-scheme: light) {
  .showcase:not([data-theme]) .phone-ui {
    --ios-bg: #f2f2f7; --ios-cell: #ffffff; --ios-ink: #000000; --ios-2nd: rgba(60, 60, 67, 0.6);
    --ios-sep: rgba(60, 60, 67, 0.29); --ios-blue: #007AFF; --ios-green: #34C759; --ios-off: rgba(120, 120, 128, 0.16);
  }
}

/* The switch, in the app's segmented control language: a recessed track and
   a raised knob behind the chosen side. */
.theme-switch {
  display: flex;
  width: max-content;
  margin: 22px auto 0;
  padding: 3px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.07);
  border: 1px solid rgba(0, 0, 0, 0.09);
}
.theme-switch button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: #7c8290;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}
.theme-switch.is-ready button { transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease; }
.theme-switch button svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}
.theme-switch button[data-theme-choice="dark"] svg { fill: currentColor; stroke: none; }
.theme-switch button[aria-pressed="true"] {
  background: #ffffff;
  color: #14161b;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 0 0 0.5px rgba(0, 0, 0, 0.12);
}
.theme-switch button:focus-visible { outline: 2px solid #3070E0; outline-offset: 2px; }

/* Which rendering shows. */
.story-track { display: none; }

/* Twenty-five steps 60vh apart; showcase.js starts the story while the stage is
   still coming in, so there is no dead scroll before the first click.
   Height: 100vh of stage + story end (25 x 60vh - 110vh lead) + 20vh hold on
   the last step before the stage scrolls away. */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  .js:not(.legacy) .story-track {
    display: block;
    position: relative;
    height: 1510vh;
  }
  .js:not(.legacy) .story-static { display: none; }
  /* Hidden until showcase.js has laid the desktop out (.is-ready), so a refresh never
     paints the unmeasured screen first. */
  .js .story:not(.is-ready) .story-track .mac { opacity: 0; }
  .js .story.is-ready .story-track .mac { transition: opacity 0.25s ease; }
  /* The story draws its own pointer on the desktop; while it plays and the visitor
     scrolls, theirs fades back over the stage (.is-cursor-off, showcase.js: full again on
     the first real mouse move), so the story's arrow leads but theirs is never lost: the
     same macOS arrow, smaller (15 x 21) and at 15%. The theme switch keeps the normal
     pointer. */
  .js .story.is-cursor-off .story-stage { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='21' viewBox='0 0 20 28'%3E%3Cpath d='M1.5 1.5v19.3l4.7-4.5 3 7.1 3.4-1.4-3-7h6.6z' fill='%23000' stroke='%23fff' stroke-width='1.5' stroke-linejoin='round' opacity='.15'/%3E%3C/svg%3E") 1 1, auto; }
  .js .story.is-cursor-off .story-stage .theme-switch,
  .js .story.is-cursor-off .story-stage .theme-switch * { cursor: pointer; }
}

.story-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.story-inner {
  /* As wide as the column allows, but never taller than the window minus the
     caption above and the theme switch below. */
  width: min(100%, calc((100vh - 215px) * 1.638));
  width: min(100%, calc((100svh - 215px) * 1.638));
}

.story-captions {
  display: grid;
  margin-bottom: 26px;
}

.story-caption {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.4s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.story-caption.is-active {
  opacity: 1;
  transform: none;
}

.story-caption h2,
.story-step h2 {
  font-family: var(--font-heading);
  font-size: clamp(26px, 3vw, 40px);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.025em;
  margin: 0 0 12px;
  text-wrap: balance;
}

/* The live story's titles fill as the scroll moves through their steps, letter by letter,
   grey to ink: a loading bar made of the words. showcase.js sets --p (0 to 1) on the
   active one; each letter (--k of --n) turns as --p passes it, over one letter's width.
   Browsers without color-mix keep the plain ink title. */
/* --p is registered so it can ease: the fill glides between scroll positions. */
@property --p { syntax: '<number>'; inherits: true; initial-value: 1; }
.story-fill { transition: --p 0.35s ease-out; }
.story-fill .sf-w { white-space: nowrap; }

@supports (color: color-mix(in srgb, red 50%, blue)) {
  .story-fill span span {
    color: color-mix(in srgb, var(--ink) calc(clamp(0, var(--p, 1) * var(--n) - var(--k), 1) * 100%), rgba(11, 11, 12, 0.2));
  }
}

.story-caption p,
.story-step p {
  margin: 0;
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.4;
  color: var(--muted);
}

/* The desktop's inside: laid out at 1120 x 725 points (the frame's screen at that width, tall
   enough for the 672 pt popover under the menu bar) and scaled down to narrower frames; in
   wider ones showcase.js keeps the scale at 1 and sizes this to the whole frame. */
.screen {
  position: absolute;
  left: 0;
  top: 0;
  width: 1120px;
  height: 725px;
  transform: scale(var(--s, 1));
  transform-origin: 0 0;
}


/* ── The menu bar ──────────────────────────────────────── */

.screen .menubar,
.ss-bar .menubar {
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', sans-serif;
  font-weight: 500;
  color: var(--mb-ink);
  background: var(--mb-bg);
  -webkit-font-smoothing: auto;
}

.mb-left {
  display: inline-flex;
  align-items: center;
  gap: 20px;
  font-weight: 400;
}
.mb-left b { font-weight: 700; margin-left: 2px; }
.menubar .apple { width: 13px; height: 15px; fill: currentColor; }

.mb-right { gap: 16px; }

.mb-sym { display: inline-flex; align-items: center; }
.mb-sym svg {
  width: 17px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mb-batt svg { width: 25px; height: 13px; stroke-width: 1.1; }
.mb-sym .g-fill { fill: currentColor; stroke: none; }
.mb-hot { display: none !important; }
.is-hotspot .mb-wifi { display: none; }
.is-hotspot .mb-hot { display: inline-flex !important; }

.mb-clock { font-variant-numeric: tabular-nums; white-space: pre; }

/* StatusBarView: two lines of 9 pt monospaced digits, upload over download, right aligned;
   orange on a hotspot. */
.mb-nt {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  min-width: 66px;
  height: 24px;
  font-size: 9px;
  line-height: 10px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: pre;
  transition: color 0.5s ease, background-color 0.12s ease-out;
}
.is-hotspot .mb-nt { color: var(--p-orange); }
.screen.is-open .mb-nt { background: var(--mb-lit); }

/* ── The popover ───────────────────────────────────────── */

.np {
  position: absolute;
  top: calc(var(--mb-h, 32px) + 1px);
  left: 0;
  width: 300px;
  height: 681px;
  z-index: 4;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: normal;
  letter-spacing: 0;
  color: var(--p-ink);
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.94);
  transform-origin: 50% 0;
  transition: opacity 0.18s ease, transform 0.25s var(--spring), visibility 0s 0.25s, width 0.42s var(--spring), left 0.42s var(--spring);
}
.np.is-open,
.screen.is-open .np {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.12s ease, transform 0.3s var(--spring), visibility 0s, width 0.42s var(--spring), left 0.42s var(--spring);
}
.np.is-side,
.screen.is-side .np { width: 600px; }

/* The arrow, part of the panel as in AppKit's popover: a low, wide hill with a round top
   (no point), standing 3 px above the popover's box, and shoulders that meet the panel's
   top edge (y 9) tangentially; the panel's material and dot texture (aligned with the
   main column's through --dx, set by showcase.js) and its light edge along the sides.
   It reaches 1.5 px into the panel and is drawn over it, so the panel's own top edge
   does not cut across its base. */
.np-arrow {
  --arrow: path("M0 13.5 L0 12 C9.5 12 12.6 3 20 3 C27.4 3 30.5 12 40 12 L40 13.5 Z");
  position: absolute;
  top: -3px;
  left: calc(50% - 20px);
  z-index: 1;
  width: 40px;
  height: 13.5px;
  pointer-events: none;
}

.np-arrow::before,
.np-arrow::after {
  content: "";
  position: absolute;
  inset: 0;
}

.np-arrow::before {
  background: var(--p-dots) var(--dx, 0px) 12px / 4px 4px repeat, var(--p-bg);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  backdrop-filter: blur(30px) saturate(1.6);
  clip-path: var(--arrow);
}

.np-arrow::after {
  background: var(--p-edge);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='13.5'%3E%3Cpath d='M0 12 C9.5 12 12.6 3 20 3 C27.4 3 30.5 12 40 12' fill='none' stroke='%23000' stroke-width='1'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='13.5'%3E%3Cpath d='M0 12 C9.5 12 12.6 3 20 3 C27.4 3 30.5 12 40 12' fill='none' stroke='%23000' stroke-width='1'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat;
}

.np-body {
  position: absolute;
  top: 9px;
  left: 0;
  right: 0;
  height: 672px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--p-bg);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  backdrop-filter: blur(30px) saturate(1.6);
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.45), inset 0 0 0 0.5px var(--p-edge), 0 22px 50px -12px rgba(0, 0, 0, 0.55);
}

.np svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.np svg .g-fill { fill: currentColor; stroke: none; }

/* The main column: DotPatternView over the material. */
.np-main {
  position: absolute;
  left: 0;
  top: 0;
  width: 300px;
  height: 672px;
  background-image: var(--p-dots);
  background-size: 4px 4px;
}

/* Header: title in the expanded system face, the buttons right to left. */
.nh {
  position: absolute;
  top: 12px;
  left: 7.5px;
  width: 285px;
  height: 26px;
}
.nh-title {
  position: absolute;
  left: 12px;
  top: 0;
  line-height: 26px;
  font-family: 'Zalando Sans Expanded', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--p-ink);
}
.nh-btn {
  position: absolute;
  top: 1px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  color: var(--p-icon);
  opacity: 0.9;
  transition: opacity 0.12s ease, transform 0.12s ease;
}
.nh-btn svg { width: 15px; height: 15px; stroke-width: 1.25; }
.nh-usage svg { width: 14px; height: 14px; }
.nh-gear { right: 2px; }
.nh-speed { right: 28px; }
.nh-usage { right: 54px; }
.nh-btn.is-hover { opacity: 1; color: var(--p-ink); }
.nh-btn.is-pressed { transform: scale(0.88); }
.is-side.side-usage .nh-usage,
.screen.is-side.side-usage .nh-usage,
.is-side.side-speed .nh-speed,
.screen.is-side.side-speed .nh-speed { color: var(--p-blue); opacity: 1; }

/* The PRO pill: navy gradient, turquoise top edge. */
.nh-pro {
  position: absolute;
  right: 84px;
  top: 4.5px;
  width: 32px;
  height: 17px;
  border-radius: 5px;
  background: linear-gradient(#092191, #001080);
  box-shadow: inset 0 1px 0 rgba(136, 216, 248, 0.5), 0 0 6px rgba(136, 216, 248, 0.25);
  color: #ffffff;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 17px;
  text-align: center;
}

/* Cards: the speed summary, rows, details. */
.ns,
.nr,
.nd-row,
.nu-card,
.uc,
.ul {
  background: var(--p-card);
  box-shadow: inset 0 0 0 1px var(--p-card-border);
  border-radius: 8px;
}

.ns {
  position: absolute;
  top: 46px;
  left: 12px;
  width: 276px;
  height: 50px;
  display: flex;
  align-items: center;
}
.ns-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.ns-col b,
.nu-card b {
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--p-ink);
}
.ns-cap { font-size: 10px; font-weight: 500; }
.ns-cap--down { color: var(--p-cap-blue); }
.ns-cap--up { color: var(--p-cap-green); }
.ns-div {
  position: absolute;
  left: 50%;
  top: 25%;
  width: 1px;
  height: 50%;
  background: var(--p-quat);
}

.nc {
  position: absolute;
  top: 102px;
  left: 12px;
  width: 276px;
  height: 76px;
  border-radius: 8px;
  background: var(--p-chart);
  overflow: hidden;
}
.nc-svg { width: 100%; height: 100%; }
.nc-line { stroke-width: 1.5; }
.nc-line--down { stroke: var(--p-blue); }
.nc-line--up { stroke: var(--p-green); }
.nc-fill { stroke: none; opacity: 0.16; }
.nc-fill--down { fill: var(--p-blue); }
.nc-fill--up { fill: var(--p-green); }

/* Column header: "Process", search, and the yellow arrows over the speed columns. */
.nl-head {
  position: relative;
  height: 22px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 4px;
}
.np-main > .nl-head {
  position: absolute;
  top: 188px;
  left: 10px;
  width: 287px;
}
.nl-title {
  font-family: 'Zalando Sans Expanded', -apple-system, sans-serif;
  font-size: 10px;
  font-weight: 500;
  color: var(--p-2nd);
}
.nl-search { display: inline-flex; width: 22px; height: 22px; align-items: center; justify-content: center; color: var(--p-icon); }
.nl-search svg { width: 12px; height: 12px; stroke-width: 1.5; }
.nl-arrow {
  position: absolute;
  top: 6px;
  width: 10px;
  height: 10px;
  color: var(--p-yellow);
}
.nl-arrow svg { width: 10px; height: 10px; stroke-width: 1.6; }
.nl-arrow--up { right: 22px; }
.nl-arrow--down { right: 94px; }

.nl {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(transparent 0, #000 5%, #000 90%, transparent 100%);
  mask-image: linear-gradient(transparent 0, #000 5%, #000 90%, transparent 100%);
}
.np-main > .nl {
  position: absolute;
  top: 210px;
  left: 10px;
  width: 287px;
  height: 234px;
}
.nl-in {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding-top: 10px;
}

/* A row (ProcessItemView): 28 pt card, 16 pt icon, name 12, two 68 pt speed columns. */
.nr {
  position: relative;
  flex: none;
  width: 275px;
  height: 28px;
  transition: background-color 0.17s ease, box-shadow 0.17s ease, transform 0.3s var(--spring);
}
.nr.is-hover {
  background: var(--p-card-hover);
  box-shadow: inset 0 0 0 1px var(--p-card-hover-border);
  transform: scale(0.985);
}
.nr-icon {
  position: absolute;
  left: 10px;
  top: 6px;
  width: 16px;
  height: 16px;
}
.nr-name {
  position: absolute;
  left: 33px;
  top: 0;
  max-width: 78px;
  height: 28px;
  display: flex;
  align-items: center;
  color: var(--p-name);
}
.nr-label {
  min-width: 0;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nr-chev {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 20px;
  border-radius: 4px;
}
.nr-chev svg { width: 9px; height: 9px; stroke-width: 1.7; }
.nr-chev svg + svg { display: none; }
.is-grouped .nr-chev svg { display: none; }
.is-grouped .nr-chev svg + svg { display: block; }
.nr-chev.is-hover { background: var(--p-card-hover); }
.nr-down,
.nr-up {
  position: absolute;
  top: 0;
  width: 68px;
  line-height: 28px;
  text-align: right;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--p-ink);
  white-space: nowrap;
}
.nr-down { left: 119px; }
.nr-up { left: 197px; }

/* A group's members, 16 pt further right, folded away until the chevron opens them. */
.nr-members {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-height: 0;
  margin-top: -5px;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.3s ease, margin-top 0.3s ease, opacity 0.22s ease;
}
.is-grouped .nr-members {
  max-height: 140px;
  margin-top: 0;
  opacity: 1;
}
.nr--member .nr-icon { left: 26px; }
.nr--member .nr-name { left: 49px; max-width: 62px; }

/* The closed group's tooltip: "Running: claude, node, git, curl". */
.nr-tip {
  position: absolute;
  z-index: 6;
  padding: 2px 7px 3px;
  border-radius: 5px;
  background: var(--p-tip);
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.3), 0 4px 12px rgba(0, 0, 0, 0.25);
  color: var(--p-ink);
  font-size: 11px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.nr-tip.is-on { opacity: 1; transition: opacity 0.15s ease 0.5s; }

/* Details: a section band, then 28 pt cards. */
.nd {
  position: absolute;
  top: 452px;
  left: 0;
  width: 300px;
  height: 220px;
  padding: 0 0 0 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 85%, transparent 100%);
  mask-image: linear-gradient(#000 85%, transparent 100%);
}
.nd-band {
  flex: none;
  height: 24px;
  line-height: 24px;
  padding-left: 6px;
  font-family: 'Zalando Sans Expanded', -apple-system, sans-serif;
  font-size: 9px;
  font-weight: 600;
  color: var(--p-2nd);
}
.nd-row {
  flex: none;
  width: 275px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  font-size: 11px;
  color: var(--p-adv-title);
}
.nd-row b { font-weight: 500; color: var(--p-adv-value); font-variant-numeric: tabular-nums; white-space: pre; }
.nd-row.is-ok b { color: var(--p-cap-green); }
.nd-hot { display: none; }
.is-hotspot .nd-conn b { color: var(--p-orange); }
.is-hotspot .nd-wifi { display: none; }
.is-hotspot .nd-hot { display: inline; }

/* ── The side panel (the drawer) ───────────────────────── */

.np-side {
  position: absolute;
  left: 300px;
  top: 0;
  width: 300px;
  height: 672px;
  background: var(--p-drawer);
}
.np-divider {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: linear-gradient(transparent, var(--p-card-border) 15%, var(--p-card-border) 85%, transparent);
}
.nu,
.nt {
  position: absolute;
  inset: 0;
  padding: 16px;
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0s 0.2s;
}
.side-usage .nu,
.side-speed .nt {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.25s ease 0.08s, visibility 0s;
}

/* System controls, drawn small. */
.seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  height: 24px;
  padding: 2px;
  border-radius: 7px;
  background: var(--p-seg);
  font-size: 12px;
  font-weight: 500;
  color: var(--p-ink);
  text-align: center;
}
.seg span { line-height: 20px; border-radius: 5px; }
.seg .is-on { background: var(--p-seg-on); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0, 0, 0, 0.1); }

.npop,
.nbtn,
.nfield {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 19px;
  padding: 0 8px;
  border-radius: 5px;
  background: var(--p-btn);
  box-shadow: 0 0.5px 1.5px rgba(0, 0, 0, 0.25), 0 0 0 0.5px rgba(0, 0, 0, 0.12);
  font-size: 11px;
  color: var(--p-ink);
  white-space: nowrap;
  transition: background-color 0.12s ease, transform 0.12s ease;
}
.npop { padding-right: 5px; }
.npop svg { width: 7px; height: 11px; stroke-width: 1.4; }
.nfield { background: transparent; box-shadow: inset 0 0 0 1px var(--p-card-border); font-variant-numeric: tabular-nums; }
.nbtn.is-hover { background: var(--p-btn-hover); }
.nbtn.is-pressed { transform: scale(0.95); }
.nbtn--default { background: var(--p-blue); color: #ffffff; }
.nbtn--default.is-hover { background: var(--p-blue); filter: brightness(1.1); }

/* Usage (UsagePanelView): segments, two cards, the chart, the network, the limit, Top Apps. */
.nu-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 12px;
}
.nu-card {
  height: 56px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.nu-card b { font-size: 15px; }

.uc {
  position: relative;
  height: 112px;
  margin-top: 12px;
  padding: 6px 6px 0;
}
.uc-bars {
  height: 90px;
  display: flex;
  align-items: flex-end;
}
.ub {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 0.35s ease-in-out;
}
.is-filled .ub,
.screen.is-filled .ub {
  transform: none;
  transition-delay: calc(var(--i, 0) * 0.07s);
}
.ub-up,
.ub-down { display: block; width: 62%; }
.ub-up { height: var(--u); background: var(--p-green); border-radius: 1.5px 1.5px 0 0; }
.ub-down { height: var(--d); min-height: 2px; background: var(--p-blue); }
.ub--future { transform: none; }
.ub--future::after { content: ''; display: block; width: 62%; height: 1px; background: var(--p-quat); }
.uc-axis {
  position: relative;
  height: 16px;
  font-size: 10px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--p-drawn);
}
.uc-axis span { position: absolute; top: 2px; transform: translateX(-50%); }
.uc-axis span:nth-child(1) { left: 2.08%; }
.uc-axis span:nth-child(2) { left: 27.08%; }
.uc-axis span:nth-child(3) { left: 52.08%; }
.uc-axis span:nth-child(4) { left: 77.08%; }
.uc-axis--pos span:nth-child(n) { left: auto; }

.nu-scope {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 5px;
  font-size: 10.5px;
  color: var(--p-2nd);
}
.nu-scope svg { width: 10px; height: 10px; stroke-width: 1.1; }

.nu-net {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
}
.nu-net-hot,
.nu-badge { display: none !important; }
.is-hotspot .nu-net-all { display: none; }
.is-hotspot .nu-net-hot { display: inline !important; }
.is-hotspot .nu-badge { display: inline-block !important; }
.nu-badge {
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(255, 159, 10, 0.18);
  color: var(--p-orange);
  font-size: 10px;
  font-weight: 600;
}
.nu-export { margin-left: auto; }

/* The data limit (UsageLimitView): 6 pt track in a 10 pt bar, orange from 80%. */
.ul {
  margin-top: 12px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ul-top { display: flex; align-items: center; justify-content: space-between; }
.ul-title {
  font-family: 'Zalando Sans Expanded', -apple-system, sans-serif;
  font-size: 10px;
  font-weight: 500;
  color: var(--p-2nd);
}
.ul-set { display: none; }
.is-limit .ul-set { display: inline; }
.is-limit .ul-none { display: none; }
.ul-bar,
.ul-foot { display: none; }
.is-limit .ul-bar { display: block; }
.is-limit .ul-foot { display: flex; }
.ul-bar { position: relative; height: 10px; }
.ul-track,
.ul-fill {
  position: absolute;
  top: 2px;
  left: 0;
  height: 6px;
  border-radius: 3px;
}
.ul-track { width: 100%; background: var(--p-track); }
.ul-fill {
  width: calc(var(--f) * 100%);
  min-width: 6px;
  background: var(--p-blue);
  transition: background-color 0.3s ease;
}
.is-over .ul-fill { background: var(--p-orange); }
.ul-pace {
  position: absolute;
  top: 0;
  width: 2px;
  height: 10px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--p-pace);
}
.ul-foot { justify-content: space-between; align-items: baseline; }
.ul-used { font-size: 11px; font-weight: 500; font-variant-numeric: tabular-nums; white-space: pre; }
.ul-reset { font-size: 10px; color: var(--p-2nd); }

.nu-head { margin-top: 12px; height: 18px; }
.nu .nl-arrow { top: 4px; }
.nu .nl-arrow--up { right: 10px; }
.nu .nl-arrow--down { right: 88px; }
.nu-list { flex: 1; min-height: 0; margin: 0 -4px; padding: 0 4px; }
.nu-list .nl-in { padding-top: 6px; }
.nu .nr { width: 268px; }
.nu .nr-name { max-width: 71px; }
.nu .nr-down { left: 112px; }
.nu .nr-up { left: 190px; }

/* ── Speed test (SpeedTestPanelView) ───────────────────── */

.nt { gap: 14px; --acc: var(--p-blue); }
.ph-ping .nt { --acc: var(--p-orange); }
.ph-up .nt { --acc: var(--p-green); }

.nt-gauge {
  position: relative;
  flex: none;
  height: 168px;
  margin-top: 8px;
}
.nt-gauge svg { position: absolute; inset: 0; width: 268px; height: 168px; overflow: visible; }
.nt-track { stroke: var(--p-quat); stroke-width: 13; }
.nt-value { stroke: var(--acc); stroke-width: 13; transition: stroke 0.3s ease; }
.nt-needle { stroke: var(--acc); stroke-width: 3; transition: stroke 0.3s ease; }
.nt-hub { fill: var(--acc); stroke: none; transition: fill 0.3s ease; }
.nt-ticks text {
  fill: var(--p-tert);
  stroke: none;
  font-size: 9px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-anchor: middle;
}
.nt-num {
  position: absolute;
  left: 0;
  right: 0;
  top: 84px;
  text-align: center;
  font-size: 34px;
  font-weight: 700;
  line-height: 40px;
  font-variant-numeric: tabular-nums;
  color: var(--p-ink);
}
.nt-unit {
  position: absolute;
  left: 0;
  right: 0;
  top: 124px;
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  color: var(--p-2nd);
}
.nt-phase { height: 16px; text-align: center; font-size: 13px; font-weight: 600; color: var(--p-2nd); }
.nt-server { margin-top: -6px; text-align: center; font-size: 10px; font-variant-numeric: tabular-nums; color: var(--p-tert); }
.nt-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.nt-card {
  padding: 12px 0;
  border-radius: 8px;
  background: var(--p-card);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.nt-card span { font-size: 10px; font-weight: 500; }
.nt-card b { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--p-ink); }
.nt-down span { color: var(--p-blue); }
.nt-up span { color: var(--p-green); }
.nt-ping span { color: var(--p-orange); }
.nt-jitter span { color: var(--p-purple); }
.nt-btn {
  height: 28px;
  border-radius: 7px;
  background: var(--p-blue);
  color: #ffffff;
  font-size: 13px;
  font-weight: 600;
  line-height: 28px;
  text-align: center;
  box-shadow: 0 0.5px 1.5px rgba(0, 0, 0, 0.25);
  transition: background-color 0.2s ease, transform 0.12s ease, filter 0.12s ease;
}
.nt-btn.is-hover { filter: brightness(1.1); }
.nt-btn.is-pressed { transform: scale(0.97); }
.nt-cancel,
.nt-again { display: none; }
.st-run .nt-btn { background: var(--p-red); }
.st-run .nt-start,
.st-done .nt-start { display: none; }
.st-run .nt-cancel,
.st-done .nt-again { display: inline; }

/* ── The Export form (UsageExportView) ─────────────────── */

.nx {
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  z-index: 5;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', sans-serif;
  font-size: 12px;
  color: var(--p-ink);
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.94);
  transform-origin: var(--ax, 50%) 0;
  transition: opacity 0.15s ease, transform 0.2s ease, visibility 0s 0.2s;
}
.screen.is-export .nx {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.12s ease, transform 0.3s var(--spring), visibility 0s;
}
.nx .np-arrow { left: calc(var(--ax, 50%) - 20px); }
/* The export form has no dot texture. */
.nx .np-arrow::before { background: var(--p-bg); }
.nx-body {
  position: relative;
  margin-top: 9px;
  padding: 16px;
  border-radius: 12px;
  background: var(--p-bg);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  backdrop-filter: blur(30px) saturate(1.6);
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.45), inset 0 0 0 0.5px var(--p-edge), 0 18px 40px -10px rgba(0, 0, 0, 0.55);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.nx svg { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.nx-title {
  font-family: 'Zalando Sans Expanded', -apple-system, sans-serif;
  font-size: 12px;
  font-weight: 600;
}
.nx-row { display: flex; align-items: center; justify-content: space-between; color: var(--p-2nd); }
.nx-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }

/* ── Notification banners ──────────────────────────────── */

.nb {
  position: absolute;
  top: calc(var(--mb-h, 32px) + 8px);
  right: 10px;
  z-index: 7;
  width: 344px;
  min-height: 57px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px 9px 10px;
  border-radius: 16px;
  background: var(--nb-bg);
  -webkit-backdrop-filter: blur(30px) saturate(1.8);
  backdrop-filter: blur(30px) saturate(1.8);
  box-shadow: inset 0 0 0 0.5px var(--nb-edge), 0 4px 12px rgba(0, 0, 0, 0.22);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', sans-serif;
  font-size: 13px;
  line-height: 1.25;
  color: var(--p-ink);
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  visibility: hidden;
  transform: translateX(30px);
  transition: opacity 0.3s ease, transform 0.45s var(--spring), visibility 0s 0.45s;
}
.screen.is-banner-hotspot .nb--hotspot,
.screen.is-banner-limit .nb--limit,
.screen.is-banner-report .nb--report {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.3s ease, transform 0.5s var(--spring), visibility 0s;
}
.nb-icon { flex: none; width: 38px; height: 38px; border-radius: 9px; }
.nb-text { display: flex; flex-direction: column; min-width: 0; }
.nb-text b { font-weight: 700; }
.nb-text span {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── The PDF report (UsageReportView): A4 at 595 x 842 pt ── */

.rp {
  position: relative;
  width: 595px;
  height: 842px;
  padding: 28px 44px;
  background: #ffffff;
  color: #1a1a1a;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', 'Segoe UI', sans-serif;
  font-size: 11px;
  line-height: 1.25;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.55), 0 0 0 0.5px rgba(0, 0, 0, 0.15);
  text-align: left;
}
.rp-head { display: flex; align-items: center; gap: 8px; }
.rp-head img { width: 28px; height: 28px; }
.rp-mark { display: flex; flex-direction: column; }
.rp-mark b { font-family: 'Zalando Sans Expanded', -apple-system, sans-serif; font-size: 16px; font-weight: 700; line-height: 1.1; }
.rp-mark span { font-size: 8px; font-weight: 500; color: #7a7a7a; }
.rp-kind { margin-left: auto; font-family: 'Zalando Sans Expanded', -apple-system, sans-serif; font-size: 10px; font-weight: 600; color: #0D45CC; letter-spacing: 0.02em; }
.rp-rule { display: block; height: 2px; margin: 10px 0 16px; background: linear-gradient(90deg, #0D45CC, #339EFF); border-radius: 1px; }
.rp-titles { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.rp-titles h4 { margin: 0; font-family: 'Zalando Sans Expanded', -apple-system, sans-serif; font-size: 17px; font-weight: 600; letter-spacing: -0.01em; }
.rp-titles p { margin: 3px 0 0; font-size: 11px; color: #7a7a7a; }
.rp-pill { padding: 3px 8px; border-radius: 999px; background: #EBF2FF; color: #0D45CC; font-size: 9px; font-weight: 600; white-space: nowrap; }
.rp-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 14px; }
.rp-card { height: 62px; padding: 9px 11px; border-radius: 9px; background: #F4F5F8; display: flex; flex-direction: column; gap: 3px; }
.rp-cap { display: flex; align-items: center; gap: 5px; font-size: 9.5px; font-weight: 600; color: #4a4a4a; }
.rp-dot { display: inline-flex; width: 13px; height: 13px; border-radius: 50%; align-items: center; justify-content: center; color: #fff; font-style: normal; font-size: 8px; font-weight: 700; }
.rp-dot--down { background: #2E7AF5; }
.rp-dot--up { background: #40BA4F; }
.rp-dot--total { background: #0D45CC; }
.rp-card b { font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums; }
.rp-card small { font-size: 8.5px; color: #7a7a7a; margin-top: -2px; }
.rp-split { display: flex; height: 3px; gap: 1px; margin-top: 2px; }
.rp-split i { display: block; background: #40BA4F; border-radius: 2px; flex: 1; }
.rp-split i:first-child { background: #2E7AF5; flex: none; }
.rp-highs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 10px; }
.rp-highs div { height: 40px; padding: 6px 10px 6px 34px; border-radius: 9px; border: 1px solid #E4E6EB; position: relative; display: flex; flex-direction: column; justify-content: center; }
.rp-highs i { position: absolute; left: 9px; top: 11px; width: 17px; height: 17px; border-radius: 5px; background: #EBF2FF; color: #0D45CC; font-style: normal; font-size: 9px; text-align: center; line-height: 17px; }
.rp-highs span { font-size: 7px; font-weight: 600; letter-spacing: 0.06em; color: #7a7a7a; }
.rp-highs b { font-size: 10px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rp-highs small { font-weight: 400; color: #7a7a7a; }
.rp-chart { margin-top: 14px; height: 186px; padding: 10px 56px 0 46px; border-radius: 9px; border: 1px solid #E4E6EB; position: relative; }
.rp-chart-head { display: flex; justify-content: space-between; align-items: center; margin: 0 -44px 0 -34px; }
.rp-chart-head b { font-size: 10.5px; font-weight: 600; }
.rp-chart-head span { display: flex; align-items: center; gap: 4px; font-size: 7.5px; color: #7a7a7a; }
.rp-l { display: inline-block; width: 7px; height: 7px; border-radius: 2px; margin-left: 6px; }
.rp-l--down { background: #2E7AF5; }
.rp-l--up { background: #40BA4F; }
.rp-l--avg { height: 2px; background: #F0A121; }
.rp-plot { position: relative; height: 128px; margin-top: 14px; border-bottom: 1px solid #E4E6EB; }
.rp-y { position: absolute; left: -36px; width: 30px; text-align: right; font-size: 7.5px; color: #9a9a9a; transform: translateY(50%); }
.rp-avg { position: absolute; left: 0; right: 0; height: 0; border-top: 1px dashed #F0A121; z-index: 1; }
.rp-avg span { position: absolute; left: calc(100% + 4px); top: -5px; white-space: nowrap; font-size: 7.5px; font-weight: 600; color: #F0A121; }
.rp-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; }
.rp-bar { flex: 1; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; position: relative; }
.rp-bar > i { display: flex; flex-direction: column; width: 62%; background: #2E7AF5; border-radius: 4px 4px 0 0; overflow: hidden; }
.rp-up { display: block; width: 100%; background: #40BA4F; }
.rp-val { font-size: 7.5px; font-weight: 600; color: #4a4a4a; margin-bottom: 2px; font-variant-numeric: tabular-nums; }
.rp-bar.is-busy .rp-val { color: #fff; background: #0D45CC; border-radius: 3px; padding: 0 3px; }
.rp-day { position: absolute; bottom: -14px; font-size: 7.5px; color: #7a7a7a; white-space: nowrap; }
.rp-bar.is-busy .rp-day { color: #0D45CC; font-weight: 600; }
.rp-apps-head { display: flex; justify-content: space-between; align-items: baseline; margin-top: 18px; }
.rp-apps-head b { font-family: 'Zalando Sans Expanded', -apple-system, sans-serif; font-size: 12px; font-weight: 600; }
.rp-apps-head span { font-size: 7.5px; color: #9a9a9a; }
.rp-apps { width: 100%; margin-top: 6px; border-collapse: collapse; font-size: 9px; font-variant-numeric: tabular-nums; }
.rp-apps th { font-size: 7px; font-weight: 600; letter-spacing: 0.05em; color: #9a9a9a; text-align: right; padding: 0 0 4px; }
.rp-apps th:nth-child(2) { text-align: left; }
.rp-apps td { height: 16.5px; text-align: right; border-top: 1px solid #F0F1F4; }
.rp-apps td:nth-child(2) { text-align: left; font-weight: 500; }
.rp-rank { width: 16px; text-align: left !important; color: #9a9a9a; }
.rp-share { width: 118px; }
.rp-share > i { display: inline-block; width: 70px; height: 4px; margin-right: 6px; border-radius: 2px; background: #E4E6EB; vertical-align: middle; overflow: hidden; }
.rp-share > i > i { display: block; height: 100%; background: #2E7AF5; }
.rp-share span { display: inline-block; width: 34px; color: #7a7a7a; }
.rp-foot { position: absolute; left: 44px; right: 44px; bottom: 28px; display: flex; align-items: center; gap: 12px; padding-top: 12px; border-top: 1px solid #E4E6EB; }
.rp-qr { width: 44px; height: 44px; fill: #1a1a1a; }
.rp-get { display: flex; flex-direction: column; gap: 1px; }
.rp-get b { font-family: 'Zalando Sans Expanded', -apple-system, sans-serif; font-size: 10px; font-weight: 600; }
.rp-get span { font-size: 8.5px; color: #7a7a7a; }
.rp-get em { font-style: normal; font-size: 10px; font-weight: 600; color: #0D45CC; }
.rp-gen { margin-left: auto; align-self: flex-end; font-size: 7.5px; color: #9a9a9a; }

/* On the desktop the page rises in beside the popover, as in the app's walkthrough. */
.screen-report {
  position: absolute;
  top: 64px;
  left: 120px;
  z-index: 3;
  transform-origin: 0 0;
  transform: translateY(60px) scale(var(--rs, 0.8));
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, transform 0.6s var(--spring), visibility 0s 0.6s;
}
.screen.is-report .screen-report {
  opacity: 1;
  visibility: visible;
  transform: scale(var(--rs, 0.8));
  transition: opacity 0.35s ease, transform 0.7s var(--spring), visibility 0s;
}

/* ── The cursor ────────────────────────────────────────── */

.kc-cursor {
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 28px;
  margin: -1.5px 0 0 -1.5px;
  pointer-events: none;
  z-index: 10;
  will-change: transform;
  filter: drop-shadow(0 2px 2.5px rgba(0, 0, 0, 0.35));
}

.kc-cursor svg {
  width: 20px;
  height: 28px;
  transform-origin: 1.5px 1.5px;
  transition: transform 0.12s ease-out;
}

.kc-cursor.is-down svg,
.kc-cursor.is-hold svg { transform: scale(0.84); }

.kc-ring {
  position: absolute;
  left: 0;
  top: 0;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  border: 1.5px solid var(--kc-ring);
  opacity: 0;
  pointer-events: none;
  z-index: 9;
}

.kc-ring.is-on { animation: kc-ring 0.5s ease-out; }

@keyframes kc-ring {
  from { opacity: 0.85; transform: scale(0.3); }
  to { opacity: 0; transform: scale(1); }
}

/* ── Front page: packshot ──────────────────────────────── */

.packshot {
  max-width: var(--column);
  margin: 0 auto;
  padding: 48px 28px 24px;
  text-align: center;
}

.packshot-icon {
  width: clamp(168px, 24vw, 272px);
  height: auto;
  margin: 0 auto;
  /* A wide, soft shadow with a little of the icon's blue. */
  filter: drop-shadow(0 18px 30px rgba(20, 40, 110, 0.20)) drop-shadow(0 4px 8px rgba(20, 40, 110, 0.12));
  transform: scale(var(--ps, 1));
  will-change: transform;
}

.packshot-name {
  font-family: var(--font-heading);
  font-size: clamp(54px, 9.4vw, 112px);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.035em;
  margin: 12px 0 16px;
}

.packshot-tagline {
  font-size: clamp(19px, 2vw, 24px);
  font-weight: 500;
  color: var(--muted);
  line-height: 1.3;
  margin: 0 auto 36px;
  max-width: 40rem;
  text-wrap: balance;
}

.packshot .store-pending { align-items: center; }

.features { margin-bottom: 0; }

/* ── Static steps (narrow screens, reduced motion, no script) ──
   Each caption beside one 300 pt wide piece of the app in that state, at the app's own
   size: the menu bar, the popover's list, or its side panel. */

.story-static {
  max-width: 1064px;
  margin: 0 auto;
}

.story-step {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: 48px;
  align-items: center;
  padding: 28px 0;
}

.story-step-shot {
  display: flex;
  justify-content: center;
  padding: 32px 16px;
  border-radius: 24px;
  background: var(--night-wallpaper);
  overflow: hidden;
}

.story-static .theme-switch { margin-top: 28px; }

.ss-pop {
  position: relative;
  width: 300px;
  height: 681px;
  overflow: hidden;
  border-radius: 12px;
}
.ss-pop .np {
  position: absolute;
  left: 0;
  top: -9px;
  width: 300px;
  transition: none;
}
.ss-pop .np-arrow { display: none; }
.ss-pop .np-body { border-radius: 12px; }
.ss-pop--side .np { width: 600px; left: -300px; }
.ss-pop--side .np-body { border-radius: 0 12px 12px 0; }
.ss-pop .ub { transform: none; transition: none; }
.ss-pop--limit { height: 400px; }
.ss-pop--short { height: 470px; }
.ss-pop--limit .np-body { height: 672px; }

/* The menu bar alone: only its right half, the status item first. */
.story-step-shot--bar {
  position: relative;
  display: block;
  padding: 0;
  min-height: 150px;
}
.ss-bar .menubar {
  justify-content: flex-end;
  border-radius: 24px 24px 0 0;
  overflow: hidden;
}
.ss-bar .mb-left { display: none; }
.ss-bar .mb-right > .mb-sym:not(.mb-wifi):not(.mb-hot) { display: none; }
.ss-bar .mb-right { flex: none; }

.story-step-shot--stack {
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding-top: 0;
}
.story-step-shot--stack .ss-bar { align-self: stretch; margin: 0 -16px; }
.story-step-shot--stack .ss-bar .menubar { position: relative; }
.story-step-shot--stack .nb {
  position: relative;
  top: auto;
  right: auto;
  width: 100%;
  max-width: 344px;
  opacity: 1;
  visibility: visible;
  transform: none;
}
.story-step-shot--stack > .nb:first-child { margin-top: 32px; }

.ss-report {
  width: 297.5px;
  height: 421px;
}
.ss-report .rp { transform: scale(0.5); transform-origin: 0 0; }

@media (max-width: 820px) {
  .story-step {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    padding: 24px 0;
  }
}

@media (max-width: 369px) {
  .story-step-shot > * { zoom: 0.9; }
}

/* ── Front page: NetTop Pro ────────────────────────────── */

.pro {
  max-width: var(--column);
  margin: 0 auto 128px;
  padding: 0 28px;
}

.pro-card {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(28px, 5vw, 48px);
  border-radius: 28px;
  background: var(--raised);
  box-shadow: inset 0 0 0 1px var(--rule), 0 24px 60px -30px rgba(20, 40, 110, 0.35);
  text-align: center;
}

.pro-mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.pro-mark img { width: 64px; height: 64px; }
.pro-mark h2 {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: clamp(30px, 4vw, 40px);
}

/* The paywall's Pro pill: navy gradient with a turquoise edge. */
.pro-pill {
  display: inline-block;
  padding: 3px 11px 4px;
  border-radius: 9px;
  background: linear-gradient(#092191, #001080);
  box-shadow: inset 0 1px 0 rgba(136, 216, 248, 0.55), 0 0 14px rgba(136, 216, 248, 0.3);
  color: #ffffff;
  font-family: var(--sans);
  font-size: 0.55em;
  font-weight: 600;
  letter-spacing: 0;
}

.pro-text {
  max-width: 34rem;
  margin: 18px auto 26px;
  color: var(--muted);
  font-size: 18px;
  line-height: 1.5;
  text-wrap: balance;
}

.pro-plans {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  text-align: left;
}

.pro-plan {
  padding: 18px 20px;
  border-radius: 16px;
  background: var(--raised-2);
}
.pro-plan b {
  display: block;
  font-family: var(--font-heading);
  font-size: 17px;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}
.pro-plan span { color: var(--muted); font-size: 15px; line-height: 1.45; }

.pro-note {
  margin: 22px 0 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
}

@media (max-width: 560px) {
  .pro-plans { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .pro { padding-inline: 18px; }
}

/* ── Mobile, two versions to choose from (?m=1, ?m=2; the head's script sets html.m1 or
   html.m2). Without either, narrow screens keep the static steps as they are. ───────── */

/* The mini iPhone of version 2 is only there in version 2. */
.ss-hot { display: none; }

/* Version 1: the live story under 821 px too, through a camera. The Mac is drawn large
   (--mac-w, showcase.js) and only part of it is in the window; --cam moves it to what the
   story is about. The iPhone comes up from below, at the shot's left (--phone-x). */
@media (max-width: 820px) and (prefers-reduced-motion: no-preference) {
  html.m1.js:not(.legacy) .story-track {
    display: block;
    position: relative;
    height: 1510vh;
  }
  html.m1.js:not(.legacy) .story-static { display: none; }
  html.m1.js .story:not(.is-ready) .story-track .mac { opacity: 0; }
  /* The stage runs edge to edge: the section's side padding would leave a strip of page
     either side of the shot. */
  html.m1 .story-track { margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }
  html.m1 .story-stage { overflow: hidden; }
  html.m1 .story-inner { width: 100%; }
  html.m1 .story-captions { padding: 0 20px; }
  html.m1 .story-caption h2 { font-size: 28px; }
  html.m1 .story-caption p { font-size: 16px; }
  html.m1 .mac {
    width: var(--mac-w, 100%);
    transform: translateX(var(--cam, 0px));
    transition: transform 0.9s cubic-bezier(0.3, 0, 0.15, 1);
  }
  html.m1 .story.is-still .mac { transition: none; }
  html.m1 .phone {
    left: var(--phone-x, 2.6%);
    width: var(--phone-w, 20%);
    bottom: -3%;
    transform: translateY(85%);
  }
  html.m1 .story.is-phone .phone { transform: none; }
}

/* Version 2: the static steps, each playing its part as it comes into view (.is-in,
   showcase.js): the picture rises in, the day's bars grow, the data limit runs from 35%
   to 84%, banners drop in; the hotspot step has a small iPhone whose link runs to the
   menu bar's hotspot icon; the titles fill letter by letter with the scroll (--p). */
html.m2 .story-step-shot {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s ease, transform 0.8s cubic-bezier(0.2, 0.7, 0.2, 1);
}
html.m2 .story-step.is-in .story-step-shot { opacity: 1; transform: none; }

html.m2 .story-step:not(.is-in) .ss-pop .ub { transform: scaleY(0); }
html.m2 .story-step.is-in .ss-pop .ub {
  transform: none;
  transition: transform 0.5s ease-out calc(0.3s + var(--i, 0) * 0.05s);
}

html.m2 .story-step:not(.is-in) .ul-fill { width: 35%; }
html.m2 .story-step.is-in .ul-fill { transition: width 1.4s cubic-bezier(0.4, 0, 0.2, 1) 0.6s, background-color 0.3s ease 1.6s; }
html.m2 .story-step:not(.is-in) .is-over .ul-fill { background: var(--p-blue); }

html.m2 .story-step-shot--stack .nb {
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 0.4s ease 0.45s, transform 0.6s cubic-bezier(0.3, 1.25, 0.5, 1) 0.45s;
}
html.m2 .story-step.is-in .story-step-shot--stack .nb { opacity: 1; transform: none; }

/* The hotspot step's iPhone: above the menu bar strip, at its left; the link (an SVG
   drawn by showcase.js) runs from its blue 9:41 capsule along and down into the strip's
   hotspot icon, with light flowing along it. */
html.m2 .ss-hot {
  display: block;
  position: relative;
  align-self: stretch;
  height: 168px;
  margin-bottom: -16px;   /* the phone stands on the menu bar strip */
}
html.m2 .ss-hot .phone {
  left: 6px;
  bottom: -12px;
  width: 86px;
  opacity: 0;
  visibility: visible;
  transform: translateY(30px);
  transition: opacity 0.4s ease, transform 0.8s cubic-bezier(0.3, 1.25, 0.5, 1);
  z-index: 3;
  --ps: 0.2;     /* 86 px of a 430 unit body: the screen's 402 points at 0.2 */
}
html.m2 .story-step.is-in .ss-hot .phone { opacity: 1; transform: none; }
html.m2 .story-step.is-in .ss-hot .ios-time { background: var(--ios-blue); color: #fff; transition-delay: 0.8s; }
html.m2 .ss-hot-step { position: relative; }
.ss-link {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  fill: none;
}
.ss-link path { stroke-linecap: round; stroke-linejoin: round; }
.ss-link .ss-link-glow { stroke: rgba(96, 160, 255, 0.35); stroke-width: 7; }
.ss-link .ss-link-core { stroke: #8fd3ff; stroke-width: 2; }
.ss-link .ss-link-flow { stroke: #fff; stroke-width: 3; stroke-dasharray: 0 12; filter: drop-shadow(0 0 3px #88d8f8); }
.ss-link path { stroke-dashoffset: 0; }
.ss-link .ss-link-glow,
.ss-link .ss-link-core { stroke-dasharray: 1 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.7s cubic-bezier(0.4, 0, 0.2, 1) 1s; }
.ss-link .ss-link-flow { opacity: 0; transition: opacity 0.3s ease 1.7s; }
.story-step.is-in .ss-link .ss-link-glow,
.story-step.is-in .ss-link .ss-link-core { stroke-dashoffset: 0; }
.story-step.is-in .ss-link .ss-link-flow { opacity: 1; animation: ss-flow 0.7s linear infinite; }
@keyframes ss-flow { to { stroke-dashoffset: -12; } }

/* Version 2 under reduced motion (it stands in for version 1 there): every step as it
   ends, nothing moving. */
@media (prefers-reduced-motion: reduce) {
  html.m2 .story-step-shot,
  html.m2 .story-step-shot--stack .nb,
  html.m2 .ss-hot .phone { opacity: 1; transform: none; transition: none; }
  html.m2 .ss-pop .ub { transform: none !important; transition: none; }
  html.m2 .ul-fill { transition: none; }
  html.m2 .ss-hot .ios-time { background: var(--ios-blue); color: #fff; transition: none; }
  .ss-link .ss-link-glow,
  .ss-link .ss-link-core { stroke-dashoffset: 0; transition: none; }
  .ss-link .ss-link-flow { display: none; }
  .story-fill { transition: none; }
}

/* ── Off the menu bar: the detached popover (steps 8 to 10) ──
   ProcessListView while detached: the close button (xmark.circle.fill, 22 pt) at the
   header's far left and the title moved from 12 to 24 pt, the pin (24 pt, 4 pt left of
   PRO), both fading in over 0.25 s. The pin off: tertiary label, turned 45 degrees; on:
   pin.fill in system yellow, upright, on a spring. No arrow on a window. */
.nh-close,
.nh-pin {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.nh-close {
  position: absolute;
  left: -2px;
  top: 2px;
  width: 22px;
  height: 22px;
  color: var(--p-tert);
}
.nh-close svg { width: 22px; height: 22px; }
.nh-close .g-fill { fill: currentColor; stroke: none; }
.nh-close .g-x { stroke: var(--p-bg); stroke-width: 1.8; opacity: 0.9; }
.nh-pin { right: 120px; color: var(--p-tert); }
.nh-pin svg {
  width: 13px;
  height: 13px;
  transform: rotate(45deg);
  transition: transform 0.45s cubic-bezier(0.3, 1.5, 0.5, 1), color 0.2s ease;
}
.nh-pin .g-pin { fill: none; }
.nh-title { transition: left 0.25s ease; }

.is-detached .nh-close,
.is-detached .nh-pin { opacity: 1; }
.is-detached .nh-title { left: 24px; }
.is-detached .np-arrow { opacity: 0; transition: opacity 0.2s ease; }
.is-pinned .nh-pin { color: var(--p-yellow); }
.is-pinned .nh-pin svg { transform: none; }
.is-pinned .nh-pin .g-pin { fill: currentColor; }

/* Dragged: the window follows the hand frame by frame. Thrown: WindowSnapEdgeManager's
   0.45 s flight with a small overshoot past the edge before it settles. */

/* The Spaces bar, as Mission Control shows it: a dark strip across the top with each
   desktop's picture and name; the chosen one is outlined. It comes down, the outline moves
   to Desktop 2, the desktop slides over, it goes up (.is-spaces, .is-space2). */
.spaces-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 6;
  height: 128px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 26px;
  padding-top: 16px;
  background: rgba(20, 20, 24, 0.55);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: 0 0.5px 0 rgba(255, 255, 255, 0.12);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;
  transform: translateY(-100%);
  opacity: 0;
  transition: transform 0.6s cubic-bezier(0.3, 0, 0.2, 1), opacity 0.45s ease;
  pointer-events: none;
}
.screen.is-spaces .spaces-bar { transform: none; opacity: 1; }
.sp-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: rgba(255, 255, 255, 0.85);
  font-size: 11px;
  font-weight: 500;
}
.sp-pic {
  position: relative;
  width: 140px;
  height: 88px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--night-wallpaper);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18), 0 4px 10px rgba(0, 0, 0, 0.3);
  transition: box-shadow 0.25s ease;
}
.sp-thumb--2 .sp-pic,
.sp-thumb--3 .sp-pic {
  background:
    radial-gradient(90% 80% at 85% 110%, rgba(150, 90, 255, 0.55), rgba(150, 90, 255, 0) 60%),
    linear-gradient(160deg, #1a1050 0%, #2a1a7a 45%, #120a3a 100%);
}
.sp-thumb--3 .sp-pic { filter: hue-rotate(60deg); }
/* The pinned NetTop window, small, in its place on the desktops it is on. */
.sp-win {
  position: absolute;
  left: 2%;
  top: 9%;
  width: 22%;
  height: 84%;
  border-radius: 2px;
  background: var(--p-bg);
  box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.2);
}
/* The window moves from Desktop 1's picture to Desktop 2's once Desktop 2 is chosen: it
   travels with you, it is not waiting there. */
.sp-thumb--2 .sp-win { opacity: 0; transform: translateX(-30%); transition: opacity 0.35s ease 0.25s, transform 0.45s cubic-bezier(0.3, 0, 0.2, 1) 0.25s; }
.screen.is-space2 .sp-thumb--2 .sp-win { opacity: 1; transform: none; }
/* ...and leaves Desktop 1's picture as it goes. */
.sp-thumb--1 .sp-win { transition: opacity 0.35s ease 0.25s, transform 0.45s cubic-bezier(0.3, 0, 0.2, 1) 0.25s; }
.screen.is-space2 .sp-thumb--1 .sp-win { opacity: 0; transform: translateX(30%); }
.sp-thumb--1 .sp-pic { box-shadow: 0 0 0 2.5px #fff, 0 4px 10px rgba(0, 0, 0, 0.3); }
.screen.is-space2 .sp-thumb--1 .sp-pic { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18), 0 4px 10px rgba(0, 0, 0, 0.3); }
.screen.is-space2 .sp-thumb--2 .sp-pic { box-shadow: 0 0 0 2.5px #fff, 0 4px 10px rgba(0, 0, 0, 0.3); }
.story.is-still .spaces-bar { transition: none; }

/* Under the bar, the current desktop as Mission Control shows it: its windows drawn
   together in the middle, scaled down; the menu bar gives way to the bar. */
.screen.is-detached .np {
  transform-origin: 50% 50%;
  transition: opacity 0.12s ease, width 0.42s var(--spring), left 0.42s var(--spring),
    translate 0.7s cubic-bezier(0.3, 0, 0.2, 1), scale 0.7s cubic-bezier(0.3, 0, 0.2, 1);
}
.screen.is-spaces .np {
  translate: var(--mc-x, 0px) var(--mc-y, 0px);
  scale: 0.58;
}
.screen .menubar { transition: opacity 0.3s ease; }
.screen.is-spaces .menubar { opacity: 0; }
.screen.is-detached.is-dragging .np { transition: opacity 0.12s ease, width 0.42s var(--spring); }
.screen.is-detached.is-throwing .np { transition: opacity 0.12s ease, width 0.42s var(--spring), left 0.45s cubic-bezier(0.25, 1, 0.45, 1.06), top 0.45s ease-out; }
.story.is-still .np { transition: none !important; }

/* Another desktop: it slides in from the right as macOS changes Spaces; the menu bar
   stays, and so does the pinned window (it is on every desktop). */
.screen-space {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(90% 80% at 85% 110%, rgba(150, 90, 255, 0.55), rgba(150, 90, 255, 0) 60%),
    radial-gradient(70% 70% at 10% 0%, rgba(60, 200, 220, 0.45), rgba(60, 200, 220, 0) 60%),
    linear-gradient(160deg, #1a1050 0%, #2a1a7a 45%, #120a3a 100%);
  transform: translateX(100%);
  transition: transform 0.9s cubic-bezier(0.5, 0, 0.2, 1);
}
.screen.is-space2 .screen-space { transform: none; }
.showcase[data-theme="light"] .sp-thumb--2 .sp-pic,
.showcase[data-theme="light"] .sp-thumb--3 .sp-pic,
.showcase[data-theme="light"] .screen-space {
  background:
    radial-gradient(90% 80% at 85% 110%, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 60%),
    linear-gradient(160deg, #c9b6ff 0%, #a98cf5 45%, #e2d8ff 100%);
}
@media (prefers-color-scheme: light) {
  .showcase:not([data-theme]) .sp-thumb--2 .sp-pic,
  .showcase:not([data-theme]) .sp-thumb--3 .sp-pic,
  .showcase:not([data-theme]) .screen-space {
    background:
      radial-gradient(90% 80% at 85% 110%, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 60%),
      linear-gradient(160deg, #c9b6ff 0%, #a98cf5 45%, #e2d8ff 100%);
  }
}
.story.is-still .screen-space { transition: none; }

/* The still of step 6 (mobile version 2, old browsers): the detached, pinned window. */
.ss-pop--detached .np-arrow { display: none; }

/* ── The usage panel's ranges: Today, Week, Month, Count (UsagePanelView) ──
   One set of each in the markup; the screen's range class (rng-week, rng-month,
   rng-count; none is Today) shows its segment, values, chart and list. Count shows its
   card (UsageCountView) in the data limit card's place. */
.nu-seg .sg-today { background: var(--p-seg-on); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0, 0, 0, 0.1); }
.rng-week .nu-seg .sg-today,
.rng-month .nu-seg .sg-today,
.rng-count .nu-seg .sg-today { background: none; box-shadow: none; }
.rng-week .nu-seg .sg-week,
.rng-month .nu-seg .sg-month,
.rng-count .nu-seg .sg-count { background: var(--p-seg-on); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0, 0, 0, 0.1); }
.nu-seg span { transition: background-color 0.15s ease; }

.rv, .rv-list, .uc--range, .uco { display: none; }
.rv-today { display: inline; }
.rv-list.rv-today { display: block; }
.rng-week .rv-today, .rng-month .rv-today, .rng-count .rv-today,
.rng-week .uc--today, .rng-month .uc--today, .rng-count .uc--today { display: none; }
.rng-week .rv-week, .rng-month .rv-month, .rng-count .rv-count { display: inline; }
.rng-week .rv-list.rv-week, .rng-month .rv-list.rv-month, .rng-count .rv-list.rv-count { display: block; }
.rng-week .uc--week, .rng-month .uc--month, .rng-count .uc--count { display: block; }
.rng-count .ul:not(.uco) { display: none; }
.rng-count .uco { display: block; }

/* A range's bars grow in as it opens, as Today's do. */
.uc--range .ub { transform: scaleY(0); transition: transform 0.35s ease-in-out; }
.rng-week .uc--week .ub, .rng-month .uc--month .ub, .rng-count .uc--count .ub {
  transform: none;
  transition-delay: calc(var(--i, 0) * 0.03s);
}
.uc--range .ub--future { transform: none; }

.uco { padding: 10px; }
.uco-btns { display: flex; gap: 6px; }
.uco-detail {
  margin-top: 8px;
  font-size: 11px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--p-ink);
}

/* ── The Dock, with NetTop's speed tile (DockTileSpeed) ── */
.dock {
  position: absolute;
  left: 50%;
  bottom: 5px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 66px;
  padding: 0 9px;
  transform: translateX(-50%);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: blur(20px) saturate(1.6);
  backdrop-filter: blur(20px) saturate(1.6);
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.35), 0 0 0 0.5px rgba(0, 0, 0, 0.25);
}
.dk-app, .dk-tile { width: 52px; height: 52px; flex: none; }
.dk-sep { width: 1px; height: 46px; background: rgba(255, 255, 255, 0.35); margin: 0 3px; }
.dk-tile { position: relative; }
.dk-tile > img { width: 100%; height: 100%; display: block; }
.dk-dot {
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
}
/* The plate: 56% of the tile tall, centred, a light frosted gradient and edge. */
.dk-plate {
  position: absolute;
  left: 3%;
  right: 3%;
  top: 22%;
  height: 56%;
  display: flex;
  flex-direction: column;
  gap: 6%;
  padding: 4.8%;
  box-sizing: border-box;
  border-radius: calc(var(--dk-s, 52px) * 0.123);
  background: linear-gradient(rgba(247, 247, 247, 0.42), rgba(217, 217, 217, 0.3));
  box-shadow: inset 0 0 0 0.75px rgba(255, 255, 255, 0.55);
}
/* Two dark panels, upload over download. */
.dk-row {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 calc(var(--dk-s, 52px) * 0.058);
  border-radius: calc(var(--dk-s, 52px) * 0.069);
  background: linear-gradient(rgba(71, 71, 71, 0.95), rgba(43, 43, 43, 0.95));
  box-shadow: inset 0 0 0 0.5px rgba(217, 217, 217, 0.3);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;
  line-height: 1;
}
.dk-row b { font-size: calc(var(--dk-s, 52px) * 0.144); font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; }
.dk-row em { margin-left: auto; font-style: normal; font-size: calc(var(--dk-s, 52px) * 0.081); font-weight: 600; color: rgba(158, 158, 158, 1); }
.dk-tri { width: 0; height: 0; border-left: calc(var(--dk-s, 52px) * 0.046) solid transparent; border-right: calc(var(--dk-s, 52px) * 0.046) solid transparent; flex: none; }
.dk-row--up .dk-tri { border-bottom: calc(var(--dk-s, 52px) * 0.077) solid rgb(255, 140, 13); filter: drop-shadow(0 0 1.2px rgba(255, 140, 13, 0.9)); }
.dk-row--down .dk-tri { border-top: calc(var(--dk-s, 52px) * 0.077) solid rgb(51, 209, 102); filter: drop-shadow(0 0 1.2px rgba(51, 209, 102, 0.9)); }

/* NetTop's place in the Dock: empty until "Show Dock icon" is on (.dock-on), then it opens
   up as macOS adds an icon (the slot widens, the icon rises in). */
.dk-tile {
  width: 0;
  margin: 0 -3px;
  opacity: 0;
  transform: translateY(14px) scale(0.6);
  transition: width 0.45s cubic-bezier(0.3, 0, 0.2, 1), margin 0.12s ease-out,
    opacity 0.3s ease 0.15s, transform 0.5s cubic-bezier(0.3, 1.4, 0.5, 1) 0.15s, scale 0.12s ease-out;
}
.dock-on .dk-tile { width: 52px; margin: 0 var(--dk-m, 0px); opacity: 1; transform: none; }
/* Magnification: each icon's size follows the pointer (showcase.js sets --dk-s per icon);
   the icons grow up from the Dock's floor and the Dock widens with them. */
.dock { align-items: flex-end; padding-bottom: 7px; box-sizing: border-box; }   /* icons grow up out of the bar */
/* Magnified: scaled about the icon's centre from the Dock's floor (--dk-k), with room
   made on both sides (--dk-m), so it grows out of its own middle. */
.dk-app, .dk-tile { scale: var(--dk-k, 1); transform-origin: 50% 100%; }
/* The Dock sits above ordinary and floating windows (its level is higher than both), so
   once the popover is a window of its own the Dock is over it; the attached popover
   (a pop-up menu level) stays above the Dock. */
.screen.is-detached .dock { z-index: 5; }
.dk-app { margin: 0 var(--dk-m, 0px); transition: scale 0.12s ease-out, margin 0.12s ease-out; }
.dk-tile { height: 52px; }
.dk-sep { align-self: center; }
.story.is-still .dk-tile { transition: none; }

/* The status item's right-click menu (PopupSettingMenu), under the status item. */
.sm {
  position: absolute;
  top: calc(var(--mb-h, 32px) + 2px);
  z-index: 8;
  width: 236px;
  padding: 5px;
  border-radius: 10px;
  background: rgba(40, 40, 42, 0.82);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  backdrop-filter: blur(30px) saturate(1.6);
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.5), inset 0 0 0 0.5px rgba(255, 255, 255, 0.14), 0 14px 34px -8px rgba(0, 0, 0, 0.5);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.88);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease, visibility 0s 0.12s;
}
.screen.is-menu .sm { opacity: 1; visibility: visible; transition: opacity 0.06s ease; }
.sm-item { position: relative; display: block; padding: 3px 10px 3px 22px; border-radius: 5px; line-height: 16px; }
.sm-item.is-hover { background: #0A64D2; color: #fff; }
.sm-check { position: absolute; left: 7px; font-style: normal; font-size: 11px; }
.sm-sep { display: block; height: 1px; margin: 5px 10px; background: rgba(255, 255, 255, 0.12); }

/* The Preferences window: 740 x 520, a 200 pt sidebar with the panes, General's form. */
.pw {
  position: absolute;
  left: 50%;
  top: 92px;
  z-index: 5;
  width: 740px;
  height: 520px;
  margin-left: -370px;
  display: flex;
  border-radius: 12px;
  overflow: hidden;
  background: var(--p-bg);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  backdrop-filter: blur(30px) saturate(1.6);
  box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.45), inset 0 0 0 0.5px var(--p-edge), 0 26px 60px -14px rgba(0, 0, 0, 0.6);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;
  color: var(--p-ink);
  opacity: 0;
  visibility: hidden;
  transform: scale(0.96);
  transition: opacity 0.2s ease, transform 0.25s ease, visibility 0s 0.25s;
}
.screen.is-prefs .pw { opacity: 1; visibility: visible; transform: none; transition: opacity 0.2s ease, transform 0.3s var(--spring); }
.pw-side {
  width: 200px;
  flex: none;
  padding: 50px 10px 10px;
  background: var(--p-drawer);
  box-shadow: inset -0.5px 0 0 var(--p-card-border);
  position: relative;
}
.pw-lights { position: absolute; left: 14px; top: 14px; display: flex; gap: 8px; }
.pw-lights i { width: 12px; height: 12px; border-radius: 50%; background: #FEBC2E; box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.2); }
.pw-lights i:first-child { background: #FF5F57; }
.pw-lights i:last-child { background: #28C840; }
.pw-pane { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; border-radius: 7px; font-size: 13px; }
.pw-pane.is-on { background: var(--p-card-hover); }
.pw-ico { width: 20px; height: 20px; border-radius: 5px; flex: none; }
.pw-ico--orange { background: #FF9500; }
.pw-ico--purple { background: #AF52DE; }
.pw-ico--red { background: #FF3B30; }
.pw-ico--blue { background: #007AFF; }
.pw-ico--yellow { background: #FFCC00; }
.pw-ico--mint { background: #00C7BE; }
.pw-main { flex: 1; padding: 16px 20px; }
.pw-title { font-size: 15px; font-weight: 700; margin-bottom: 26px; }
.pw-form-title { font-size: 12px; font-weight: 600; color: var(--p-2nd); margin: 0 0 8px 4px; }
.pw-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 40px;
  margin-bottom: 8px;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--p-card);
  box-shadow: inset 0 0 0 1px var(--p-card-border);
  font-size: 13px;
  box-sizing: border-box;
}
.pw-row b { display: block; font-weight: 400; }
.pw-row small { display: block; margin-top: 2px; font-size: 11px; color: var(--p-2nd); }
.pw-toggle { position: relative; display: block; width: 38px; height: 22px; border-radius: 999px; background: var(--p-track); transition: background-color 0.2s ease; }
.pw-toggle::after { content: ""; position: absolute; top: 1px; left: 1px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); transition: transform 0.25s cubic-bezier(0.3, 1.3, 0.5, 1); }
.pw-toggle.is-on, .dock-on .pw-toggle--dock { background: #0A84FF; }
.pw-toggle.is-on::after, .dock-on .pw-toggle--dock::after { transform: translateX(16px); }

/* The still of the Dock caption: the Dock alone, NetTop's tile in it. */
.story-step-shot--dock { align-items: center; min-height: 150px; }
.ss-dock { position: relative; width: 100%; height: 90px; }
.ss-dock .dock { bottom: 10px; left: 4px; transform: none; max-width: calc(100% - 8px); overflow: hidden; }

/* The demo is the app's English, left-to-right interface on a Mac in every language, so
   it keeps left to right on a right-to-left page (only the words around it turn). */
[dir="rtl"] .mac,
[dir="rtl"] .story-step-shot,
[dir="rtl"] .theme-switch { direction: ltr; }

