/* bacpulse.com home page
   Brand values come from the app (src/styles.css, brand/BRAND.md).
   No external requests: fonts are self-hosted, the B mark is inline. */

@font-face {
  font-family: "Space Grotesk";
  src: url("assets/fonts/SpaceGrotesk-Latin.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* tokens the inline B mark reads */
  --bp-tx-orange: #FF8A1F;
  --bp-rx-green: #3BE05A;
  --bp-tx-tint: #DE8241;
  --bp-plate: #202020;
  --bp-metal-hi: #F2F3F5;

  /* page */
  --ground: #202020;     /* brand plate */
  --glow: #2A2C30;       /* splash glow */
  --panel: #27292C;
  --rule: #393B40;
  --rule-strong: #575B61;
  --ink-hi: #F2F3F5;     /* 14.7:1 on ground */
  --ink: #C4C7CB;        /* 9.6:1 */
  --ink-2: #A9ADB2;      /* 7.2:1 */
  --tx: #FF8A1F;         /* TX LED: leaves the laptop. Primary action. */
  --rx: #3BE05A;         /* RX LED: arrives. Signal only, never a fill. */
  --on-tx: #1E1F22;      /* 7.0:1 on TX orange */

  /* the app's dark theme, used only where the page shows the product */
  --app-bg: #090E13;
  --app-panel: #131920;
  --app-raised: #232932;
  --app-border: #363B42;
  --app-border-1: #474E56;
  --app-text-0: #EBEFF4;
  --app-text-1: #CFD5DC;
  --app-text-2: #A4ACB5;
  --app-mono: #A3B4C0;
  --app-warn: #F0B135;

  --sans: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --gutter: clamp(16px, 4vw, 40px);
  --max: 1200px;
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: 16px;
}

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

h1, h2, h3 {
  margin: 0;
  color: var(--ink-hi);
  font-weight: 600;
  text-wrap: balance;
}
h2 {
  font-size: clamp(1.875rem, 1.1rem + 2.6vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
}
h3 {
  font-size: clamp(1.25rem, 1.1rem + 0.45vw, 1.5rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
}
p { margin: 0 0 1em; max-width: 64ch; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0; padding: 0; }
img, svg { display: block; }

a {
  color: var(--ink-hi);
  text-decoration: underline;
  text-decoration-color: rgb(255 138 31 / 0.7);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
a:hover { text-decoration-color: var(--tx); }

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

/* MACs, device instances, baud rates, priorities, prices and the figures in
   the product mocks are set in mono. Durations in prose ("12 months",
   "30 days", "Month 0 to 12") stay in the text face. */
.n {
  font-family: var(--mono);
  font-size: 0.92em;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: 16px;
  top: -80px;
  z-index: 10;
  padding: 10px 14px;
  border-radius: 6px;
  background: var(--tx);
  color: var(--on-tx);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { top: 12px; }

.wrap {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 22px;
  border-radius: 6px;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: transform 150ms var(--ease-out), background-color 150ms, border-color 150ms;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(0.98); }
.btn-primary { background: var(--tx); color: var(--on-tx); }
.btn-primary:hover { background: #FF9B40; }
.btn-line {
  border: 1px solid var(--ink-2);
  color: var(--ink-hi);
}
.btn-line:hover { border-color: var(--ink-hi); background: rgb(242 243 245 / 0.06); }

/* ---------- header ---------- */

.site-head { border-bottom: 1px solid var(--rule); }
.head-row {
  display: flex;
  align-items: center;
  gap: 28px;
  min-height: 68px;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
  text-decoration: none;
}
.brand .bp-mark { width: 34px; height: 34px; }
.brand img { width: 120px; height: auto; }
.site-head nav ul { display: flex; gap: 26px; list-style: none; }
.site-head nav a {
  display: block;
  padding: 8px 0;
  color: var(--ink);
  font-size: 0.9375rem;
  text-decoration: none;
}
.site-head nav a:hover { color: var(--ink-hi); }

@media (max-width: 720px) {
  .nav-opt { display: none; }
}
@media (max-width: 400px) {
  .head-row { gap: 18px; }
  .site-head nav ul { gap: 18px; }
  .brand img { width: 104px; }
}

/* ---------- hero ---------- */

.hero {
  padding-top: clamp(44px, 7vw, 96px);
  background:
    radial-gradient(ellipse 60% 70% at 28% 38%, var(--glow), transparent 72%),
    var(--ground);
  border-bottom: 1px solid var(--rule);
}
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
}
.hero h1 {
  font-size: clamp(2.625rem, 1rem + 5.6vw, 5.5rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}
.lede {
  margin-top: 28px;
  max-width: 56ch;
  font-size: clamp(1.125rem, 1.02rem + 0.35vw, 1.3125rem);
  line-height: 1.55;
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
}
.hero-note {
  margin-top: 18px;
  color: var(--ink-2);
  font-size: 0.9375rem;
}

@media (max-width: 420px) {
  .actions .btn { flex: 1 1 100%; }
}

/* Two columns only where the frame log gets 346px or more, so no row wraps. */
@media (min-width: 1180px) {
  .hero-grid {
    grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
    align-items: end;
    gap: 48px;
  }
}
@media (max-width: 1179px) {
  .tk-log { max-width: 440px; }
}

/* the frame log: a piece of the app */
.tk-log {
  margin: 0;
  padding: 14px 16px 16px;
  background: var(--app-panel);
  border: 1px solid var(--app-border-1);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgb(0 0 0 / 0.35), inset 0 1px 0 rgb(255 255 255 / 0.04);
  color: var(--app-text-1);
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.5;
}
.tk-log-head {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--app-border);
  color: var(--app-text-2);
  font-size: 0.75rem;
}
.tk-log ol { display: grid; gap: 5px; list-style: none; }
.tk-log li {
  display: grid;
  grid-template-columns: 5ch 16ch minmax(0, 1fr);
  column-gap: 12px;
}
.dir { display: inline-flex; align-items: center; gap: 7px; color: var(--app-text-2); }
.dir::before {
  content: "";
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
}
.dir.tx::before { background: var(--tx); box-shadow: 0 0 6px rgb(255 138 31 / 0.6); }
.dir.rx::before { background: var(--rx); box-shadow: 0 0 6px rgb(59 224 90 / 0.5); }
.svc { color: var(--app-text-0); font-weight: 500; }
.det { color: var(--app-text-2); }
@media (min-width: 360px) {
  .tk-log .det { white-space: nowrap; }
}

@media (max-width: 380px) {
  .tk-log li { grid-template-columns: 4.6ch 15.5ch minmax(0, 1fr); column-gap: 9px; }
}

/* the trunk band
   From 840px up the whole drawing scales to fit; the text grows in drawing
   units as it shrinks, so it stays at about 12px or more on screen.
   Below 840px it shows a window from the left end (Bacpulse and the first
   controllers) and the trunk runs off the right edge. */
.trunk {
  margin-top: clamp(36px, 6vw, 64px);
  padding-bottom: 6px;
  overflow: hidden;
}
.trunk-svg {
  width: min(100%, 1200px);
  height: auto;
  margin-inline: auto;
}
.trunk-svg text {
  fill: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
}
.tk-lab text { fill: var(--ink-2); font-size: 12px; }

@media (max-width: 1089px) {
  .trunk-svg text { font-size: 14px; }
  .tk-lab text { font-size: 13.5px; }
  .tk-lab text:first-child { transform: translateX(-16px); }
}
@media (max-width: 959px) {
  .trunk-svg text { font-size: 16px; }
  .tk-lab text { font-size: 15.5px; }
  .tk-lab text:first-child { transform: translateX(-20px); }
}
/* window: x 0 to 740 of the drawing, Bacpulse plus MAC 1 to 3 */
@media (max-width: 839px) {
  .trunk-svg { width: calc(100% * 1090 / 740); max-width: none; margin-inline: 0; }
  .trunk-svg text, .tk-lab text { font-size: 15.5px; }
}
/* window: x 0 to 600, Bacpulse plus MAC 1 and 2 */
@media (max-width: 599px) {
  .trunk-svg { width: calc(100% * 1090 / 600); }
  .trunk-svg text, .tk-lab text { font-size: 16px; }
}
@media (max-width: 479px) {
  .trunk-svg text, .tk-lab text { font-size: 20px; }
  .tk-dev text { transform: translateX(4px); }
  .tk-lab text:not(:nth-child(2)) { display: none; }
}
.tk-box { fill: #2A2C30; stroke: #5A5E64; stroke-width: 1.2; }
.tk-term { fill: #8A8E94; }
.tk-led { fill: #5E646B; }
.tk-led-on { fill: var(--ink-hi); opacity: 0; }
.tk-pkt { opacity: 0; }
.tk-pkt-tx { fill: var(--tx); filter: drop-shadow(0 0 5px rgb(255 138 31 / 0.75)); }
.tk-pkt-rx { fill: var(--rx); filter: drop-shadow(0 0 5px rgb(59 224 90 / 0.65)); }
.tk-token { fill: var(--ink-hi); transform: translateX(890px); }
.tk-token-halo { opacity: 0.18; }

.bp-mark--hero .bp-svg-led-tx,
.bp-mark--hero .bp-svg-led-rx,
.bp-mark--hero .bp-svg-glow-tx,
.bp-mark--hero .bp-svg-glow-rx {
  transform-box: fill-box;
  transform-origin: center;
}

/* ---------- sections ---------- */

.sec { padding-block: clamp(72px, 10vw, 128px); }
.sec + .sec { border-top: 1px solid var(--rule); }

.intro {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink);
}
.split-head .intro { margin-top: 20px; }

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 36px;
}
@media (min-width: 980px) {
  .split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 72px;
  }
  .split-head { position: sticky; top: 40px; align-self: start; }
}

/* what it does on a job */
.jobs { list-style: none; }
.job { padding-block: 32px; border-top: 1px solid var(--rule); }
.job:first-child { padding-top: 0; border-top: 0; }
.job:last-child { padding-bottom: 0; }
.job h3 { margin-bottom: 12px; }

/* product depictions */
.mock { margin: 28px 0 0; }
.mock-win {
  overflow: hidden;
  background: var(--app-panel);
  border: 1px solid var(--app-border-1);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgb(0 0 0 / 0.35), inset 0 1px 0 rgb(255 255 255 / 0.04);
  color: var(--app-text-1);
  font-size: 0.875rem;
  line-height: 1.5;
}
.mock-cap {
  margin-top: 10px;
  color: var(--ink-2);
  font-size: 0.875rem;
}

.diag-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--app-border);
  color: var(--app-text-2);
  font-size: 0.8125rem;
}
.diag-score {
  color: var(--app-warn);
  font-family: var(--mono);
  font-size: 1.375rem;
  font-weight: 500;
  line-height: 1;
}
.diag-head span:last-child { margin-left: auto; }
.diag-list { list-style: none; }
.diag-list li {
  position: relative;
  padding: 14px 16px 14px 36px;
  border-top: 1px solid var(--app-border);
}
.diag-list li:first-child { border-top: 0; }
.diag-list li::before {
  content: "";
  position: absolute;
  left: 16px;
  top: 21px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--app-warn);
}
.diag-list b { display: block; color: var(--app-text-0); font-weight: 600; }

/* overrides */
.ovr {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px;
}
.ovr-copy h2 { margin-bottom: 20px; }
@media (min-width: 980px) {
  .ovr {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: 72px;
    align-items: start;
  }
  .ovr-mock { position: sticky; top: 40px; margin-top: 6px; }
}

.pa { margin: 32px 0 28px; }
.pa-slots {
  display: grid;
  grid-template-columns: repeat(16, minmax(0, 1fr));
  gap: 3px;
  max-width: 560px;
  list-style: none;
}
.pa-slots li {
  display: grid;
  place-items: center;
  height: clamp(34px, 5vw, 46px);
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.pa-slots .pa-block, .sw-block {
  border-color: var(--rule);
  background: repeating-linear-gradient(135deg, #34363A 0 3px, #26282B 3px 7px);
  color: var(--ink-2);
}
.pa-slots .pa-mine, .sw-mine {
  border-color: var(--tx);
  background: var(--tx);
  color: var(--on-tx);
  font-weight: 500;
}
@media (max-width: 400px) {
  .pa-slots { gap: 2px; }
  .pa-slots li { font-size: 0.6875rem; }
}
.pa-key {
  display: grid;
  gap: 8px;
  margin-top: 16px;
  list-style: none;
  font-size: 0.9375rem;
}
.pa-key li { display: flex; gap: 12px; align-items: baseline; }
.sw {
  flex: none;
  width: 14px; height: 14px;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  transform: translateY(2px);
}
.fine { color: var(--ink-2); font-size: 0.9375rem; }

.dlg { padding: 20px; }
.dlg-title {
  margin: 0 0 6px;
  color: var(--app-text-0);
  font-size: 1.0625rem;
  font-weight: 600;
}
.dlg-body { margin-bottom: 16px; color: var(--app-text-2); }
.dlg table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
.dlg th {
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--app-border-1);
  color: var(--app-text-2);
  font-weight: 500;
  text-align: left;
}
.dlg td {
  padding: 10px 10px 10px 0;
  border-bottom: 1px solid var(--app-border);
  vertical-align: top;
}
.dlg td small {
  display: block;
  color: var(--app-text-2);
  font-family: var(--mono);
  font-size: 0.75rem;
}
.dlg .pri { padding-right: 0; text-align: right; }
.dlg td.pri { font-family: var(--mono); }
.dlg-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}
.mbtn {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  border-radius: 6px;
  font-size: 0.8125rem;
  font-weight: 500;
  white-space: nowrap;
}
.mbtn-ghost { color: var(--app-text-1); }
.mbtn-sec { border: 1px solid var(--app-border-1); background: var(--app-raised); color: var(--app-text-0); }
.mbtn-pri { background: linear-gradient(#00CDB1, #00AD99); color: #010408; font-weight: 600; }

/* offline */
.code {
  margin: 0 0 1.25em;
  padding: 18px 20px;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  background: var(--app-bg);
  border: 1px solid var(--app-border-1);
  border-radius: 10px;
  color: var(--app-text-1);
  font-family: var(--mono);
  font-size: 0.875rem;
  line-height: 1.7;
}
.c-tx { color: var(--tx); font-weight: 500; }
.c-k { color: var(--app-mono); }
.c-s { color: var(--app-text-0); }
@media (max-width: 420px) {
  .code { padding: 14px 14px; font-size: 0.78rem; }
}

/* ---------- pricing ---------- */

.price-head { max-width: 760px; }
.price-head h2 { margin-bottom: 20px; }

/* trial card, then the license table; on narrow screens the prices come first */
.price-body { display: flex; flex-direction: column; }
.price-list { margin-top: 48px; }
@media (max-width: 860px) {
  .price-body .trial { order: 2; }
}

.trial {
  display: grid;
  gap: 20px 40px;
  margin-top: 44px;
  padding: clamp(20px, 3vw, 32px);
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: 10px;
}
.trial h3 { margin-bottom: 10px; }
.trial .btn { justify-self: start; }
@media (min-width: 860px) {
  .trial { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
}

.prices {
  width: 100%;
  border-collapse: collapse;
}
.prices thead th {
  padding: 0 16px 12px 0;
  border-bottom: 1px solid var(--rule-strong);
  color: var(--ink-2);
  font-size: 0.875rem;
  font-weight: 500;
  text-align: left;
  vertical-align: bottom;
}
.prices tbody th,
.prices td {
  padding: 24px 16px 24px 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  text-align: left;
}
.prices tbody th {
  color: var(--ink-hi);
  font-size: 1.3125rem;
  font-weight: 600;
  line-height: 1.25;
}
.plan-sub {
  display: block;
  margin-top: 4px;
  color: var(--ink-2);
  font-size: 0.9375rem;
  font-weight: 400;
}
.price {
  color: var(--ink-hi);
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
/* a mono comma takes a full cell at display size; pull the digits back in */
.price .sep { margin-inline: -0.2em; }
.prices td .n { color: var(--ink-hi); }
.save { display: block; color: var(--ink-2); font-size: 0.875rem; }
.prices .act { padding-right: 0; text-align: right; }
.prices .act .btn { white-space: nowrap; }
.row-quote th { font-size: 1.125rem; }
.quote-cell { color: var(--ink); }

@media (max-width: 860px) {
  .prices thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .prices, .prices tbody { display: block; }
  /* one card per license: plan and price side by side, per-laptop price
     under it, then the renewal line and the button across the card */
  .prices tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 14px 20px;
    padding-block: 24px;
    border-bottom: 1px solid var(--rule);
  }
  .prices tbody th, .prices td { display: block; padding: 0; border: 0; }
  .prices tbody th { grid-column: 1; grid-row: 1 / span 2; }
  .prices td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 2px;
    color: var(--ink-2);
    font-size: 0.8125rem;
  }
  .prices td[data-label="One-time price"] { grid-column: 2; grid-row: 1; text-align: right; }
  .prices td[data-label="One-time price"]::before { display: none; }
  .prices td[data-label="Per laptop"] { grid-column: 2; grid-row: 2; text-align: right; }
  .prices td[data-label="Laptops"], .prices td.dup { display: none; }
  .prices td[data-label="Update renewal"],
  .prices .act,
  .prices .row-quote th,
  .prices .quote-cell { grid-column: 1 / -1; grid-row: auto; }
  .prices .act { text-align: left; }
  .prices .act .btn { width: 100%; }
}

.price-foot { margin-top: 14px; color: var(--ink-2); font-size: 0.875rem; }

.price-more {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 56px;
  margin-top: 64px;
}
@media (min-width: 980px) {
  .price-more { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: 72px; }
}

.incl ul { margin-top: 16px; list-style: none; }
.incl li {
  position: relative;
  padding: 11px 0 11px 18px;
  border-top: 1px solid var(--rule);
}
.incl li:last-child { border-bottom: 1px solid var(--rule); }
.incl li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 21px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink-2);
}

/* the updates timeline: solid while updates are on, dashed after */
.upd-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-top: 24px;
  list-style: none;
}
.upd-bar li { padding: 2px 0 20px 22px; }
.upd-bar p { max-width: 40ch; }
.upd-on { background: linear-gradient(var(--tx), var(--tx)) left top / 4px 100% no-repeat; }
.upd-off {
  background: repeating-linear-gradient(180deg, var(--ink-2) 0 8px, transparent 8px 14px) left top / 4px 100% no-repeat;
}
.upd-when {
  display: block;
  margin-bottom: 4px;
  color: var(--ink-hi);
  font-weight: 600;
}
.upd-renew { margin-top: 12px; }
@media (min-width: 640px) {
  .upd-bar { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .upd-bar li { padding: 20px 28px 0 0; }
  .upd-on { background-size: 100% 4px; }
  .upd-off {
    background: repeating-linear-gradient(90deg, var(--ink-2) 0 10px, transparent 10px 18px) left top / 100% 4px no-repeat;
  }
  .upd-renew { margin-top: 24px; }
}

/* ---------- FAQ ---------- */

.faq details { border-top: 1px solid var(--rule); }
.faq details:last-child { border-bottom: 1px solid var(--rule); }
.faq summary {
  position: relative;
  padding: 20px 44px 20px 0;
  color: var(--ink-hi);
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.4;
  list-style: none;
  cursor: pointer;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 50%;
  width: 10px; height: 10px;
  border-right: 2px solid var(--ink-2);
  border-bottom: 2px solid var(--ink-2);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 200ms var(--ease-out);
}
.faq details[open] summary::after { transform: translateY(-25%) rotate(225deg); }
.faq summary:hover::after { border-color: var(--ink-hi); }
.faq-a { padding: 0 0 24px; }

/* ---------- contact and footer ---------- */

.contact h2 { margin-bottom: 18px; }
.mail-line { max-width: none; }
.mail-big {
  color: var(--ink-hi);
  font-size: clamp(1.75rem, 0.9rem + 4.2vw, 4rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  text-decoration-thickness: 2px;
  overflow-wrap: break-word;
}
.contact-note { margin-top: 24px; color: var(--ink-2); }

.site-foot {
  padding-block: 28px 36px;
  border-top: 1px solid var(--rule);
  color: var(--ink-2);
  font-size: 0.875rem;
}
.foot-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 32px;
}
.foot-row p { margin: 0; }

/* ---------- the one motion moment: Bacpulse joins the trunk ----------
   The trunk plays once, when it is half on screen: it waits on its first
   frame until assets/links.js adds .is-live to the hero. The frame log
   above it plays on load, because on a phone it is on screen first.
   Every animation ends on the same values the static rules above set, so
   with reduced motion, or without JavaScript (the <noscript> rule in
   index.html), the page simply shows the end state: Bacpulse in the ring,
   the frame log complete, both LEDs lit. */

@media (prefers-reduced-motion: no-preference) {
  .hero:not(.is-live) .trunk * { animation-play-state: paused; }

/* timeline in seconds after a 0.5s settle: token round, Poll-For-Master, Reply-To-PFM, token to Bacpulse, Who-Is, token on, I-Am x4 */
  .tk-token { animation: tk-token 7.3s linear 0.5s both; }
  .tk-pkt-rx { animation: tk-pkt-rx 7.3s linear 0.5s both; }
  .tk-pkt-tx { animation: tk-pkt-tx 7.3s linear 0.5s both; }
  .bp-mark--hero .bp-svg-led-rx { animation: tk-led-rx 7.3s linear 0.5s both; }
  .bp-mark--hero .bp-svg-glow-rx { animation: tk-glow-rx 7.3s linear 0.5s both; }
  .bp-mark--hero .bp-svg-led-tx { animation: tk-led-tx 7.3s linear 0.5s both; }
  .bp-mark--hero .bp-svg-glow-tx { animation: tk-glow-tx 7.3s linear 0.5s both; }
  .tk-dev-1 .tk-led-on { animation: tk-dev-1 7.3s linear 0.5s both; }
  .tk-dev-2 .tk-led-on { animation: tk-dev-2 7.3s linear 0.5s both; }
  .tk-dev-3 .tk-led-on { animation: tk-dev-3 7.3s linear 0.5s both; }
  .tk-dev-4 .tk-led-on { animation: tk-dev-4 7.3s linear 0.5s both; }
  .tk-log li { animation: tk-line 300ms var(--ease-out) both; }
  .tk-log li:nth-child(1) { animation-delay: 1.50s; }
  .tk-log li:nth-child(2) { animation-delay: 2.15s; }
  .tk-log li:nth-child(3) { animation-delay: 2.80s; }
  .tk-log li:nth-child(4) { animation-delay: 3.60s; }
  .tk-log li:nth-child(5) { animation-delay: 4.35s; }
  .tk-log li:nth-child(6) { animation-delay: 4.65s; }

  @keyframes tk-token {
    0% { transform: translateX(290px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    3.562% { transform: translateX(490px); }
    4.658% { transform: translateX(490px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    8.219% { transform: translateX(690px); }
    9.315% { transform: translateX(690px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    12.877% { transform: translateX(890px); }
    31.507% { transform: translateX(890px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    39.726% { transform: translateX(110px); }
    52.74% { transform: translateX(110px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    56.164% { transform: translateX(290px); }
    62.329% { transform: translateX(290px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    65.753% { transform: translateX(490px); }
    70.548% { transform: translateX(490px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    73.973% { transform: translateX(690px); }
    78.767% { transform: translateX(690px); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
    82.192% { transform: translateX(890px); }
    100% { transform: translateX(890px); }
  }

  @keyframes tk-pkt-rx {
    0% { transform: translateX(890px); opacity: 0; }
    13.699% { transform: translateX(890px); opacity: 0; }
    14.521% { transform: translateX(796.4px); opacity: 1; }
    19.726% { transform: translateX(203.6px); opacity: 1; }
    20.548% { transform: translateX(110px); opacity: 0; }
    56.849% { transform: translateX(290px); opacity: 0; }
    57.671% { transform: translateX(246.8px); opacity: 1; }
    59.452% { transform: translateX(153.2px); opacity: 1; }
    60.274% { transform: translateX(110px); opacity: 0; }
    66.438% { transform: translateX(490px); opacity: 0; }
    67.26% { transform: translateX(414.0px); opacity: 1; }
    69.726% { transform: translateX(186.0px); opacity: 1; }
    70.548% { transform: translateX(110px); opacity: 0; }
    74.658% { transform: translateX(690px); opacity: 0; }
    75.479% { transform: translateX(590.6px); opacity: 1; }
    78.63% { transform: translateX(209.4px); opacity: 1; }
    79.452% { transform: translateX(110px); opacity: 0; }
    82.877% { transform: translateX(890px); opacity: 0; }
    83.699% { transform: translateX(786.0px); opacity: 1; }
    88.219% { transform: translateX(214.0px); opacity: 1; }
    89.041% { transform: translateX(110px); opacity: 0; }
    100% { transform: translateX(110px); opacity: 0; }
  }

  @keyframes tk-pkt-tx {
    0% { transform: translateX(110px); opacity: 0; }
    22.603% { transform: translateX(110px); opacity: 0; }
    23.425% { transform: translateX(203.6px); opacity: 1; }
    28.63% { transform: translateX(796.4px); opacity: 1; }
    29.452% { transform: translateX(890px); opacity: 0; }
    42.466% { transform: translateX(110px); opacity: 0; }
    43.288% { transform: translateX(196.8px); opacity: 1; }
    50.548% { transform: translateX(963.2px); opacity: 1; }
    51.37% { transform: translateX(1050px); opacity: 0; }
    100% { transform: translateX(1050px); opacity: 0; }
  }

  @keyframes tk-led-rx {
    0% { opacity: 0.45; transform: scale(1); }
    20.411% { opacity: 0.45; transform: scale(1); }
    20.548% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    24.932% { opacity: 0.45; transform: scale(1); }
    39.589% { opacity: 0.45; transform: scale(1); }
    39.726% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    44.11% { opacity: 0.45; transform: scale(1); }
    60.137% { opacity: 0.45; transform: scale(1); }
    60.274% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    64.658% { opacity: 0.45; transform: scale(1); }
    70.411% { opacity: 0.45; transform: scale(1); }
    70.548% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    74.932% { opacity: 0.45; transform: scale(1); }
    79.315% { opacity: 0.45; transform: scale(1); }
    79.452% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    83.836% { opacity: 0.45; transform: scale(1); }
    88.904% { opacity: 0.45; transform: scale(1); }
    89.041% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    93.425% { opacity: 0.45; transform: scale(1); }
    94.521% { opacity: 0.45; transform: scale(1); animation-timing-function: ease-out; }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes tk-glow-rx {
    0% { opacity: 0.3; transform: scale(1); }
    20.411% { opacity: 0.3; transform: scale(1); }
    20.548% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    24.932% { opacity: 0.3; transform: scale(1); }
    39.589% { opacity: 0.3; transform: scale(1); }
    39.726% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    44.11% { opacity: 0.3; transform: scale(1); }
    60.137% { opacity: 0.3; transform: scale(1); }
    60.274% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    64.658% { opacity: 0.3; transform: scale(1); }
    70.411% { opacity: 0.3; transform: scale(1); }
    70.548% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    74.932% { opacity: 0.3; transform: scale(1); }
    79.315% { opacity: 0.3; transform: scale(1); }
    79.452% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    83.836% { opacity: 0.3; transform: scale(1); }
    88.904% { opacity: 0.3; transform: scale(1); }
    89.041% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    93.425% { opacity: 0.3; transform: scale(1); }
    94.521% { opacity: 0.3; transform: scale(1); animation-timing-function: ease-out; }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes tk-led-tx {
    0% { opacity: 0.45; transform: scale(1); }
    22.466% { opacity: 0.45; transform: scale(1); }
    22.603% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    26.986% { opacity: 0.45; transform: scale(1); }
    42.329% { opacity: 0.45; transform: scale(1); }
    42.466% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    46.849% { opacity: 0.45; transform: scale(1); }
    52.603% { opacity: 0.45; transform: scale(1); }
    52.74% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    57.123% { opacity: 0.45; transform: scale(1); }
    94.521% { opacity: 0.45; transform: scale(1); animation-timing-function: ease-out; }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes tk-glow-tx {
    0% { opacity: 0.3; transform: scale(1); }
    22.466% { opacity: 0.3; transform: scale(1); }
    22.603% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    26.986% { opacity: 0.3; transform: scale(1); }
    42.329% { opacity: 0.3; transform: scale(1); }
    42.466% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    46.849% { opacity: 0.3; transform: scale(1); }
    52.603% { opacity: 0.3; transform: scale(1); }
    52.74% { opacity: 1; transform: scale(1.12); animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    57.123% { opacity: 0.3; transform: scale(1); }
    94.521% { opacity: 0.3; transform: scale(1); animation-timing-function: ease-out; }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes tk-dev-1 {
    0% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    4.795% { opacity: 0; }
    56.712% { opacity: 0; }
    56.849% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    61.644% { opacity: 0; }
    62.192% { opacity: 0; }
    62.329% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    67.123% { opacity: 0; }
    100% { opacity: 0; }
  }

  @keyframes tk-dev-2 {
    0% { opacity: 0; }
    4.521% { opacity: 0; }
    4.658% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    9.452% { opacity: 0; }
    66.301% { opacity: 0; }
    66.438% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    70.411% { opacity: 0; }
    70.548% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    71.233% { opacity: 0; }
    75.342% { opacity: 0; }
    100% { opacity: 0; }
  }

  @keyframes tk-dev-3 {
    0% { opacity: 0; }
    9.178% { opacity: 0; }
    9.315% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    14.11% { opacity: 0; }
    74.521% { opacity: 0; }
    74.658% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    78.63% { opacity: 0; }
    78.767% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    79.452% { opacity: 0; }
    83.562% { opacity: 0; }
    100% { opacity: 0; }
  }

  @keyframes tk-dev-4 {
    0% { opacity: 0; }
    13.562% { opacity: 0; }
    13.699% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    18.493% { opacity: 0; }
    31.37% { opacity: 0; }
    31.507% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    36.301% { opacity: 0; }
    82.74% { opacity: 0; }
    82.877% { opacity: 1; animation-timing-function: cubic-bezier(0.2, 0.6, 0.3, 1); }
    87.671% { opacity: 0; }
    100% { opacity: 0; }
  }

  @keyframes tk-line {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
