/* Site styles: element defaults, the shared layout (header, footer, page container, phone install
   bar) and the few semantic components the pages use. Every value comes from tokens.css; nothing
   here names a colour, a typeface or a size of its own. */

/* Element defaults */

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

html {
  color: var(--ink);
  background: var(--surface);
  font-family: var(--font-text);
  line-height: var(--leading-text);
  /* Every figure on the site is tabular, so numbers line up wherever they are compared. */
  font-variant-numeric: tabular-nums;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: var(--surface);
  font-size: var(--text-md);
}

main {
  flex: 1;
}

h1,
h2,
h3 {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-display);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-display);
}

h2 {
  font-size: var(--text-2xl);
  font-weight: var(--weight-heading);
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-heading);
}

h3 {
  font-size: var(--text-lg);
  font-weight: var(--weight-heading);
  letter-spacing: -0.01em;
  line-height: var(--leading-title);
}

p,
ul,
ol,
dl,
dd,
table {
  margin: 0;
}

p {
  text-wrap: pretty;
}

ul,
ol {
  padding-inline-start: 1.25em;
}

strong {
  font-weight: var(--weight-strong);
}

a {
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}

a:hover {
  text-decoration-color: currentColor;
}

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: var(--space-3) var(--space-4) var(--space-3) 0;
  border-bottom: 1px solid var(--line);
  text-align: start;
  vertical-align: top;
}

thead th {
  border-bottom-color: var(--line-strong);
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

svg {
  display: block;
  flex: none;
}

/* The hidden attribute wins over any display a component sets. */
[hidden] {
  display: none !important;
}

::selection {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}

/* Layout */

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

/* The default main: pages other than the home page are one column inside the container. */
.page {
  padding-block: var(--section-y);
}

.skip-link {
  position: absolute;
  z-index: 100;
  top: var(--space-3);
  left: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: var(--surface);
  font-weight: var(--weight-strong);
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

.site-header {
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}

.site-header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: var(--header-height);
}

/* The navigation and the action sit together at the far end, opposite the wordmark. */
.site-nav {
  margin-inline-start: auto;
}

.site-nav ul {
  display: flex;
  gap: var(--space-5);
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-sm);
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  /* A link never breaks in two: where the header runs short, the not-yet-listed status wraps. */
  white-space: nowrap;
}

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

/* The header's call to action is the smaller sibling of the hero's. */
.site-header .button {
  min-height: var(--control-sm);
  padding-inline: var(--space-4);
  font-size: var(--text-sm);
}

/* From tablet up the header, and its install action, stay in view. Phones get the bottom bar. */
@media (width >= 40rem) {
  .site-header {
    position: sticky;
    z-index: 10;
    top: 0;
  }

  /* A section a link scrolls to stops below the header that covers the top of the page. */
  section[id] {
    scroll-margin-top: var(--header-height);
  }
}

@media (width < 40rem) {
  /* On a phone the not-yet-listed status would crowd the wordmark; the hero states it right
     below. */
  .site-header .button-unavailable {
    display: none;
  }

  /* Every link but one goes too (layout.peb marks them): the wordmark, one page link and the
     action are all that fit, and the footer still lists the others. */
  .site-nav .from-tablet {
    display: none;
  }
}

/* Until the app is listed, the status that stands in for the button is twice its width, so the
   marked links wait for a tablet held upright. */
@media (width < 48rem) {
  .site-header:has(.button-unavailable) .site-nav .from-tablet {
    display: none;
  }
}

/* The narrowest phones fit the wordmark and the action only; the action then takes the far end
   the navigation held. */
@media (width < 22.5rem) {
  .site-nav {
    display: none;
  }

  .site-header .button {
    margin-inline-start: auto;
  }
}

.site-footer {
  padding-block: var(--space-7);
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: var(--text-sm);
}

.site-footer-inner {
  display: grid;
  gap: var(--space-7);
}

.site-footer .wordmark {
  font-size: 1.125rem;
}

.site-footer-operator {
  margin-top: var(--space-3);
}

/* As many link columns as fit: three, or two on the narrowest phones. */
.site-footer-nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
  gap: var(--space-6) var(--space-5);
}

/* A column's title. */
.site-footer-nav p {
  color: var(--ink);
  font-weight: var(--weight-strong);
}

.site-footer-nav ul {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 0;
  list-style: none;
}

.site-footer-nav a {
  color: var(--ink-2);
  text-decoration: none;
}

