/* Calibro Software — the company level of the site.
   Serves `/` and `/explore/`. Calibro Track keeps its own stylesheet at
   /track/assets/css/site.css and is not affected by anything in this file.

   THE TOKEN BLOCK BELOW IS DUPLICATED from that file, deliberately and with a
   cost. There is no build step to share it, and the alternative — having the
   company home load a product's stylesheet — puts the umbrella downstream of
   one of the things under it. Two consequences worth knowing:

   - A colour change has to be made in both files or the two levels drift.
   - This is the second time the no-build choice has been paid for (the first
     is the header and footer copied into every page). site/README.md names a
     generator as the answer; this file is more evidence for it, not a
     counter-argument.

   Light only, matching Track. */

:root {
  color-scheme: light;

  --ink: #14171a;
  --ink-raised: #1b1f24;
  --ink-line: #2c3138;
  --text: #3c4149;
  --text-soft: #4a5058;
  --muted: #6b7280;
  --muted-on-ink: #a8afb8;

  --teal: #0b6e61;
  --teal-deep: #094f46;
  --teal-bright: #35c4b0;
  --teal-tint: #e6f5f2;
  --teal-wash: #f4fbf9;

  --white: #ffffff;
  --surface: #fafafa;
  --surface-2: #f7f8f9;
  --surface-3: #f1f2f4;
  --line: #e8eaed;
  --line-strong: #d4d7dc;

  --amber: #e56910;
  --amber-wash: #fff9f2;
  --red: #ae2e24;
  --red-wash: #fff7f6;

  --lz-neutral-bg: #f1f2f4;
  --lz-neutral-fg: #44546f;
  --lz-green-bg: #dffcf0;
  --lz-green-fg: #216e4e;
  --lz-amber-bg: #fff7d6;
  --lz-amber-fg: #7f5f01;

  --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --wrap: 1280px;
  --gutter: 56px;
  --radius: 6px;
}

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

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

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

body {
  margin: 0;
  background: var(--white);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4,
p {
  margin: 0;
}

h1,
h2,
h3,
h4 {
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  text-wrap: pretty;
}

img,
svg {
  max-width: 100%;
}

[hidden] {
  display: none !important;
}

a {
  color: var(--teal);
  text-decoration: none;
}

a:hover {
  color: var(--teal-deep);
  text-decoration: underline;
}

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

.mono {
  font-family: var(--mono);
}

/* ------------------------------------------------------------------ layout */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--white);
  font-size: 14px;
}

.skip-link:focus {
  left: 8px;
  top: 8px;
  color: var(--white);
  text-decoration: none;
}

/* Anything sharing an element with .wrap sets vertical padding with
   `padding-block`, never the shorthand — the shorthand resets padding-inline
   to 0 and puts content against the viewport edge. */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.measure {
  max-width: 620px;
}

.section {
  padding-block: 64px;
}

.section--surface {
  background: var(--surface);
}

.section--ink {
  background: var(--ink);
}

.section__head {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 36px;
}

.section__head h2 {
  font-size: 30px;
}

.section__head p {
  color: var(--text-soft);
}

.section--ink .section__head h2 {
  color: var(--white);
}

.section--ink .section__head p {
  color: var(--muted-on-ink);
}

/* ------------------------------------------------------------- components */

.eyebrow {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: 4px;
  background: var(--teal-tint);
  color: var(--teal);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
}

.lozenge {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  border-radius: 4px;
  background: var(--lz-neutral-bg);
  color: var(--lz-neutral-fg);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.lozenge--live {
  background: var(--lz-green-bg);
  color: var(--lz-green-fg);
}

.lozenge--soon {
  background: var(--lz-amber-bg);
  color: var(--lz-amber-fg);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 46px;
  padding: 0 24px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  text-align: center;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.btn:hover {
  text-decoration: none;
}

.btn--primary {
  background: var(--ink);
  color: var(--white);
}

.btn--primary:hover {
  background: #24282e;
  color: var(--white);
}

.btn--secondary {
  border-color: var(--line-strong);
  background: var(--white);
  color: var(--ink);
}

.btn--secondary:hover {
  border-color: #b9bdc4;
  background: var(--surface);
  color: var(--ink);
}

.btn--bright {
  background: var(--teal-bright);
  color: var(--ink);
  font-weight: 600;
}

.btn--bright:hover {
  background: #4ad3c0;
  color: var(--ink);
}

.btn--sm {
  height: 38px;
  padding: 0 18px;
  font-size: 14px;
}

.btn--block {
  width: 100%;
}

.btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid var(--line);
  background: var(--white);
}

.site-header__bar {
  display: flex;
  align-items: center;
  gap: 32px;
  padding-block: 20px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.brand:hover {
  color: var(--ink);
  text-decoration: none;
}

/* The old inline-SVG mark. Superseded on 8 August 2026 by `.brand__logo`, which
   references a file in /brand/ instead — this stays because Calibro Track's own
   17 pages still draw their caliper inline in the footer, and that drawing is
   the app icon Jira fetches rather than something the site is free to change.
   Nothing on the company pages uses it any more. */
.brand__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--ink);
}

