/* GENERATED by packages/tokens — do not edit. Run `pnpm tokens`. */

:root {
  --color-ink: #121212;
  --color-ink-2: #3D3D3D;
  --color-muted: #6B6B6B;
  --color-faint: #8A8A8A;
  --color-ground: #EDEDED;
  --color-surface: #FFFFFF;
  --color-surface-2: #F4F4F4;
  --color-line: #E0E0E0;
  --color-line-strong: #C2C2C2;
  --color-ink-fill: #121212;
  --color-on-ink-fill: #FFFFFF;
  --color-ink-fill-2: #232323;
  --color-ink-fill-line: #2E2E2E;
  --color-ink-fill-dot: #2E3134;
  --color-on-ink-fill-2: #A3A7AD;
  --color-on-ink-fill-dim: #7C8087;
  --color-sidebar: #E8E8E8;
  --color-sidebar-2: #FFFFFF;
  --color-sidebar-border: #D4D4D4;
  --color-sidebar-text: #6B6B6B;
  --color-sidebar-text-strong: #121212;
  --color-sidebar-text-dim: #8A8A8A;
  --color-sidebar-avatar: #D4D4D4;
  --color-sidebar-warn-bg: #FAF3DC;
  --color-sidebar-warn-fg: #7A5B00;
  --color-primary: #C5F24C;
  --color-primary-hover: #B2E033;
  --color-primary-soft: #F0FCD2;
  --color-primary-border: #D6F87A;
  --color-primary-text: #415C08;
  --color-on-primary: #121212;
  --color-on-solid: #FFFFFF;
  --color-success: #157A47;
  --color-success-soft: #E2F0E8;
  --color-warning: #7A5B00;
  --color-warning-soft: #F6E7AE;
  --color-danger: #F4353F;
  --color-danger-soft: #FDE7E8;
  --color-hazard: #E8B004;
  --color-neutral-soft: #E8E8E8;
  --color-sync-bg: #E2F0E8;
  --color-sync-fg: #157A47;
  --color-sync-icon: #2E9E6B;
  --color-status-dot-ok: #2E9E6B;
  --color-offline-bg: #F6E7AE;
  --color-offline-border: #E2CE87;
  --color-offline-btn: #EBD79A;
  --color-attention-bg: #FAF3DC;
  --color-attention-fg: #5E4400;
  --color-attention-fg-dim: #7A5F17;
  --color-chart-track: #D4D4D4;
  --color-media-placeholder: #EFEFEC;
  --color-pattern-dark: #262626;
  --color-pattern-light: #F4F4F4;
  --color-scrim: #12121299;
  --color-panel: #FAFAFA;
  --color-card-lift: #12121214;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-panel: 26px;
  --radius-pill: 999px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --control-sm: 44px;
  --control-md: 44px;
  --control-lg: 52px;
  --control-xl: 64px;
  --tracking-caps: 0.06em;
  --tracking-caps-wide: 0.08em;
  --tracking-normal: 0em;
  --tracking-tight: -0.01em;
  --tracking-tighter: -0.02em;
  --tracking-display: -0.035em;
}