.site-footer-nav a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* From tablet up the brand keeps the left and the link columns line up at the right. */
@media (width >= 48rem) {
  .site-footer-inner {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .site-footer-nav {
    grid-template-columns: repeat(3, auto);
    column-gap: var(--space-8);
  }
}

/* Phone only: the install action pinned to the bottom once the page's opening has scrolled away.
   site.js sets data-visible; without script the bar stays hidden and the page's own buttons remain. */
.install-bar {
  display: none;
}

@media (width < 40rem) {
  .install-bar {
    display: block;
    position: fixed;
    z-index: 20;
    right: 0;
    bottom: 0;
    left: 0;
    padding: var(--space-3) var(--gutter);
    border-top: 1px solid var(--line);
    background: var(--surface);
    box-shadow: var(--shadow-bar);
    transform: translateY(100%);
    visibility: hidden;
    transition:
      transform var(--duration) var(--ease-out),
      visibility 0s linear var(--duration);
  }

  .install-bar[data-visible] {
    transform: none;
    visibility: visible;
    transition: transform var(--duration) var(--ease-out);
  }

  .install-bar .button {
    width: 100%;
  }

  /* Keeps the end of the footer clear of the bar. */
  body:has(.install-bar) .site-footer {
    padding-bottom: calc(var(--space-7) + 4.5rem);
  }
}

/* Components */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-md);
  padding-inline: var(--space-5);
  border-radius: var(--radius-md);
  background: var(--accent);
  box-shadow:
    0 1px 2px rgb(14 17 22 / 0.14),
    inset 0 1px 0 rgb(255 255 255 / 0.1);
  color: var(--accent-ink);
  font-size: var(--text-md);
  font-weight: var(--weight-strong);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--duration) var(--ease-out);
}

.button:hover {
  background: var(--accent-hover);
}

/* Not listed on the App Store yet: a status, not a control. Outlined, no hover, and allowed to
   wrap because its sentence is longer than any button label. */
.button-unavailable,
.button-unavailable:hover {
  background: transparent;
  padding-inline: var(--space-4);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-wrap: balance;
  white-space: normal;
  cursor: default;
}

.button-unavailable::before {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--accent);
  content: "";
  flex: none;
}

/* A secondary text action beside a button, with a drawn arrow pointing where it goes. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--control-md);
  color: var(--ink);
  font-weight: var(--weight-strong);
  text-decoration: none;
}

.link-arrow svg {
  width: 1rem;
  height: 1rem;
  transition: transform var(--duration) var(--ease-out);
}

.link-arrow:hover svg {
  transform: translateY(2px);
}

/* A link onward to another page: its arrow points right, so it moves right. */
.link-arrow-onward:hover svg {
  transform: translateX(2px);
}

/* Home: hero */

.hero {
  padding-block: clamp(3rem, 1.6rem + 5.6vw, 6.5rem) clamp(3.5rem, 2.4rem + 4.4vw, 6rem);
}

.hero-audience {
  margin-bottom: var(--space-5);
  color: var(--ink-2);
  font-weight: var(--weight-medium);
}

.hero-lead {
  max-width: var(--measure-lead);
  color: var(--ink-2);
  font-size: var(--text-lg);
  line-height: var(--leading-lead);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-6);
}

.hero-actions .button {
  min-height: var(--control-lg);
}

/* The hero's button gets more room; the not-listed status keeps its own tighter padding. */
.hero-actions .button:not(.button-unavailable) {
  padding-inline: var(--space-6);
}

.hero-note {
  max-width: var(--measure-note);
  margin-top: var(--space-4);
  color: var(--ink-3);
  font-size: var(--text-sm);
}

.hero-body {
  margin-top: var(--space-6);
}

/* Wide screens: the headline on the left in three lines, the case for it and the action on the
   right, bottoms aligned. The product screenshot will sit full width below both. */
@media (width >= 72rem) {
  .hero-inner {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: end;
    column-gap: var(--space-6);
  }

  .hero-title {
    grid-column: 1 / span 6;
  }

  .hero-body {
    grid-column: 8 / -1;
    margin-top: 0;
    padding-bottom: var(--space-2);
  }
}

/* Bands: a page laid out as full-width sections (home, pricing). Every band has the same vertical
   room and the even ones are tinted, so sections alternate white and tint without a class each.
   :where() around the whole selector gives both rules no specificity: they are defaults, and a
   section's own class (.hero, .final-call) overrides them wherever it sits in this file. */
:where(.bands > section) {
  padding-block: var(--section-y);
}

:where(.bands > section:nth-of-type(even)) {
  border-block: 1px solid var(--line);
  background: var(--surface-tint);
}

/* The headline of a band whose content runs the full width below it. */
.band-heading {
  /* Its own measure: a headline at --text-2xl breaks into two or three lines of even length. */
  max-width: 44rem;
  margin-bottom: var(--space-7);
}

/* The install call that closes a band's content, with the line under it if it has one. */
.band-action {
  margin-top: var(--space-6);
}

.band-action p {
  max-width: var(--measure-note);
  margin-top: var(--space-4);
  color: var(--ink-2);
}

/* A band in two parts: the headline, with its paragraph if it has one, and beside it the content
   that backs it up. One column on phones and tablets. */
.split {
  display: grid;
  gap: var(--space-7);
}