/* The breadcrumb brand.

   Replaces the plain brand link on every page of the site. It exists because
   the header was doing two jobs in one row — saying which product you are in,
   and where you are inside it — and swapping between them page to page. The
   company name now never moves: it is the first thing in the header
   everywhere, always a link home, and the product name follows it.

   The right-hand nav still changes its items between products, and that is
   fine, because the rule behind it no longer changes: those links are always
   sections of whatever the last crumb names.

   Duplicated into /track/assets/css/site.css, like everything else here. */
.brandbar {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.brandbar__home {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
}

.brandbar__home:hover {
  color: var(--ink);
  text-decoration: none;
}

/* On the home page there is no second crumb, so the company is the page you
   are on and takes the weight the product name carries elsewhere. */
.brandbar__home.is-current {
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.brandbar__sep {
  color: #c2c7ce;
  font-size: 15px;
}

.brandbar__here {
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.brandbar__here:hover {
  color: var(--ink);
  text-decoration: none;
}

.brand__product {
  color: var(--muted);
  font-weight: 400;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  margin-left: 16px;
}

.site-nav a {
  color: var(--text);
  font-size: 14px;
}

.site-nav a[aria-current="page"] {
  padding-bottom: 2px;
  border-bottom: 2px solid var(--teal);
  color: var(--ink);
  font-weight: 600;
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-left: auto;
}

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 4px;
  margin-left: auto;
  padding: 8px 6px;
  border: 0;
  background: none;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--ink);
}

/* ------------------------------------------------------------ company home */

.home-hero {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
  padding-block: 72px 56px;
}

.home-hero h1 {
  max-width: 15ch;
  font-size: 48px;
}

.home-hero__sub {
  max-width: 56ch;
  color: var(--text-soft);
  font-size: 18px;
}

.home-hero__note {
  color: var(--muted);
  font-size: 14px;
}

/* Two products, one row. A third would want a different grid; at two, equal
   columns keep them visibly siblings rather than implying a ranking. */
.products {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.product {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  overflow: hidden;
}

.product__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 24px 28px 0;
}

.product__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--ink);
}

.product__name {
  font-size: 19px;
}

.product__head .lozenge {
  margin-left: auto;
}

.product__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 28px 28px;
}

.product__body p {
  color: var(--text-soft);
  font-size: 15px;
}

/* A card's one differentiating phrase, lifted out of the soft body colour the
   same way the carousel captions do — 600 against ink, never browser bold.
   One per element: emphasise two things in a card and it emphasises neither. */
.product__body strong {
  color: var(--ink);
  font-weight: 600;
}

.product__points {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.product__points li {
  position: relative;
  padding-left: 18px;
  color: var(--text-soft);
  font-size: 14px;
}

.product__points li::before {
  position: absolute;
  left: 0;
  color: var(--teal);
  content: "—";
}

.product__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: auto;
  padding: 20px 28px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}

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

.x-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  justify-items: start;
  padding-block: 64px 40px;
  text-align: left;
}

.x-hero h1 {
  max-width: 18ch;
  font-size: 46px;
}

.x-hero__sub {
  max-width: 62ch;
  color: var(--text-soft);
  font-size: 18px;
}

.x-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.x-hero__note {
  color: var(--muted);
  font-size: 14px;
}

/* --------------------------------------------------------------- carousel */

/* Without JS this is a horizontally scrollable strip with snap points — the
   arrows and dots are the enhancement, not the mechanism. */
.carousel {
  position: relative;
}

.carousel__viewport {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  border-radius: 10px;
}

.carousel__viewport::-webkit-scrollbar {
  display: none;
}

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

.carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
}

.carousel__frame {
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface-3);
  line-height: 0;
}