/* Dark follows the OS, unless the operator has explicitly chosen light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-ink: #F2F2F0;
    --color-ink-2: #C2C2C2;
    --color-muted: #8F8F8F;
    --color-faint: #6B6B6B;
    --color-ground: #0A0A0A;
    --color-surface: #141414;
    --color-surface-2: #1C1C1C;
    --color-line: #2A2A2A;
    --color-line-strong: #3D3D3D;
    --color-ink-fill: #1C1C1C;
    --color-on-ink-fill: #F2F2F0;
    --color-ink-fill-2: #232323;
    --color-ink-fill-line: #2E2E2E;
    --color-ink-fill-dot: #2E3134;
    --color-on-ink-fill-2: #A3A7AD;
    --color-on-ink-fill-dim: #7C8087;
    --color-sidebar: #242424;
    --color-sidebar-2: #2E2E2E;
    --color-sidebar-border: #383838;
    --color-sidebar-text: #A3A7AD;
    --color-sidebar-text-strong: #EDEDEA;
    --color-sidebar-text-dim: #7C8087;
    --color-sidebar-avatar: #3A3D40;
    --color-sidebar-warn-bg: #3A3000;
    --color-sidebar-warn-fg: #E8B004;
    --color-primary: #C5F24C;
    --color-primary-hover: #B2E033;
    --color-primary-soft: #1F2A0A;
    --color-primary-border: #D6F87A;
    --color-primary-text: #D6F87A;
    --color-on-primary: #121212;
    --color-on-solid: #121212;
    --color-success: #45B37A;
    --color-success-soft: #12241B;
    --color-warning: #E8B004;
    --color-warning-soft: #2B2209;
    --color-danger: #FF5A63;
    --color-danger-soft: #2A1416;
    --color-hazard: #E8B004;
    --color-neutral-soft: #242424;
    --color-sync-bg: #16241C;
    --color-sync-fg: #86CFA6;
    --color-sync-icon: #45B37A;
    --color-status-dot-ok: #2E9E6B;
    --color-offline-bg: #F6E7AE;
    --color-offline-border: #E2CE87;
    --color-offline-btn: #EBD79A;
    --color-attention-bg: #241E0A;
    --color-attention-fg: #EBD79A;
    --color-attention-fg-dim: #B9A97A;
    --color-chart-track: #D4D4D4;
    --color-media-placeholder: #EFEFEC;
    --color-pattern-dark: #232323;
    --color-pattern-light: #1F1F1F;
    --color-scrim: #12121299;
    --color-panel: #0F0F0F;
    --color-card-lift: #FFFFFF0F;
  }
}

/* An explicit choice wins over the OS, in both directions. */
[data-theme="dark"] {
  --color-ink: #F2F2F0;
  --color-ink-2: #C2C2C2;
  --color-muted: #8F8F8F;
  --color-faint: #6B6B6B;
  --color-ground: #0A0A0A;
  --color-surface: #141414;
  --color-surface-2: #1C1C1C;
  --color-line: #2A2A2A;
  --color-line-strong: #3D3D3D;
  --color-ink-fill: #1C1C1C;
  --color-on-ink-fill: #F2F2F0;
  --color-ink-fill-2: #232323;
  --color-ink-fill-line: #2E2E2E;
  --color-ink-fill-dot: #2E3134;
  --color-on-ink-fill-2: #A3A7AD;
  --color-on-ink-fill-dim: #7C8087;
  --color-sidebar: #242424;
  --color-sidebar-2: #2E2E2E;
  --color-sidebar-border: #383838;
  --color-sidebar-text: #A3A7AD;
  --color-sidebar-text-strong: #EDEDEA;
  --color-sidebar-text-dim: #7C8087;
  --color-sidebar-avatar: #3A3D40;
  --color-sidebar-warn-bg: #3A3000;
  --color-sidebar-warn-fg: #E8B004;
  --color-primary: #C5F24C;
  --color-primary-hover: #B2E033;
  --color-primary-soft: #1F2A0A;
  --color-primary-border: #D6F87A;
  --color-primary-text: #D6F87A;
  --color-on-primary: #121212;
  --color-on-solid: #121212;
  --color-success: #45B37A;
  --color-success-soft: #12241B;
  --color-warning: #E8B004;
  --color-warning-soft: #2B2209;
  --color-danger: #FF5A63;
  --color-danger-soft: #2A1416;
  --color-hazard: #E8B004;
  --color-neutral-soft: #242424;
  --color-sync-bg: #16241C;
  --color-sync-fg: #86CFA6;
  --color-sync-icon: #45B37A;
  --color-status-dot-ok: #2E9E6B;
  --color-offline-bg: #F6E7AE;
  --color-offline-border: #E2CE87;
  --color-offline-btn: #EBD79A;
  --color-attention-bg: #241E0A;
  --color-attention-fg: #EBD79A;
  --color-attention-fg-dim: #B9A97A;
  --color-chart-track: #D4D4D4;
  --color-media-placeholder: #EFEFEC;
  --color-pattern-dark: #232323;
  --color-pattern-light: #1F1F1F;
  --color-scrim: #12121299;
  --color-panel: #0F0F0F;
  --color-card-lift: #FFFFFF0F;
}

/* store.mozzo.shop — the whole stylesheet.
   Paper `G01` / `MG01` (desktop 1440, phone 390) are one page at two widths,
   the same rule the app follows: layout branches on WIDTH, never on device.

   Colours, radii, spacing and tracking come from tokens.generated.css, which
   is written from `@mozzo/tokens`. There is no hex below this comment.

   Type SIZES are this surface's own, and deliberately not in the token package:
   the app scales per form factor, the back office is one width, and a marketing
   page needs bigger type than either. A third shared scale would be a scale
   nobody draws. Whole pixels, line-heights on the 4px grid, exactly as the back
   office does it — and named after Paper's own tokens so a value read out of the
   design tool pastes in unchanged. */