/* The paragraph under a headline, and a paragraph that is the whole answer beside one. */
.split-lead > p,
.split-body > p {
  max-width: 32rem;
  color: var(--ink-2);
  font-size: var(--text-lg);
  line-height: 1.55;
}

.split-lead > p {
  margin-top: var(--space-5);
}

@media (width >= 60rem) {
  .split {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
    column-gap: var(--space-6);
  }

  /* The headline stays beside its content while a taller right column scrolls past it. */
  .split-lead {
    position: sticky;
    top: calc(var(--header-height) + var(--space-7));
    grid-column: 1 / span 5;
  }

  .split-body {
    grid-column: 7 / -1;
  }
}

/* The worked example, set like the bottom of a profit and loss statement: deductions under the
   revenue, a single rule above the result and the accountant's double rule under it. The calculator
   under it and the plan card (further down) are the same panel: the places the page shows money. */
.statement,
.calculator,
.plan,
.utm-presets,
.utm-builder {
  width: 100%;
  max-width: var(--measure-panel);
  padding: var(--space-5) var(--space-5) var(--space-6);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-panel);
}

@media (width >= 40rem) {
  .statement,
  .calculator,
  .plan,
  .utm-presets,
  .utm-builder {
    padding: var(--space-6) var(--space-7) var(--space-7);
  }
}

/* Separate borders so the result's rule above and double rule below both draw in full. */
.statement table {
  border-collapse: separate;
  border-spacing: 0;
}

.statement caption {
  padding-bottom: var(--space-3);
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
  text-align: start;
}

.statement th,
.statement td {
  padding: var(--space-3) 0;
  border-top: 1px solid var(--line);
  border-bottom: 0;
  font-size: var(--text-md);
  line-height: var(--leading-panel);
}

.statement th {
  padding-inline-end: var(--space-4);
  color: var(--ink-2);
  font-weight: 400;
}

.statement td {
  color: var(--ink);
  font-family: var(--font-figures);
  font-weight: var(--weight-medium);
  text-align: end;
  white-space: nowrap;
}

/* The given spend opens the example; a heavier rule closes it off from the arithmetic it feeds. */
.statement-given th,
.statement-given td {
  padding-bottom: var(--space-4);
  border-top: 0;
}

.statement-given + tbody tr:first-child > * {
  border-top-color: var(--line-strong);
}

.statement-deduction td {
  color: var(--ink-2);
}

/* The bottom line, of the statement and of the calculator that repeats it. */
.statement tfoot th,
.statement tfoot td,
.calculator-profit {
  padding-block: var(--space-4);
  border-top: 1px solid var(--ink);
  border-bottom: 3px double var(--ink);
  color: var(--ink);
  font-size: var(--text-xl);
  /* The one figure set heavier than a heading: the result the panel exists for. */
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* The sentence under a bottom line: the statement's verdict, the calculator's break-even line. */
.statement-verdict,
.calculator-line {
  margin-top: var(--space-5);
  color: var(--ink);
  font-size: var(--text-lg);
  font-weight: var(--weight-strong);
  line-height: var(--leading-panel);
}

/* The calculator: the statement again with the reader's numbers. Rows of label and field, then
   the result set like the statement's bottom line. */

/* Flat, so the example above it stays the one raised panel of the pair. The UTM builder sits
   under a channel's presets the same way. */
.calculator,
.utm-builder {
  margin-top: var(--space-5);
  box-shadow: none;
}

.calculator-fields {
  margin-top: var(--space-4);
}

/* A row: label and field, under the hairline the statement's rows have. */
.calculator-fields > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  border-top: 1px solid var(--line);
}

.calculator-fields label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  color: var(--ink-2);
  line-height: var(--leading-title);
}

/* The unit a share is measured in. */
.calculator-fields label span {
  color: var(--ink-3);
  font-size: var(--text-sm);
}

/* On a phone the unit fits beside the shortest label only, so every label puts it on a line of
   its own and the three shares read alike. */
@media (width < 40rem) {
  .calculator-fields label {
    flex-direction: column;
  }
}

/* The box around a figure. It, not the input inside, draws the border, so the dollar sign sits in
   the same box as the amount. */
.calculator-field {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-2);
  width: 8.5rem;
  min-height: var(--control-sm);
  margin-block: var(--space-2);
  padding-inline: var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-3);
}

.calculator-field:hover {
  border-color: var(--ink-3);
}

/* The ring sits on the box's own border, not at the usual distance from it. */
.calculator-field:focus-within {
  border-color: var(--accent);
  outline: var(--focus-ring);
  outline-offset: 0;
}