.carousel__frame img {
  display: block;
  width: 100%;
  height: auto;
}

/* A carousel whose slides are not all the same shape.
 *
 * /explore/ ships six screenshots that are all 16:9, so its frame can size
 * itself to the image and every slide comes out the same height. /pulse/ shows
 * one whole dashboard and then nine crops of individual widgets, whose aspect
 * ratios run from 1.3 to 11.6 — sized to their content, the frame grew taller
 * than the viewport on the first slide and then collapsed to a strip on the
 * next, so paging through it meant scrolling up and down to find where the
 * image had gone.
 *
 * This fixes the frame's height and fits each image inside it instead. Every
 * slide is now the same height, the controls and caption never move, and a
 * short-and-wide widget sits centred in the frame rather than pinned to the
 * top of it. Opt-in, because it is the wrong trade for a set of uniform
 * screenshots: /explore/ would gain letterboxing and lose pixels for nothing.
 */
.carousel--fit .carousel__frame {
  /* Tall enough to read a stage table, short enough that the first slide and
     its caption are both on screen without scrolling. */
  height: clamp(260px, 56vh, 560px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px;
}

.carousel--fit .carousel__frame img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
}

.carousel__caption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 14px;
}

.carousel__caption strong {
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
}

.carousel__caption span {
  color: var(--muted);
  font-size: 14px;
}

.carousel__controls {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 20px;
}

.carousel__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
}

.carousel__arrow:hover:not([disabled]) {
  border-color: #b9bdc4;
  background: var(--surface);
}

.carousel__arrow[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.carousel__dots {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.carousel__dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--line-strong);
  cursor: pointer;
}

.carousel__dot[aria-current="true"] {
  background: var(--teal);
}

/* --------------------------------------------------------------- features */

.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  border-block: 1px solid var(--line);
  background: var(--line);
}

.feature {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 32px 36px;
  background: var(--white);
}

.feature__num {
  color: var(--teal);
  font-family: var(--mono);
  font-size: 12px;
}

.feature h3 {
  font-size: 18px;
}

.feature p {
  color: var(--text-soft);
  font-size: 15px;
  text-wrap: pretty;
}

.feature code {
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--surface-3);
  font-family: var(--mono);
  font-size: 13px;
}

/* ------------------------------------------------------------ interest band */

.interest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 56px;
}

.interest__copy {
  max-width: 60ch;
}

.interest__copy h2 {
  margin-bottom: 8px;
  color: var(--white);
  font-size: 30px;
}

.interest__copy p {
  color: var(--muted-on-ink);
}

.honest {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 48px;
  padding-block: 56px;
}

.honest h2 {
  margin-bottom: 12px;
  color: var(--white);
  font-size: 30px;
}

.honest p {
  margin-bottom: 12px;
  color: var(--muted-on-ink);
}

.honest__panel {
  padding: 24px;
  border: 1px solid var(--ink-line);
  border-radius: 10px;
  background: var(--ink-raised);
}

.honest__panel h3 {
  margin-bottom: 14px;
  color: var(--white);
  font-size: 15px;
}

.honest__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 10px;
  border-top: 1px solid var(--ink-line);
  color: var(--muted-on-ink);
  font-size: 14px;
}

.honest__item span:first-child {
  color: var(--white);
}

.honest__status {
  color: var(--teal-bright);
  font-family: var(--mono);
  font-size: 12px;
}

/* ------------------------------------------------------------------ modal */

.modal {
  width: min(480px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  color: var(--text);
}

.modal::backdrop {
  background: rgb(20 23 26 / 0.55);
}

.modal__inner {
  padding: 28px;
}

.modal__head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 8px;
}

.modal__head h2 {
  font-size: 21px;
}

.modal__close {
  margin-left: auto;
  padding: 4px 8px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.modal__close:hover {
  color: var(--ink);
}

.modal p {
  color: var(--text-soft);
  font-size: 15px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 18px;
}

.field label {
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
}

.field input,
.field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
  font-family: inherit;
  font-size: 15px;
}

.field textarea {
  min-height: 76px;
  resize: vertical;
}

.field input:focus,
.field textarea:focus {
  border-color: var(--teal);
  outline: 2px solid var(--teal-tint);
  outline-offset: 0;
}

.field__hint {
  color: var(--muted);
  font-size: 13px;
}

.modal__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 22px;
}