:root {
  --font-sans: Geist, ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;

  /* Phone first — these are the values at 390. The desktop block overrides the
     four that change. */
  --text-micro: 11px;
  --leading-micro: 16px;
  --text-label: 13px;
  --leading-label: 20px;
  --text-body: 15px;
  --leading-body: 24px;
  --text-lede: 17px;
  --leading-lede: 26px;
  --text-title: 20px;
  --leading-title: 28px;
  --text-kpi: 24px;
  --leading-kpi: 30px;
  --text-headline: 30px;
  --leading-headline: 34px;
  --text-display: 40px;
  --leading-display: 44px;

  /* The design's own content width, and the gutter that holds it off the edge. */
  --content: 1344px;
  --gutter: 20px;
  --section-gap: 56px;

  /* ── The only two values that flip with the theme and are not in the token
     package ────────────────────────────────────────────────────────────────
     A dark FILL on a dark page needs an edge; on a light page the same edge is a
     light ring drawn around a near-black object. So this is a hairline in dark
     and nothing in light. It is here rather than in `@mozzo/tokens` because it
     is a fact about a page whose surface and whose panels are both dark — the
     app never stacks `inkFill` on `surface` this way.

     Everything else about dark mode comes free: `inkFill` lifts a step off the
     ground while `ink` flips to near-white, the `*Soft` tints darken, both
     pattern strokes follow the surface down, and lime stays lime with near-black
     on top. That is ADR-0013's parallel layer doing what it was built for.

     Not even in a comment: a hex written here is a value that can go stale
     against the token package without anything failing, and `grep '#[0-9A-Fa-f]'
     src/site.css` returning nothing is a check worth being able to trust. */
  --edge-ink: transparent;
  --shot-frame: var(--color-line);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --edge-ink: var(--color-line);
    --shot-frame: var(--color-line-strong);
  }
}

[data-theme="dark"] {
  --edge-ink: var(--color-line);
  --shot-frame: var(--color-line-strong);
}

@media (min-width: 900px) {
  :root {
    --text-body: 16px;
    --leading-body: 26px;
    --text-lede: 20px;
    --leading-lede: 32px;
    --text-title: 24px;
    --leading-title: 32px;
    --text-kpi: 32px;
    --leading-kpi: 38px;
    --text-headline: 44px;
    --leading-headline: 48px;
    --text-display: 76px;
    --leading-display: 76px;
    --gutter: 48px;
    --section-gap: 112px;
  }
}

/* ── Fonts ─────────────────────────────────────────────────────────────────
   Self-hosted, not Google's CDN. A third-party connection before first paint
   costs more than the 52KB these two files weigh, and a shop on a slow
   Ghanaian connection pays that cost twice — DNS, then TLS, then the font.

   Both faces are variable, so one file per family covers every weight the page
   uses. `latin-ext` is declared and almost never fetched: unicode-range means
   the browser downloads it only if the page actually contains one of its
   characters. */

@font-face {
  font-family: Geist;
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/geist-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: Geist;
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/geist-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("fonts/geist-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("fonts/geist-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Reset ─────────────────────────────────────────────────────────────── */

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

body,
h1,
h2,
h3,
p,
ul,
li,
figure {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Both, so the browser's own chrome — scrollbars, form controls, the
     scrollbar gutter — matches whichever palette resolved. */
  color-scheme: light dark;
}

/* The sticky nav is 72px tall, so an anchor jump without this lands the heading
   underneath it. */
:target,
[id] {
  scroll-margin-top: 96px;
}

body {
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-weight: 400;
  /* Not decoration: the whole point of the sans/mono split is that money reads
     as a column even when it is inline in a sentence (design.md §Type). */
  font-variant-numeric: tabular-nums;
}

a {
  color: inherit;
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--color-primary-text);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Skipped by mouse users, essential to everyone else — the page is long. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 12px 16px;
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: var(--text-label);
  font-weight: 500;
  z-index: 20;
}
.skip:focus {
  left: 12px;
  top: 12px;
}

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

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-muted);
}

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

.headline {
  font-size: var(--text-headline);
  line-height: var(--leading-headline);
  font-weight: 500;
  letter-spacing: var(--tracking-tighter);
}

.kpi {
  font-size: var(--text-kpi);
  line-height: var(--leading-kpi);
  font-weight: 500;
  letter-spacing: var(--tracking-tighter);
}

.title {
  font-size: var(--text-title);
  line-height: var(--leading-title);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
}

.lede {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  color: var(--color-ink-2);
}

.note {
  font-size: var(--text-label);
  line-height: var(--leading-label);
  color: var(--color-muted);
}

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

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

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

/* Half above and half below, so two adjacent sections add up to exactly one
   `--section-gap` and the token means what its name says. Applying the whole
   value on both edges is what left a band of empty white between the hero and
   the first section tall enough to read as the end of the page. */
section {
  padding: calc(var(--section-gap) / 2) 0;
}

.section-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 760px;
  margin-bottom: 40px;
}

.section-head .lede {
  max-width: 660px;
}