/* Empty, negative or out of range: the field the message under the result is about. */
.calculator-field:has(:invalid) {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.calculator input {
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  /* The box shows the focus. */
  outline: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-weight: var(--weight-medium);
  text-align: end;
  /* A figure, not a stepper: the spin buttons would sit where the number's last digit aligns. */
  appearance: textfield;
}

/* Chrome and Safari draw the spin buttons through these pseudo-elements. */
.calculator input::-webkit-inner-spin-button,
.calculator input::-webkit-outer-spin-button {
  appearance: none;
}

/* The result row: label and figure at the two ends, ruled as the statement's bottom line is. */
.calculator-profit {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 var(--space-4);
  line-height: var(--leading-panel);
}

.calculator-profit strong {
  font-family: var(--font-figures);
  font-weight: inherit;
}

/* With no profit row above it the message opens the result, so it takes the row's rule. */
.calculator-profit[hidden] + .calculator-line {
  margin-top: 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
}

/* Home: what you get. Four columns under a full rule, like the heads of a market table. */

.benefits {
  display: grid;
  gap: var(--space-6);
  padding: 0;
  list-style: none;
}

.benefits > li {
  display: grid;
  align-content: start;
  row-gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
}

.benefits p {
  color: var(--ink-2);
}

@media (width >= 40rem) {
  .benefits {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Titles wrap to different heights. Sharing the list's rows starts every sentence on one line. */
  .benefits > li {
    grid-row: span 2;
    grid-template-rows: subgrid;
  }
}

@media (width >= 72rem) {
  .benefits {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Home: how it works. The steps are a sequence, so each carries its number in the display face. */

.steps {
  padding: 0;
  border-top: 1px solid var(--ink);
  list-style: none;
  counter-reset: step;
}

.steps > li {
  display: grid;
  grid-template-columns: var(--space-7) minmax(0, 1fr);
  row-gap: var(--space-2);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--line);
  counter-increment: step;
}

.steps > li::before {
  grid-row: span 2;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-heading);
  /* The numeral's top sits on the title's first line. */
  line-height: 0.9;
  content: counter(step);
}

.steps p {
  grid-column: 2;
  color: var(--ink-2);
}

/* Home: what's inside. Six answers in a ruled grid, read across like the cells of a table. */

.answers {
  display: grid;
  padding: 0;
  border-top: 1px solid var(--ink);
  list-style: none;
}

.answers > li {
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--line);
}

.answers p {
  margin-top: var(--space-2);
  color: var(--ink-2);
}

/* In columns every cell but the first of a row gets a rule on its left and room either side of
   it. Six cells fill two columns or three with no cell left alone on a row. */
@media (width >= 40rem) {
  .answers {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .answers > li {
    padding-inline: var(--space-5);
    border-inline-start: 1px solid var(--line);
  }
}

@media (40rem <= width < 72rem) {
  .answers > li:nth-child(2n + 1) {
    padding-inline-start: 0;
    border-inline-start: 0;
  }
}

@media (width >= 72rem) {
  .answers {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .answers > li:nth-child(3n + 1) {
    padding-inline-start: 0;
    border-inline-start: 0;
  }
}

/* Home: platforms. Meta and Google Ads side by side, the same size: neither is the add-on. */

.platforms {
  display: grid;
  gap: var(--space-6);
}

.platforms > div {
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
}

.platforms dt {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-heading);
  letter-spacing: var(--tracking-heading);
  line-height: var(--leading-title);
}

.platforms dd {
  margin-top: var(--space-2);
  color: var(--ink-2);
}

@media (width >= 40rem) {
  .platforms {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* A list of statements, one to a line between hairlines, under a full rule. */
.ruled-list {
  padding: 0;
  border-top: 1px solid var(--ink);
  list-style: none;
}

.ruled-list > li {
  padding-block: var(--space-4);
  border-bottom: 1px solid var(--line);
}

/* The plan card: the billing period, the price for it, what is included and the install call. */

/* The two periods as one segmented control. The presets a UTM builder starts from are the same
   control. */
.plan-period,
.preset-choice {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
}

/* A choice is a label holding its radio button and, after it, its name in a span. The span draws
   the choice, so the chosen one is read from the radio button beside it (:checked + span) and
   every browser shows it, with or without :has(). */
.plan-period label,
.preset-choice label {
  display: inline-flex;
  position: relative;
  cursor: pointer;
}

.plan-period span,
.preset-choice span {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-sm);
  padding-inline: var(--space-5);
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

/* The radio button itself covers its label, invisible: it keeps the arrow keys, the focus and its
   name for screen readers, and the span after it draws the control. */
.plan-period input,
.preset-choice input,
.channel-choice input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.plan-period :checked + span,
.preset-choice :checked + span,
.channel-choice :checked + span {
  background: var(--ink);
  color: var(--surface);
}

/* The invisible radio button cannot show its own focus ring, so the span after it does. */
.plan-period :focus-visible + span,
.preset-choice :focus-visible + span,
.channel-choice :focus-visible + span {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* Only the chosen period's price shows. A browser without :has() shows both, which is still true. */
.plan:has([value="monthly"]:checked) [data-period="annual"],
.plan:has([value="annual"]:checked) [data-period="monthly"] {
  display: none;
}

.plan-price {
  margin-top: var(--space-6);
}

.plan-amount {
  color: var(--ink-2);
  font-size: var(--text-lg);
}

.plan-amount strong {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  /* One line, never wrapped: the price takes its own height and no more. */
  line-height: 1;
}

.plan-note {
  margin-top: var(--space-2);
  color: var(--ink-2);
}

.plan-included-label {
  margin-top: var(--space-6);
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

.plan-included {
  margin-top: var(--space-3);
  padding: 0;
  list-style: none;
}

.plan-included > li {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-top: 1px solid var(--line);
  line-height: var(--leading-panel);
}

/* A drawn tick: two sides of a small box, turned. */
.plan-included > li::before {
  flex: none;
  width: 0.375rem;
  height: 0.6875rem;
  border: solid var(--ink);
  border-width: 0 var(--stroke-mark) var(--stroke-mark) 0;
  transform: translateY(-0.0625rem) rotate(45deg);
  content: "";
}

.plan-action {
  margin-top: var(--space-5);
}

/* The card's one action spans it. */
.plan-action .button {
  width: 100%;
}

.plan-action p {
  margin-top: var(--space-3);
  color: var(--ink-3);
  font-size: var(--text-sm);
}

/* Questions: each opens and closes on its own (details), between hairlines under a full rule. */

.questions {
  border-top: 1px solid var(--ink);
}

.questions details {
  border-bottom: 1px solid var(--line);
}

.questions summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-4);
  /* Replaces the browser's disclosure triangle with the chevron drawn below. */
  list-style: none;
  cursor: pointer;
}

/* Safari draws its triangle through this pseudo-element, not through list-style. */
.questions summary::-webkit-details-marker {
  display: none;
}

/* A drawn chevron: two sides of a small box. Drawn once, for a question and for a select of the
   UTM builder; each places and turns its own below. */
.questions summary::after,
.builder-select::after {
  width: 0.5625rem;
  height: 0.5625rem;
  border: solid var(--ink-3);
  border-width: 0 var(--stroke-mark) var(--stroke-mark) 0;
  content: "";
}

/* A question's chevron: turned down when closed and up when open. */
.questions summary::after {
  flex: none;
  margin-inline: var(--space-2);
  transform: translateY(-25%) rotate(45deg);
  transition: transform var(--duration) var(--ease-out);
}

.questions details[open] > summary::after {
  transform: translateY(25%) rotate(-135deg);
}

.questions summary:hover::after {
  border-color: var(--ink);
}

.questions details > p {
  max-width: var(--measure);
  padding-bottom: var(--space-5);
  color: var(--ink-2);
}

/* Home: the final call. The page's one band on the accent, laid out like the hero it answers. */

.final-call {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}

.final-call h2 {
  color: inherit;
  font-size: var(--text-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-display);
}

.final-call-body {
  margin-top: var(--space-6);
}

.final-call-body p {
  max-width: var(--measure-lead);
  color: color-mix(in srgb, var(--accent-ink) 84%, transparent);
  font-size: var(--text-lg);
  line-height: var(--leading-lead);
}

.final-call-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-6);
}

/* On the accent the button turns over: white, with the accent as its text. */
.final-call .button {
  min-height: var(--control-lg);
  background: var(--accent-ink);
  color: var(--accent);
}

.final-call .button:not(.button-unavailable) {
  padding-inline: var(--space-6);
}

.final-call .button:hover {
  background: var(--surface-tint);
}

/* The not-listed status keeps its outline, drawn in white on the accent. */
.final-call .button-unavailable,
.final-call .button-unavailable:hover {
  background: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-ink) 50%, transparent);
  color: var(--accent-ink);
}