.modal__privacy {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.modal__error {
  margin-top: 14px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: #fff7f6;
  color: var(--red);
  font-size: 14px;
}

.modal__done {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
}

.modal__done h2 {
  font-size: 21px;
}

/* ------------------------------------------------------- feedback dialog */

/* The kind-of-feedback picker. Real radios, visually pills: the input stays
   in the tree for keyboard and screen-reader use and the label carries the
   look, so there is no ARIA to hand-maintain. DUPLICATED in
   track/assets/css/site.css — the dialog is embedded on product pages from
   both design systems (/sketch/ here, /track/ there); edit the two
   together. */

.feedback-type {
  border: 0;
  padding: 0;
}

.feedback-type legend {
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  padding: 0;
  margin-bottom: 6px;
}

.feedback-type__options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.feedback-pill {
  position: relative;
  display: inline-flex;
}

.feedback-pill input {
  position: absolute;
  opacity: 0;
  inset: 0;
}

.feedback-pill span {
  padding: 7px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--white);
  color: var(--text);
  font-size: 14px;
  cursor: pointer;
}

.feedback-pill input:checked + span {
  border-color: var(--teal);
  background: var(--teal-tint);
  color: var(--teal-deep);
  font-weight: 500;
}

.feedback-pill input:focus-visible + span {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------- footer */

.site-footer {
  border-top: 1px solid var(--line);
}

.site-footer__inner {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
  padding-block: 40px 48px;
}

.site-footer__about {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 280px;
}

.site-footer__about .brand {
  font-size: 14px;
}

.site-footer__about .brand__mark {
  width: 22px;
  height: 22px;
  border-radius: 6px;
}

.site-footer__tagline {
  color: var(--muted);
  font-size: 13px;
  line-height: 1.6;
}

.site-footer__cols {
  display: flex;
  gap: 56px;
}

.site-footer__col {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.site-footer__col h2 {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
}

.site-footer__col a {
  color: var(--text);
  font-size: 14px;
}

.site-footer__bottom {
  border-top: 1px solid var(--line);
}

.site-footer__bottom-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 40px;
  padding-block: 20px 24px;
}

.site-footer__made {
  color: var(--muted);
  font-size: 13px;
}

.site-footer__copyright {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
}

/* ------------------------------------------------------------- responsive */

/* Brand marks are <img> references now, not inline SVG.

   The caliper used to be pasted into every page — which is why a logo change
   was a 20-file edit, and why the mark next to "Calibro Software" was still
   Track's drawing after the company level arrived. Each mark is one file in
   /brand/ now; the tile, the corner radius and the colours live in it.

   Sizes are set here and as width/height attributes on the element, so the
   header does not reflow while the file is still loading. */
.brand__logo {
  display: block;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
}

.brand__logo--sm {
  width: 22px;
  height: 22px;
}

.product__logo {
  display: block;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
}

@media (max-width: 900px) {
  :root {
    --gutter: 20px;
  }

  .site-header__bar {
    padding-block: 14px;
  }

  .site-nav,
  .site-header__actions {
    display: none;
  }

  .nav-toggle {
    display: flex;
  }

  .site-header[data-nav-open="true"] .site-nav,
  .site-header[data-nav-open="true"] .site-header__actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    width: 100%;
    margin: 0;
    padding: 8px 0 16px;
  }

  .site-header[data-nav-open="true"] .site-header__bar {
    flex-wrap: wrap;
  }

  .site-header[data-nav-open="true"] .site-nav a {
    padding: 10px 0;
    font-size: 16px;
  }

  .site-header[data-nav-open="true"] .site-nav a[aria-current="page"] {
    border-bottom: 0;
    color: var(--teal);
  }

  .site-header[data-nav-open="true"] .site-header__actions {
    padding-top: 12px;
    border-top: 1px solid var(--line);
  }

  .home-hero {
    padding-block: 44px 36px;
  }

  .home-hero h1 {
    font-size: 34px;
  }

  .home-hero__sub {
    font-size: 17px;
  }

  .x-hero {
    padding-block: 40px 28px;
  }

  .x-hero h1 {
    font-size: 32px;
  }

  .x-hero__sub {
    font-size: 17px;
  }

  .section {
    padding-block: 44px;
  }

  .section__head h2,
  .interest__copy h2,
  .honest h2 {
    font-size: 24px;
  }

  .products,
  .features {
    grid-template-columns: 1fr;
  }

  .honest {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  /* A single card is the whole viewport minus a peek of the next, which is what
     tells you the strip scrolls without an arrow to point at. */
  .carousel__slide {
    flex-basis: 92%;
  }

  .site-footer__inner {
    flex-direction: column;
    gap: 28px;
  }

  .site-footer__cols {
    flex-wrap: wrap;
    gap: 28px 40px;
  }

  .x-hero__actions .btn,
  .interest .btn {
    width: 100%;
  }
}

/* Very narrow phones. "Calibro Software / Calibro Explore" plus a hamburger
   does not fit across 320px, and the two obvious fixes are both worse than
   wrapping: hiding the company crumb removes the route home, which is the
   whole reason this breadcrumb exists, and truncating the product name to
   "Calibro Explo…" is the name people came for.

   So it wraps between the crumbs instead. Each crumb keeps `nowrap` so a
   product name never splits down the middle; only the gap between them is a
   break opportunity. The header grows a line on the smallest screens and
   nothing is lost. */
@media (max-width: 420px) {
  .brandbar {
    flex-wrap: wrap;
    row-gap: 0;
  }

  .brandbar__home,
  .brandbar__here {
    font-size: 14px;
  }

  .brandbar__home.is-current {
    font-size: 15px;
  }
}

/* ------------------------------------------------------------- page heading */

/* Title and standfirst for the pages that are prose rather than layout: the
   three legal pages and the 404.

   Moved here from track/assets/css/site.css on 18 August 2026, when the legal
   pages moved from /track/legal/ to /legal/ — a company-level document has no
   business depending on one product's stylesheet. See site/README.md. */
.page-head {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 760px;
  padding: 64px 0 24px;
}

.page-head h1 {
  font-size: 38px;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.page-head p {
  color: var(--text-soft);
  font-size: 17px;
  line-height: 1.65;
  text-wrap: pretty;
}

/* -------------------------------------------------------------- legal pages */

/* Long-form prose, narrower than the marketing measure. Legal text is read in
   full by the few people who read it at all, so it gets a comfortable line
   length and generous leading rather than the tighter marketing rhythm. */

.legal {
  max-width: 680px;
  padding-bottom: 80px;
}

.legal__updated {
  display: block;
  margin-bottom: 32px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
}

.legal section {
  margin-top: 40px;
}

.legal h2 {
  margin-bottom: 12px;
  font-size: 20px;
}

.legal h3 {
  margin: 24px 0 8px;
  font-size: 15px;
}

.legal p,
.legal li {
  font-size: 15px;
  line-height: 1.75;
}

.legal p + p {
  margin-top: 14px;
}

.legal ul {
  margin: 14px 0 0;
  padding-left: 20px;
}

.legal li {
  margin-bottom: 8px;
}

.legal li::marker {
  color: var(--line-strong);
}

.legal strong {
  color: var(--ink);
  font-weight: 600;
}

.legal code {
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--surface-3);
  font-family: var(--mono);
  font-size: 0.9em;
}

/* An unresolved decision, shown rather than hidden. These are the lines that
   need a person — a jurisdiction, a mailbox that exists — and a reader deserves
   to know which parts of a policy are not yet settled. Grep `legal__open` to
   find every one of them before launch. */
.legal__open {
  margin-top: 14px;
  padding: 14px 16px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text-soft);
  font-size: 14px;
}