/* ── The background pattern ────────────────────────────────────────────────
   Accra's perforated screen blocks (design.md §Background pattern). Two rules
   it is easy to break: it marks CHROME, never data, and the DENSITY is what
   holds across widths, not the radius — r193 on a 273px grid at 1440, r65 on 92
   at 390. Running the desktop numbers down a phone column shows one giant arc.

   An SVG `<pattern>` tile rather than the generated one-path-many-subpaths the
   design files use: a tile repeats to any size, which is what a page that does
   not know its own height needs. Same geometry — circles on the lattice points,
   drawn at all four corners of the tile so the arcs that cross the seam are
   whole. Stroke is `currentColor`, so the colour is still a token. */

/* The definitions carry no size and must not take part in layout. */
.pattern-defs {
  position: absolute;
  width: 0;
  height: 0;
}

.pattern {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.pattern--lg {
  display: none;
}

@media (min-width: 900px) {
  .pattern--sm {
    display: none;
  }
  .pattern--lg {
    display: block;
  }
}

/* Everything inside a patterned band has to sit above it. */
.banded {
  position: relative;
  overflow: hidden;
}

.banded > *:not(.pattern) {
  position: relative;
  z-index: 1;
}

/* ── Buttons and badges ───────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--control-lg);
  padding: 0 24px;
  border-radius: var(--radius-pill);
  font-size: var(--text-body);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 200ms ease, border-color 200ms ease, transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 200ms ease;
}

/* Lifts on hover and takes the press. Two pixels and 60ms is the difference
   between a button and a coloured rectangle. */
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px var(--color-card-lift);
}

.btn:active {
  transform: translateY(0);
  box-shadow: none;
  transition-duration: 60ms;
}

/* One lime moment per screen, and text on lime is never white (design.md §2).
   The hero's call to action is that moment above the fold; the download band is
   a separate screen by the time anyone reaches it. */
.btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn--primary:hover {
  background: var(--color-primary-hover);
}

.btn--ghost {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-line-strong);
}
.btn--ghost:hover {
  border-color: var(--color-ink);
}

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

/* The store badges. Apple and Google both require their own artwork and
   wording, so this is the shape of the real thing and the marks are their own
   — the two `fill` values inside those SVGs are the only colours on the page
   that are not ours, and they are trademarks, not decoration. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 48px;
  padding: 0 18px;
  border-radius: var(--radius-md);
  background: var(--color-ink-fill);
  color: var(--color-on-ink-fill);
  border: 1px solid var(--edge-ink);
  flex: 1 1 auto;
  min-width: 150px;
}

.badge {
  transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 200ms ease;
}

.badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px var(--color-card-lift);
}

.badge__lines {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.badge__pre {
  font-size: 9px;
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  opacity: 0.75;
}

.badge__name {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
}

@media (min-width: 900px) {
  .badge {
    flex: 0 0 auto;
  }
}

/* ── The nav ──────────────────────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-line);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 72px;
}

.nav__links {
  display: none;
  align-items: center;
  gap: 28px;
  margin-left: auto;
  font-size: var(--text-body);
  color: var(--color-ink-2);
}

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

.nav__links a[aria-current="page"] {
  color: var(--color-ink);
  font-weight: 500;
}

/* The store links live in the header because that is where a shop owner who has
   already decided goes looking. At 390 there is no room for the two-line
   lockup, so they become the marks alone — same links, same place. */