.final-call .button-unavailable::before {
  background: var(--accent-ink);
}

.final-call .link-arrow {
  color: inherit;
}

/* The accent ring would vanish on the accent. */
.final-call :focus-visible {
  outline-color: var(--accent-ink);
}

@media (width >= 72rem) {
  .final-call-inner {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: end;
    column-gap: var(--space-6);
  }

  .final-call h2 {
    grid-column: 1 / span 7;
  }

  .final-call-body {
    grid-column: 9 / -1;
    margin-top: 0;
    padding-bottom: var(--space-2);
  }
}

/* UTM builder: the choice of channel, the chosen channel's presets set as a panel like the worked
   example, and under it the builder, laid out like the calculator. */

/* A tool's headline names the tool in a handful of words, where the display size is cut for a
   slogan of two or three: a step down, so it sets in two lines beside the tool and not in four. */
.tool-title {
  font-size: var(--text-3xl);
}

/* The channels as one control, like the plan's two periods, but too many for one line: a grid of
   equal cells, two to a row on a phone and three from tablet up. Each cell draws its own border
   and overlaps its neighbours' by one pixel, so the rules between cells stay hairlines and a last
   row that is not full needs no filler. The padding is the room that overlap takes. */
.channel-choice {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: var(--measure-panel);
  padding: 0 1px 1px 0;
}