.legal__open strong {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
  margin-bottom: 4px;
}

/* Placed after the base .page-head rules above, not inside the earlier
   @media (max-width: 900px) block with the rest of this file's responsive
   rules — .page-head's base rule lives below that block in source order, so
   a same-specificity override placed inside it loses the cascade tie and
   never takes effect. Confirmed by testing: the override was present and
   syntactically fine, and still didn't apply, until it moved down here. */
@media (max-width: 900px) {
  .page-head {
    padding: 32px 0 16px;
  }

  .page-head h1 {
    font-size: 28px;
  }

  .page-head p {
    font-size: 16px;
  }
}

/* --------------------------------------------------------------- changelog

   Ported verbatim from Track's per-product site.css so the /sketch/changelog/
   page reads identically to /track/changelog/. Lives in the shared sheet
   because Sketch loads calibro.css, not a product-scoped one; any later
   product with a changelog reuses these classes for free. */

.changelog {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 40px 0 48px;
  max-width: 860px;
}

.changelog > h1 {
  margin-bottom: 16px;
  font-size: 30px;
  letter-spacing: -0.02em;
}

.release {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: 28px;
  padding: 24px 0;
  border-top: 1px solid var(--line);
}

.release:last-of-type {
  border-bottom: 1px solid var(--line);
}