.nav__stores {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.nav__store {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 36px;
  width: 36px;
  border-radius: var(--radius-pill);
  background: var(--color-ink-fill);
  color: var(--color-on-ink-fill);
  border: 1px solid var(--edge-ink);
  flex-shrink: 0;
}

.nav__store span {
  display: none;
}

.nav__menu {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  cursor: pointer;
  flex-shrink: 0;
}

/* This block comes after every rule it overrides. Two selectors of equal
   specificity are decided by source order, and a `display: none` written above
   the `display: inline-flex` it means to beat loses silently — which is exactly
   how the hamburger ended up sitting next to the full nav at 1440. */
@media (min-width: 900px) {
  .nav__links {
    display: flex;
  }
  .nav__stores {
    margin-left: 0;
  }
  .nav__store {
    width: auto;
    padding: 0 14px;
    border-radius: var(--radius-md);
    font-size: var(--text-label);
    font-weight: 500;
  }
  .nav__store span {
    display: block;
  }
  .nav__menu {
    display: none;
  }
}

/* The phone menu is a disclosure, not an overlay: it pushes the page down and
   nothing is trapped behind it. */
.nav__drawer {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 8px 0 20px;
  border-top: 1px solid var(--color-line);
}

.nav__drawer[data-open] {
  display: flex;
}

.nav__drawer a {
  padding: 12px 0;
  font-size: var(--text-lede);
  border-bottom: 1px solid var(--color-line);
}

@media (min-width: 900px) {
  .nav__drawer,
  .nav__drawer[data-open] {
    display: none;
  }
}

/* ── The lockup ────────────────────────────────────────────────────────────
   Fixed geometry (ADR-0031). The tile is exactly twice the x-height of the
   logotype and the gap is 30/108 of the tile — that ratio is what makes the
   lockup lock, so both SVGs are sized from one number and never nudged. */

.lockup {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.lockup__mark {
  height: 28px;
  width: 28px;
  flex-shrink: 0;
}

/* No width: the viewBox holds the ratio, so one number sizes the logotype and
   it can never be stretched. */
.lockup__type {
  height: 15px;
  width: auto;
  flex-shrink: 0;
}

@media (min-width: 900px) {
  .lockup {
    gap: 9px;
  }
  .lockup__mark {
    height: 32px;
    width: 32px;
  }
  .lockup__type {
    height: 17px;
  }
}

/* On the dark band the logotype has to invert; the tile never does. */
.band .lockup__type path,
.band .lockup__type circle {
  stroke: var(--color-on-ink-fill);
}

/* ── Hero ─────────────────────────────────────────────────────────────── */

/* No bottom padding of its own: the next section already brings a full section
   gap, and two of them stacked leaves a band of empty white tall enough to read
   as the end of the page. */
.hero {
  padding-top: 40px;
  padding-bottom: 0;
}

.hero__grid {
  display: flex;
  flex-direction: column;
  gap: 40px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 660px;
}

.hero__lede {
  max-width: 560px;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
}

.hero__cta .btn {
  flex: 1 1 auto;
}

/* The screenshot is 1366 wide at its own size, so left to itself it takes the
   whole row and squeezes the headline into a column six lines deep. Both
   children are given an explicit share, and the shot gets `min-width: 0` — a
   flex item holding an image will not shrink below its content without it, which
   is what pushed the panel past the right edge of the page. */
@media (min-width: 900px) {
  .hero {
    padding-top: 72px;
  }
  .hero__grid {
    flex-direction: row;
    align-items: center;
    gap: 64px;
  }
  .hero__copy {
    flex: 0 1 620px;
  }
  .hero__shot {
    flex: 1 1 0;
    min-width: 0;
  }
  .hero__cta .btn {
    flex: 0 0 auto;
  }
}

.hero__shot {
  border-radius: var(--radius-panel);
  border: 1px solid var(--shot-frame);
  overflow: hidden;
  background: var(--color-surface-2);
}

.hero__shot img {
  width: 100%;
  height: auto;
}

.hero__caption {
  padding: 12px 16px;
  border-top: 1px solid var(--color-line);
  background: var(--color-surface);
}

/* ── The rotator ───────────────────────────────────────────────────────────
   Two modes, and the plain one is the default.

   OFF (no script yet, script blocked, or reduced motion): the phrases are static
   flow content, one shown, the rest `display: none`. The FIRST is marked active
   in the markup, so the headline is a finished sentence before anything runs —
   the page reads "One system to count your stock." with no JavaScript at all.

   ON (the script measured the phrases and is cycling): the list becomes a
   clipping window with the phrases stacked absolutely inside it. The outgoing
   line rises out of the top while the incoming line rises in from the bottom, and
   the window's own width animates between the two — which is what carries the
   lime cursor along with the text instead of letting it jump. The widths are
   measured in JS because only the browser knows how wide "keep your books" is in
   Geist at 76px; nothing else about the effect needs a script. */

.rotator {
  display: inline-flex;
  align-items: baseline;
}

.rotator__list {
  display: inline;
}

.rotator__item {
  display: none;
  color: var(--color-ink);
}

.rotator__item[data-active] {
  display: inline;
}

.rotator__cursor {
  display: inline-block;
  width: 4px;
  height: calc(var(--text-display) * 0.62);
  margin-left: 6px;
  background: var(--color-primary);
  border-radius: 2px;
  vertical-align: baseline;
}

[data-rotator="on"] .rotator__list {
  display: inline-block;
  position: relative;
  height: var(--leading-display);
  /* Set by the script to the active phrase's own width. The easing is the same
     one every transition on this page uses — slow out of the gate, decisive at
     the end. */
  transition: width 460ms cubic-bezier(0.22, 1, 0.36, 1);
  vertical-align: bottom;
  overflow: hidden;
}

[data-rotator="on"] .rotator__item {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  white-space: nowrap;
  /* Off screen and unreadable by default — only the two taking part in a
     handover are given an animation. */
  opacity: 0;
  transform: translateY(100%);
}

[data-rotator="on"] .rotator__item[data-active] {
  animation: phrase-in 520ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

[data-rotator="on"] .rotator__item[data-leaving] {
  animation: phrase-out 380ms cubic-bezier(0.55, 0, 0.55, 1) both;
}

[data-rotator="on"] .rotator__cursor {
  animation: blink 1.1s steps(1) infinite;
}

@keyframes phrase-in {
  from {
    opacity: 0;
    transform: translateY(90%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes phrase-out {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-90%);
  }
}

@keyframes blink {
  50% {
    opacity: 0.15;
  }
}

/* A separate list of the same four phrases, as pills, so the promise is legible
   at a glance rather than only to whoever waits four seconds. */
.cycle {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cycle li {
  position: relative;
  overflow: hidden;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line);
  font-size: var(--text-label);
  color: var(--color-muted);
  transition: color 240ms ease, border-color 240ms ease, background-color 240ms ease;
}

.cycle li[data-active] {
  background: var(--color-primary-soft);
  border-color: var(--color-primary-border);
  color: var(--color-primary-text);
}

/* A lime line sweeping the active pill over exactly the dwell time, so the
   headline's next move is visible a beat before it happens instead of arriving
   unannounced. The animation restarts by itself: the attribute is removed and
   re-added on every hand-over, which is a fresh element state as far as the
   animation is concerned. */
.cycle li[data-active]::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--color-primary);
  transform-origin: left;
  animation: sweep var(--dwell, 2600ms) linear both;
}

@keyframes sweep {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* ── Panels and the bento ─────────────────────────────────────────────────
   The app leans on soft curves, so the grid is panels of different sizes on one
   lane rather than a repeating tile. The panel EDGE is the lane: it is what
   makes two blocks of different content line up, which a bare column gap does
   not. */

.panel {
  border-radius: var(--radius-panel);
  border: 1px solid var(--color-line);
  background: var(--color-surface);
  padding: 28px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
  position: relative;
}

.panel--soft {
  background: var(--color-surface-2);
  border-color: transparent;
}

.panel--ink {
  background: var(--color-ink-fill);
  color: var(--color-on-ink-fill);
  border-color: var(--edge-ink);
}

.panel--lime {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: transparent;
}

.panel--ink .note,
.panel--ink .lede,
.panel--ink .eyebrow {
  color: inherit;
  opacity: 0.72;
}

.panel--lime .lede,
.panel--lime .eyebrow {
  color: inherit;
  opacity: 0.78;
}

@media (min-width: 900px) {
  .panel {
    padding: 40px;
    gap: 20px;
  }
}

.bento {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .bento {
    gap: 24px;
  }
  /* Two of the rows are deliberately uneven — a shop's own page is the bigger
     promise than the marketplace, and the grid says so. */
  .bento--wide-narrow {
    grid-template-columns: 2fr 1fr;
  }
  .bento--narrow-wide {
    grid-template-columns: 1fr 1fr;
  }
}

.stack {
  display: grid;
  gap: 20px;
}

@media (min-width: 900px) {
  .stack {
    gap: 24px;
  }
}

/* Copy stops at a line length somebody can read without losing the line
   (design.md §Type — the split between the two faces is about measure, not
   importance). */
.measure {
  max-width: 720px;
}

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

.ticks li {
  padding-left: 22px;
  position: relative;
  font-weight: 500;
}

/* The arch again, at the smallest size it survives: a check drawn as two
   strokes rather than a bullet, because a bullet says "list" and this is three
   claims. */
.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 11px;
  height: 6px;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-50%) rotate(-45deg);
  transform-origin: center;
}

/* ── The three problems ───────────────────────────────────────────────── */

.problem {
  gap: 0;
}

.problem__head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 16px;
}