@media (width >= 40rem) {
  .channel-choice {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* A cell overlaps the next one's border, and its span (the plan toggle's kind of choice, above)
   fills it. */
.channel-choice label {
  display: flex;
  position: relative;
  margin: 0 -1px -1px 0;
  cursor: pointer;
}

/* The cell as drawn: a name that may take two lines on the narrowest phones, centred in a target
   a thumb can hit. Positioned, so the chosen and the focused one can lie over their neighbours. */
.channel-choice span {
  display: flex;
  position: relative;
  flex: 1;
  align-items: center;
  justify-content: center;
  min-height: var(--control-md);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
  line-height: var(--leading-title);
  text-align: center;
}

/* The chosen cell's border is its own colour, and lies over the neighbours' it overlaps. */
.channel-choice :checked + span {
  z-index: 1;
  border-color: var(--ink);
}

/* The focus ring must not pass under the next cell. */
.channel-choice :focus-visible + span {
  z-index: 2;
}

/* Only the chosen channel shows: one selector per channel of UtmParameters.channels, which
   UtmBuilderTest holds complete. A browser without :has() shows them all, which is still true. */
.utm-tool:has([value="meta"]:checked) .utm-channel:not([data-channel="meta"]),
.utm-tool:has([value="google"]:checked) .utm-channel:not([data-channel="google"]),
.utm-tool:has([value="tiktok"]:checked) .utm-channel:not([data-channel="tiktok"]),
.utm-tool:has([value="pinterest"]:checked) .utm-channel:not([data-channel="pinterest"]),
.utm-tool:has([value="microsoft"]:checked) .utm-channel:not([data-channel="microsoft"]),
.utm-tool:has([value="klaviyo"]:checked) .utm-channel:not([data-channel="klaviyo"]) {
  display: none;
}

.utm-channel {
  margin-top: var(--space-5);
}

/* A panel's title is the page's second level but sits inside a panel, so it takes the size of the
   calculator's title, not of a band's headline. */
.utm-tool h2 {
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  line-height: var(--leading-title);
}

.utm-tool h2 + p {
  margin-top: var(--space-3);
  color: var(--ink-2);
}

/* A preset: its name, what it gives, and its string, ruled off from what is above it. */
.utm-preset {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

/* A preset's name labels a string inside a panel: set in the text face, a step under the panel's
   title, so the serif stays with the titles. */
.utm-preset h3 {
  font-family: var(--font-text);
  font-size: var(--text-md);
  font-weight: var(--weight-strong);
  letter-spacing: 0;
}

.utm-preset h3 + p {
  margin-top: var(--space-1);
  color: var(--ink-2);
}

/* The settings of a channel that builds its own parameters: rows like the builder's fields, the
   setting's name beside what to choose. */
.utm-settings {
  margin-top: var(--space-5);
}

/* A setting's name stays at the top of its row, however many lines its choice takes. */
.utm-settings dt {
  align-self: start;
}

.utm-settings dd {
  color: var(--ink);
  line-height: var(--leading-panel);
}

/* What to know before relying on the parameters: a quiet label, then one statement to a line
   between hairlines, as the plan card lists what is included. */
.utm-caveats-label {
  margin-top: var(--space-6);
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

.utm-caveats {
  margin-top: var(--space-3);
  padding: 0;
  list-style: none;
}

.utm-caveats > li {
  padding-block: var(--space-3);
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  line-height: var(--leading-panel);
}

/* Which channels AdZoom matches orders for, closing the statements above it under their rule. */
.utm-unmatched {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  line-height: var(--leading-panel);
}

/* The guide or the documentation to read next, side by side while they fit. */
.utm-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-5);
  padding: 0;
  list-style: none;
}

/* A macro or a parameter named in a sentence. */
.utm-tool :is(p, li, dd) code,
.shopify-facts code {
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* How Shopify records UTM parameters: each statement a small title and its paragraph, kept to a
   readable measure where the list runs the width of a tablet. */
.shopify-facts p {
  max-width: var(--measure);
  margin-top: var(--space-2);
  color: var(--ink-2);
}

/* The sentence under a string and its Copy button, where a guide opens with the recommended
   set: why these parameters. */
.parameters + p {
  margin-top: var(--space-4);
  color: var(--ink-2);
}

/* A string to paste, with its Copy button under it. */
.parameters {
  margin-top: var(--space-4);
}

/* The string itself, ruled off from the text around it. It breaks before an "&" (the spans below),
   and inside a pair only when the pair alone is wider than the block, so it never pushes a phone
   screen sideways. */
.parameters > code {
  display: block;
  padding: var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-tint);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-text);
  overflow-wrap: anywhere;
  /* One click selects the whole string: it is only ever copied whole. */
  -webkit-user-select: all;
  user-select: all;
}