.release__when {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.release__when time {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 13px;
}

.release__version {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--text-soft);
  font-family: var(--mono);
  font-size: 11px;
}

.release__version--latest {
  background: var(--teal-tint);
  color: var(--teal);
}

.release__what {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.release__what h2 {
  font-size: 18px;
  letter-spacing: 0;
}

.release__what p {
  color: var(--text);
  font-size: 15px;
  line-height: 1.65;
  text-wrap: pretty;
}

.release__what a {
  font-size: 14px;
}

@media (max-width: 900px) {
  .changelog {
    padding: 28px 0 32px;
  }

  .changelog > h1 {
    font-size: 26px;
  }

  .release {
    grid-template-columns: 1fr;
    gap: 12px;
  }

  .release__when {
    flex-direction: row;
    align-items: center;
    gap: 10px;
  }
}

/* =================================================================== pricing
   Brought over from the Track site's landing refresh so Sketch carries the
   same one-sentence teaser on the landing page and the same rate table on
   /sketch/pricing/. Every value below is a token already defined at the top
   of this file, so the two products stay one design system. */

.pricing {
  display: grid;
  grid-template-columns: minmax(300px, 7fr) 5fr;
  align-items: center;
  gap: 48px;
  padding-block: 64px;
}

.pricing__copy {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pricing__copy h2 {
  font-size: 30px;
}

.pricing__copy p {
  color: var(--text-soft);
  text-wrap: pretty;
}

.pricing__note {
  font-size: 14px;
}

.pricing__figure {
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 32px 44px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--teal-wash);
}

.pricing__num {
  color: var(--teal-deep);
  font-family: var(--mono);
  font-size: 52px;
  font-weight: 500;
  line-height: 1;
}

.pricing__per {
  color: var(--text-soft);
  font-size: 13px;
}

.pricing__free {
  margin-top: 10px;
  padding: 3px 10px;
  border-radius: 12px;
  background: var(--teal-tint);
  color: var(--teal);
  font-size: 12px;
  font-weight: 600;
}

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

.pricing-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-block: 56px 72px;
}

.pricing-page h1 {
  font-size: 36px;
}

.pricing-page__lede {
  color: var(--text-soft);
  font-size: 18px;
  text-wrap: pretty;
}

.price-rows {
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--white);
}

.price-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 16px;
  padding: 14px 18px;
}

.price-row + .price-row {
  border-top: 1px solid var(--line);
}

.price-row__label {
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
}

.price-row__value {
  color: var(--text-soft);
  font-size: 14px;
}

.pricing-page__note {
  color: var(--text-soft);
  font-size: 14px;
}

.pricing-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* ------------------------------------------------------ marketplace rating
   Sits on the dark ink band, so its text is light rather than tokened. Kept
   in step with the Track site's .reviews__score. */

.reviews__score {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 32px 0 56px;
  color: #f4f6f8;
  font-size: 15px;
  font-weight: 600;
}

.reviews__score span {
  color: #f0a12e;
  font-size: 14px;
  letter-spacing: 2px;
}

.reviews__score a {
  color: var(--teal-bright);
  font-weight: 600;
}

@media (max-width: 900px) {
  .pricing {
    grid-template-columns: 1fr;
    gap: 28px;
    padding-block: 40px;
  }

  .pricing__figure {
    justify-self: start;
  }

  .price-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

/* ============================================================ hero showcase
   Sketch's landing leads with a two-column hero — copy beside an
   auto-advancing screenshot tour — mirroring the Track site. The other
   product pages keep the single-column .x-hero above, so this is a separate
   .hero that only Sketch opts into. The .heroshow markup and the crossfade
   autoplay in calibro.js are ported from track/assets/js/site.js. */

.hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
  padding-block: 64px 40px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.hero__copy h1 {
  max-width: 15ch;
  font-size: 46px;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.hero__sub {
  color: var(--text-soft);
  font-size: 18px;
  line-height: 1.6;
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.hero__note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-top: 4px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}

.hero__note::before {
  content: "";
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  margin-top: 8px;
  border-radius: 50%;
  background: var(--teal);
}

/* the auto-advancing screenshot tour ------------------------------------- */

.heroshow {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.heroshow__stage {
  display: grid;
}

/* Panels share one grid cell, so the stage always holds the height of the
   tallest and a swap never nudges the page. The hidden attribute is only the
   no-JS state: calibro.js strips it on boot and the crossfade below owns
   visibility from then on. */
.heroshow__panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.985);
  transition: opacity 0.55s ease, transform 0.55s ease, visibility 0s linear 0.55s;
}

.heroshow__panel[data-active="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.55s ease, transform 0.55s ease;
}

.heroshow__panel[hidden] {
  display: none;
}

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

/* A fixed frame, so six screenshots of different shapes fill one stable
   height instead of jumping — the same trade as .carousel--fit. */
.heroshow__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  height: clamp(220px, 36vh, 340px);
  padding: 12px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface-3);
  overflow: hidden;
}