.problem__no {
  font-family: var(--font-mono);
  font-size: var(--text-title);
  font-weight: 500;
  color: var(--color-primary-text);
  flex-shrink: 0;
}

.problem__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 560px;
}

/* A light screenshot on a dark page needs a firmer frame, or it reads as a hole
   cut in the panel. */
.problem__shot {
  margin: 24px 0;
  border-radius: var(--radius-lg);
  border: 1px solid var(--shot-frame);
  overflow: hidden;
  background: var(--color-surface-2);
}

.problem__shot img {
  width: 100%;
  height: auto;
}

/* Pinned to the bottom so the answer starts at the same height in both panels
   of a two-up row, whatever the copy above does. */
.answer {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--color-primary-soft);
  border: 1px solid var(--color-primary-border);
}

.answer .eyebrow {
  color: var(--color-primary-text);
}

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

@media (min-width: 900px) {
  .problem--wide {
    display: grid;
    grid-template-columns: 448px 1fr;
    gap: 48px;
    align-items: center;
  }
  .problem--wide .problem__shot {
    margin: 0;
  }
  .problem--wide .problem__col {
    display: flex;
    flex-direction: column;
    gap: 20px;
  }
}

/* ── Add-ons ──────────────────────────────────────────────────────────── */

.tag {
  align-self: flex-start;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-neutral-soft);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-muted);
  flex-shrink: 0;
}