/* One key=value pair: it moves to the next line whole. */
.parameters > code span {
  display: inline-block;
}

.parameters-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3);
}

/* Copy is the panel's action, not the page's: drawn in ink like the chosen channel, so the one
   button on the accent stays the install call. */
.parameters-copy button {
  min-height: var(--control-sm);
  padding-inline: var(--space-5);
  border: 0;
  border-radius: var(--radius-md);
  background: var(--ink);
  color: var(--surface);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
  cursor: pointer;
  transition: background-color var(--duration) var(--ease-out);
}

.parameters-copy button:hover {
  background: var(--ink-2);
}

/* What the button just did, or what to do when the browser refused. */
.parameters-copy p {
  flex: 1;
  /* With less room than this beside the button, the message wraps to a line of its own under
     it instead of standing in a narrow column. */
  min-width: 12rem;
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: var(--leading-title);
}

/* What the control or the string under it is: "Start from", "Your URL parameters". */
.builder-label {
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

.utm-builder > .builder-label {
  margin-top: var(--space-5);
}

.preset-choice {
  margin-top: var(--space-2);
}

.builder-fields {
  margin-top: var(--space-5);
}

/* A row: the field's name and the value chosen for it, under the hairline the calculator's rows
   have. On a phone the value sits under the name and takes the panel's width. */
.builder-fields > div,
.utm-settings > div {
  display: grid;
  gap: var(--space-2);
  padding-block: var(--space-3);
  border-top: 1px solid var(--line);
}

@media (width >= 40rem) {
  /* The value's column is wide enough for the picker's longest name ("Ad group or asset group
     id") beside the chevron; the field's name takes the rest. */
  .builder-fields > div {
    grid-template-columns: minmax(0, 1fr) 17rem;
    column-gap: var(--space-4);
  }

  /* A setting's choice is a sentence, not a control, so it takes the wider column. The name's
     column holds the longest name with its parameter ("Campaign utm_campaign") on one line. */
  .utm-settings > div {
    grid-template-columns: 12rem minmax(0, 1fr);
    column-gap: var(--space-5);
  }
}

.builder-fields label,
.utm-settings dt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  color: var(--ink-2);
  line-height: var(--leading-title);
}

/* Beside its select the name sits on the select's middle line, however far a text field or a
   note under the select reaches. */
@media (width >= 40rem) {
  .builder-fields label {
    align-content: center;
    align-self: start;
    min-height: var(--control-sm);
  }
}

/* The parameter the field writes. */
.builder-fields label span,
.utm-settings dt span {
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}

.builder-value {
  display: grid;
  gap: var(--space-2);
}

/* The same box the calculator's figures sit in, for a choice and for typed text. */
.builder-fields select,
.builder-fields input {
  width: 100%;
  min-height: var(--control-sm);
  padding-inline: var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-weight: var(--weight-medium);
}

.builder-fields select:hover,
.builder-fields input:hover {
  border-color: var(--ink-3);
}

/* The ring sits on the box's own border, as the calculator's does. */
.builder-fields select:focus-visible,
.builder-fields input:focus-visible {
  border-color: var(--accent);
  outline-offset: 0;
}