.heroshow__frame img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
}

.heroshow__caption {
  color: var(--muted);
  font-size: 13px;
  text-wrap: pretty;
}

.heroshow__dots {
  display: flex;
  gap: 4px;
}

.heroshow__dots button {
  position: relative;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.heroshow__dots button::after {
  content: "";
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  background: var(--line-strong);
}

.heroshow__dots button[aria-pressed="true"]::after {
  background: var(--teal);
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 32px;
    padding-block: 40px 28px;
  }
}

/* Roadmap — the same content-page layout the changelog uses, one row per item.
   No voting: each row carries a mark in the left column instead of a vote
   control, which is what gives the list its rhythm — without something there
   the rows read as undifferentiated paragraphs. Status is the lozenge's job. */
.board__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 32px;
  padding: 40px 0 28px;
}

.board__intro {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 620px;
}

.board__intro h1 {
  margin-bottom: 8px;
  font-size: 30px;
  letter-spacing: -0.02em;
}

.board__intro p {
  color: var(--text-soft);
  line-height: 1.65;
  text-wrap: pretty;
}

.board__actions {
  flex: 0 0 auto;
}

.requests {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 48px;
}

/* Three columns: mark, item, status. Aligned to the start rather than centred
   because the summaries run to three or four lines, and a mark floating at the
   vertical middle of one looks unattached. */
.request {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) 130px;
  align-items: start;
  gap: 20px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 8px;
}

/* Decorative — the heading beside it says what the item is, so the SVG is
   aria-hidden. Teal stays the one accent; status colour is the lozenge's job. */
.request__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--teal-tint);
  border-radius: 10px;
  background: var(--teal-wash);
  color: var(--teal);
}

.request__main {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.request__main h2 {
  font-size: 17px;
  letter-spacing: 0;
}

.request__summary {
  color: var(--text-soft);
  font-size: 14px;
  line-height: 1.55;
  text-wrap: pretty;
}

.request__status {
  display: flex;
  justify-content: flex-end;
}

.lozenge--planned {
  background: var(--lz-neutral-bg);
  color: var(--lz-neutral-fg);
}

.lozenge--shipped {
  background: var(--lz-green-bg);
  color: var(--lz-green-fg);
}

@media (max-width: 900px) {
  .board__head {
    flex-direction: column;
    gap: 16px;
    padding: 28px 0 20px;
  }

  .board__intro h1 {
    font-size: 26px;
  }

  /* Mark and status share the top row; the title and summary run full width
     below. A 48px gutter down the side of a phone card would cost a quarter of
     the line length for the whole paragraph. */
  .request {
    grid-template-columns: 36px minmax(0, 1fr);
    align-items: center;
    gap: 10px 12px;
    padding: 16px;
  }

  .request__main {
    display: contents;
  }

  /* Placed explicitly. `.request__main` is `display: contents`, so the grid
     sees icon, heading, summary, status in DOM order and would otherwise drop
     the lozenge into a fourth row on its own. */
  .request__icon {
    grid-row: 1;
    grid-column: 1;
    width: 36px;
    height: 36px;
    border-radius: 8px;
  }

  .request__icon svg {
    width: 20px;
    height: 20px;
  }

  .request__status {
    grid-row: 1;
    grid-column: 2;
    justify-content: flex-start;
  }

  .request__main h2 {
    grid-column: 1 / -1;
    font-size: 16px;
    line-height: 1.35;
  }

  .request__summary {
    grid-column: 1 / -1;
  }

  .request .lozenge {
    height: 22px;
    padding: 0 8px;
    font-size: 11px;
  }
}