/* State is colour PLUS a word (design.md §5). Nothing on this page is a live
   status, but "coming" is a claim about what a shop can do today, and it has to
   survive being read in one glance by someone deciding whether to trust us. */
.tag--soon {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

/* The tag holds its line and the title wraps instead. Wrapping the row put
   `Coming` on a line of its own below a title that had plenty of room. */
.panel__titlerow {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.panel__titlerow .tag {
  flex-shrink: 0;
}

.addr {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 20px;
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  align-self: flex-start;
}

.addr__url {
  font-family: var(--font-mono);
  font-size: var(--text-body);
  font-weight: 500;
}

/* The illustrations. Hand-authored, from the brand's own arch (ADR-0042) —
   never an icon scaled up, never a stock drawing. One per panel, and each one
   carries the idea the panel is making. */
.illo {
  align-self: flex-start;
  margin-top: auto;
  flex-shrink: 0;
}

.illo--corner {
  align-self: flex-end;
}

.fee {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: auto;
  padding-top: 20px;
  border-top: 1px solid var(--color-line);
}

/* The day card — three sales, three channels, one total. The argument of the
   whole page in one object, which is why it is the only place a figure appears
   at size. */
.day {
  gap: 0;
}

.day__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-sidebar-border);
}

/* Three columns at 1440, and at 390 the channel moves onto its own line above
   the sale. Holding a 96px label column at that width left the product name
   about eleven characters wide, so "Nasco standing fan" broke over two lines
   next to an amount that could not. */
.day__row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 14px;
  row-gap: 4px;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-sidebar-border);
}

.day__channel {
  grid-column: 1 / -1;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  opacity: 0.6;
}

.day__what {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.day__what strong {
  font-weight: 500;
}

.day__amount {
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}

/* The total sits on the floor of the card, so it lines up with the bottom of the
   lime panel beside it rather than floating halfway up a tall box. */
.day__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-top: 18px;
  margin-top: auto;
}

.day__total strong {
  font-size: var(--text-kpi);
  line-height: var(--leading-kpi);
  font-weight: 500;
  letter-spacing: var(--tracking-tighter);
  white-space: nowrap;
}

@media (min-width: 900px) {
  .day__row {
    grid-template-columns: 120px 1fr auto;
  }
  .day__channel {
    grid-column: auto;
  }
}

/* ── Delivery ─────────────────────────────────────────────────────────── */

.steps {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}

.step {
  display: flex;
  gap: 14px;
}

.step__no {
  width: 26px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-caps);
  color: var(--color-primary);
  padding-top: 3px;
}

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

.step__body strong {
  font-weight: 500;
  font-size: var(--text-lede);
  letter-spacing: var(--tracking-tight);
}

@media (min-width: 900px) {
  .steps {
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
  }
  .step {
    flex-direction: column;
    gap: 12px;
  }
}

/* ── Everyday things ──────────────────────────────────────────────────── */

.hairlines {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border-top: 1px solid var(--color-line);
}

.hairline {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 24px 0;
  border-bottom: 1px solid var(--color-line);
}

.hairline__no {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-caps);
  color: var(--color-faint);
}

.hairline strong {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
}

@media (min-width: 900px) {
  .hairlines {
    grid-template-columns: repeat(3, 1fr);
    column-gap: 48px;
  }
  .hairline {
    padding: 28px 0;
  }
}

/* ── Download band ────────────────────────────────────────────────────── */

/* A band with its own colour needs the full gap INSIDE it — half a gap of dark
   above a headline reads as a crop, not as breathing room. */
.band {
  background: var(--color-ink-fill);
  color: var(--color-on-ink-fill);
  border-top: 1px solid var(--edge-ink);
  border-bottom: 1px solid var(--edge-ink);
  padding: var(--section-gap) 0;
}

.band__inner {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 720px;
}

.band .lede,
.band .eyebrow {
  color: inherit;
  opacity: 0.72;
}

/* ── Footer ───────────────────────────────────────────────────────────── */

.footer {
  background: var(--color-surface);
  border-top: 1px solid var(--color-line);
  padding: 56px 0 32px;
}

.footer__top {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.footer__tagline {
  max-width: 420px;
  margin-top: 16px;
}

.footer__cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 32px;
}

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

.footer__col a,
.footer__col span {
  font-size: var(--text-label);
  color: var(--color-muted);
}

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

.footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--color-line);
}

/* The theme toggle. It sits in the footer rather than the nav because it is not
   a thing anybody came here to do — and because the nav at 390 is already the
   lockup, two store links and a menu. */