/* Typed text is pasted as written, so it is set like the result. */
.builder-fields input {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* The browser's own arrow goes; the chevron drawn below takes its place and its room. On the
   narrowest phones the longest value's name ends in an ellipsis instead of under the chevron. */
.builder-fields select {
  padding-inline-end: var(--space-6);
  text-overflow: ellipsis;
  appearance: none;
  cursor: pointer;
}

.builder-select {
  display: block;
  position: relative;
}

/* The chevron drawn for the questions (above), turned down at the select's end. Clicks pass
   through to the select. */
.builder-select::after {
  position: absolute;
  top: 50%;
  right: var(--space-4);
  transform: translateY(-75%) rotate(45deg);
  pointer-events: none;
}

/* Which campaign types leave the chosen value empty. */
.builder-note {
  color: var(--ink-3);
  font-size: var(--text-sm);
  line-height: var(--leading-title);
}

/* The result, ruled off from the fields as the calculator's profit row is. */
.builder-result {
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
}

/* Under its label ("Your URL parameters") the string sits closer than under a preset's
   description: the label names it, so the two read as one. */
.builder-result .parameters {
  margin-top: var(--space-3);
}

/* What the chosen values mean for matching orders: a warning opens in ink, a note stays quiet. */
.builder-status p {
  margin-top: var(--space-5);
  color: var(--ink-2);
  line-height: var(--leading-panel);
}

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

/* With no result above it the message opens the panel's close, so it takes the result's rule. */
.builder-result[hidden] + .builder-status p {
  margin-top: 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
}

/* Error pages */

.notice {
  max-width: 40rem;
  padding-block: clamp(1rem, 6vw, 5rem);
}

.notice p {
  margin-top: var(--space-5);
  color: var(--ink-2);
  font-size: var(--text-lg);
}

/* Long-form pages: privacy policy, terms, support */

.prose {
  max-width: var(--measure);
  color: var(--ink-2);
  line-height: 1.7;
}

.prose > * + * {
  margin-top: var(--space-4);
}

.prose h1 {
  font-size: var(--text-3xl);
  line-height: 1.08;
}

/* The "Last updated" line under the title. */
.prose h1 + p {
  margin-top: var(--space-4);
  color: var(--ink-3);
  font-size: var(--text-sm);
}

.prose h2 {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
}

.prose h1 + p + h2 {
  margin-top: var(--space-7);
}

.prose h3 {
  margin-top: var(--space-6);
}

.prose h2 + *,
.prose h3 + * {
  margin-top: var(--space-3);
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose li::marker {
  color: var(--ink-3);
}

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

/* Addresses and URLs must never push a phone screen sideways. Cells use break-word, not anywhere,
   so a column is never squeezed narrower than its longest word. */
.prose a {
  overflow-wrap: anywhere;
}

.prose td,
.prose th {
  overflow-wrap: break-word;
}

.prose table {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  line-height: 1.55;
}

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

/* Guides: long-form reference pages like the ones above, with a table of contents that sits
   above the sections on a phone and beside the text on a wide screen. */

.guide {
  display: grid;
  gap: var(--space-7);
}

/* A grid item is as wide as its longest unbreakable line unless told otherwise; a string of
   parameters or a table must wrap inside its column instead of widening it. */
.guide > * {
  min-width: 0;
}

/* The platform the guide is about, above its headline: a label, set like a table's column head. */
.guide-platform,
.guide-toc p {
  color: var(--ink-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-strong);
}

/* The grid's gap already separates the sections from the opening above them. */
.guide-sections > :first-child {
  margin-top: 0;
}

/* The table of contents: the sections' headings under a full rule, set like the footer's links. */
.guide-toc {
  padding-top: var(--space-4);
  border-top: 1px solid var(--ink);
  font-size: var(--text-sm);
}

.guide-toc ol {
  margin-top: var(--space-2);
  padding: 0;
  list-style: none;
}

/* Each link fills its line, so a thumb has the whole row to press. */
.guide-toc a {
  display: block;
  padding-block: var(--space-1);
  color: var(--ink-2);
  text-decoration: none;
}

.guide-toc a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* A value named in a sentence, a list or a table cell, set like the string it is pasted into. A
   value moves to the next line whole and breaks only when it alone is wider than its line. */
.guide :is(p, li, th, td) > code {
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  overflow-wrap: break-word;
}

/* A table's text is already small; its values go one step down so they stay the cell's size. */
.guide :is(th, td) > code {
  font-size: var(--text-xs);
}

/* A row's first cell is its header for a screen reader, not a heading for the eye: it holds the
   value the row is about and is set like the cells beside it, not in the browser's bold. */
.guide tbody th {
  font-weight: inherit;
}

/* The header stays in view from tablet up (above), so a heading the table of contents jumps to
   stops below it. */
@media (width >= 40rem) {
  .guide h2[id] {
    scroll-margin-top: var(--header-height);
  }
}

/* On a phone a table's rows stack: the value to paste on a line of its own, what it means under
   it. Side by side, the longest value would leave the other columns a few characters each.
   display: block takes a table out of Safari's accessibility tree, so every table stacked here
   says what it is in its markup: a role on each element and a row header per row (guide.peb). */
@media (width < 40rem) {
  .guide table,
  .guide tbody,
  .guide tr,
  .guide tbody :is(th, td) {
    display: block;
  }

  /* Stacked cells sit under no column, so the column names leave the screen. They are still read
     out: the row is clipped, not removed. */
  .guide thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .guide tbody tr {
    padding-block: var(--space-3);
    border-bottom: 1px solid var(--line);
  }

  /* The row carries the rule and the room its cells had. */
  .guide tbody :is(th, td) {
    padding: 0;
    border-bottom: 0;
  }

  .guide tbody :is(th, td) + td {
    margin-top: var(--space-1);
  }
}

/* Wide screens: the text keeps the left, at its measure, and the table of contents stays in view
   on the right while the sections scroll past it. */
@media (width >= 60rem) {
  .guide {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--space-6);
  }

  .guide > .prose {
    grid-column: 1 / span 8;
  }

  .guide-toc {
    position: sticky;
    top: calc(var(--header-height) + var(--space-7));
    grid-column: 10 / -1;
    grid-row: 1 / span 2;
    align-self: start;
  }
}

/* Motion off when asked: overrides every transition above, whichever selector set it. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0s !important;
    scroll-behavior: auto !important;
  }
}