.theme {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-line);
  background: transparent;
  color: var(--color-muted);
  font-family: inherit;
  font-size: var(--text-label);
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease;
}

.theme:hover {
  color: var(--color-ink);
  border-color: var(--color-line-strong);
}

/* The glyph turns as the theme does — a small confirmation that the button did
   something, in a place where the change itself is the whole page and easy to
   read as a mis-tap. */
.theme svg {
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

.theme[aria-pressed="true"] svg {
  transform: rotate(150deg);
}

@media (min-width: 900px) {
  .footer {
    padding: 72px 0 40px;
  }
  .footer__top {
    flex-direction: row;
    justify-content: space-between;
    gap: 64px;
  }
  .footer__cols {
    grid-template-columns: repeat(4, minmax(0, 160px));
    gap: 48px;
  }
}

/* ── Legal and contact pages ──────────────────────────────────────────────
   design.md's banned-words table does not reach these two. A privacy policy is
   read by an app store reviewer and, one day, by a lawyer — "we retain your
   data" is the plain word there, and softening it into merchant voice would
   make the document worse at its job. Everything else on the surface still
   speaks the shop's language. */

.prose {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  padding-bottom: var(--section-gap);
}

.prose--after {
  margin-top: 56px;
}

.prose h2 {
  font-size: var(--text-title);
  line-height: var(--leading-title);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  margin-top: 20px;
}

.prose h3 {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  font-weight: 500;
}

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

.prose ul {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-left: 20px;
  list-style: disc;
}

.prose section {
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.prose a {
  text-decoration: underline;
  text-decoration-color: var(--color-primary-border);
  text-underline-offset: 3px;
}

/* A draft is marked as a draft, in the document, where it cannot be missed.
   Publishing an unreviewed policy as if it were reviewed is the one mistake on
   these pages that costs real money. */
.draft {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--color-warning-soft);
  border: 1px solid var(--color-offline-border);
}

.draft strong {
  font-weight: 500;
  color: var(--color-warning);
}

.page-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 40px;
  margin-bottom: 40px;
}

.contact__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-top: 8px;
}

@media (min-width: 900px) {
  .contact__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
  }
}

.contact__card strong {
  font-weight: 500;
}

.contact__value {
  font-family: var(--font-mono);
  font-size: var(--text-body);
}

/* ── Panels answer the pointer ─────────────────────────────────────────── */

.panel {
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 260ms ease,
    border-color 260ms ease;
}

.panel:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px var(--color-card-lift);
}

/* The two coloured panels have no border to firm up, and a shadow under lime
   turns the edge muddy. They lift and that is all. */
.panel--lime:hover,
.panel--ink:hover {
  box-shadow: none;
}

.panel:not(.panel--lime):not(.panel--ink):not(.panel--soft):hover {
  border-color: var(--color-line-strong);
}

.hairline {
  transition: border-color 200ms ease;
}

.hairline:hover {
  border-color: var(--color-line-strong);
}

/* A lime rule grows under a nav link rather than an underline appearing. */
.nav__links a {
  position: relative;
  padding-bottom: 2px;
  transition: color 200ms ease;
}

.nav__links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

.nav__links a:hover::after,
.nav__links a[aria-current="page"]::after {
  transform: scaleX(1);
}

/* ── Sections arrive ──────────────────────────────────────────────────────
   Scroll-driven, so there is no observer, no scroll listener and no script — the
   browser owns the timeline and it costs nothing on the main thread. Behind
   `@supports`, so a browser without it simply shows the page, which is the
   correct outcome rather than a fallback: everything is already visible and the
   animation only takes it away and gives it back.

   `animation-range` ends at `cover 34%`, i.e. finished a third of the way into
   the viewport — a reveal that completes at the centre of the screen reads as
   sluggish on a long page like this one. */

@supports (animation-timeline: view()) {
  .section-head,
  .panel,
  .hairline,
  .band__inner,
  .hero__shot {
    animation: arrive 1ms linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 34%;
  }

  /* The hero is above the fold on every width. Animating it means the first
     thing a visitor sees is the page assembling itself, which is the one place
     motion is a cost rather than a courtesy. */
  .hero .hero__shot {
    animation: none;
  }
}

@keyframes arrive {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── Motion, when it is not wanted ───────────────────────────────────────
   Two kinds of motion here, and both have to stop. The rotator moves without
   being scrolled to, indefinitely; the reveals move a whole page of content. The
   blanket rule below collapses every duration, and the reveals are switched off
   by name as well — a scroll-driven animation ignores `animation-duration`, so
   the blanket rule alone would leave them running. */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  @supports (animation-timeline: view()) {
    .section-head,
    .panel,
    .hairline,
    .band__inner,
    .hero__shot {
      animation: none;
      opacity: 1;
      transform: none;
    }
  }
}
