/* Values come from curious-site.pen. Change the token, not the call site. */

/* ---------------------------------------------------------------- tokens -- */

:root {
  /* Motion. The design file covers colour, size, spacing and weight; these
     were chosen here — see motion-audits/ for the reasoning. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Lets the FAQ disclosure transition to its auto height. */
  interpolate-size: allow-keywords;

  /* Dark surfaces */
  --ink: #0b0b0b;
  --ink-raised: #151515;
  --ink-button: #161616;
  --border-dark: #262626;
  --border-dark-strong: #3a3a3a;
  --rule-dark: #3b3b3b;

  /* Light surfaces */
  --paper: #ffffff;
  --paper-alt: #f6f7f6;
  --paper-head: #fafafa;
  --paper-chip: #f7f7f7;
  --paper-chip-flat: #f2f2f2;
  --paper-sunken: #f5f5f5;
  --border: #e5e5e5;
  /* Form controls need a 3:1 boundary. This is the lightest value that clears
     it against both adjacent fills: 3.23:1 on white, 3.01:1 on --paper-alt. */
  --field-border: #8f8f8f;
  --track: #e9e9e9;

  /* Text */
  --text-inverse: #fafafa;
  --text-inverse-muted: #a3a3a3;
  --text: #0b0b0b;
  --text-muted: #5f5f5f;
  --text-muted-2: #6e6e6e;

  /* Accent + state */
  --accent: #3cb371;
  --accent-on-dark: #67d28e;
  --positive: #17613c;
  --positive-soft: #eaf6ee;
  --positive-tint: #eef8f1;
  --positive-line: #cce8d5;
  --connector: #b9dfc5;
  --bar-soft: #d9ebdd;
  --warn: #8a6512;
  --warn-soft: #fff4d8;
  --warn-pill: #fff0c7;
  --warn-tint: #fff7e6;
  --warn-row: #fff9ea;

  /* Logo band */
  --band: #f3f3f0;
  --band-line: #d8d8d4;

  /* Type */
  --sans: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Fluid ramps: designed at 390px and 1440px, linear between, clamped outside. */
  --fs-display: clamp(44px, 35.09px + 2.286vw, 68px); /* 44 -> 68 */
  --fs-h2: clamp(34px, 29.54px + 1.143vw, 46px); /* 34 -> 46 */
  --fs-lead: clamp(16px, 15.26px + 0.19vw, 18px); /* 16 -> 18 */
  --fs-body: clamp(16px, 15.63px + 0.095vw, 17px); /* 16 -> 17 */

  /* Rhythm. Sections carry different vertical padding in the design. */
  /* Gutter tracks the design's 24 / 40 / 96 at 390 / 834 / 1440. */
  --gutter: clamp(24px, 9.24vw - 37px, 96px);
  /* Each ramp hits its design value exactly at 390 and at 1440. */
  --section-y: clamp(56px, 44.11px + 3.048vw, 88px);
  --y-56: clamp(40px, 34.06px + 1.524vw, 56px);
  --y-64: clamp(44px, 36.57px + 1.905vw, 64px);
  --y-72: clamp(48px, 39.09px + 2.286vw, 72px);
  --y-80: clamp(52px, 41.6px + 2.667vw, 80px);
  --y-96: clamp(64px, 52.11px + 3.048vw, 96px);
  --col-gap: clamp(32px, 17.14px + 3.81vw, 72px);
  --nav-h: 78px;
  --shell: 1440px;
}

/* ------------------------------------------------------------------ base -- */

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

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

/* Clear the sticky header so an anchored heading lands below it. */
[id] {
  scroll-margin-top: calc(var(--nav-h) + 14px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  /* The design leaves single-line text at its natural leading. 1.2 matches the
     metrics the .pen renders with; Chrome's own 'normal' for Inter is 1.211. */
  line-height: 1.2;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

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

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

h1,
h2,
h3,
p,
figure,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

/* --accent is only 2.7:1 on white, below the 3:1 non-text minimum. */
:focus {
  outline: 2px solid var(--positive);
  outline-offset: 3px;
}

:focus:not(:focus-visible) {
  outline: none;
}

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

.nav :focus-visible,
.hero :focus-visible,
.page-hero :focus-visible,
.final :focus-visible,
.footer :focus-visible,
.midcta :focus-visible,
.section--dark :focus-visible {
  outline-color: var(--accent);
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 8px;
  z-index: 100;
  translate: -50% -200%;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
}

.skip-link:focus-visible {
  translate: -50% 0;
}

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

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-y);
  border-bottom: 1px solid var(--border);
}

.section--dark {
  background: var(--ink);
  border-bottom-color: var(--border-dark);
}

.section--alt {
  background: var(--paper-alt);
}

.section--y56 {
  padding-block: var(--y-56);
}

.section--y64 {
  padding-block: var(--y-64);
}

.section--y72 {
  padding-block: var(--y-72);
}

.section--y80 {
  padding-block: var(--y-80);
}

/* The one section with asymmetric padding in the design. */
.section--customers {
  padding-block: var(--y-64) var(--y-72);
}

/* Two-up copy/preview rows used by all four product pillars. */
.split {
  display: flex;
  align-items: center;
  gap: var(--col-gap);
}

.split > * {
  flex: 1 1 0;
  min-width: 0;
}

.split--reverse {
  flex-direction: row-reverse;
}

/* ------------------------------------------------------------ typography -- */

.display {
  font-size: var(--fs-display);
  font-weight: 700;
  line-height: 1.0294;
  letter-spacing: -0.037em;
  color: var(--text-inverse);
}

.h2 {
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1.087;
  letter-spacing: -0.039em;
}

/* About-page headings track slightly looser than the homepage's. */
.h2--loose {
  letter-spacing: -0.026em;
}

.h2--on-dark {
  color: var(--text-inverse);
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.6111;
  color: var(--text-muted);
}

.prose.lead--on-dark,
.lead--on-dark {
  color: var(--text-inverse-muted);
}

/* Section intros run a size smaller than the hero's subcopy. */
.lead--sm {
  font-size: 16px;
  line-height: 1.5625;
}

.prose {
  font-size: var(--fs-body);
  line-height: 1.59;
  color: var(--text-muted);
}

.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.11em;
  color: var(--text-inverse-muted);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px 26px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  transition:
    background-color 0.15s var(--ease),
    border-color 0.15s var(--ease),
    color 0.15s var(--ease),
    scale 0.1s var(--ease);
}

/* Hover is gated to fine pointers; this is what acknowledges a tap. */
.btn:active {
  scale: 0.97;
}

.btn svg {
  flex: none;
}

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

@media (hover: hover) and (pointer: fine) {
  .btn--accent:hover {
    background: #45c37e;
  }
}

.btn--ghost {
  border: 1px solid var(--border-dark-strong);
  color: var(--text-inverse);
  font-weight: 500;
}

@media (hover: hover) and (pointer: fine) {
  .btn--ghost:hover {
    border-color: var(--text-inverse-muted);
    background: #ffffff0f;
  }
}

.btn--sm {
  padding: 10px 18px;
  font-size: 14px;
}

.btn-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-top: 4px;
}

/* ------------------------------------------------------------------- nav -- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ink);
  border-bottom: 1px solid var(--border-dark);
}

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

.wordmark {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.3px;
  color: var(--text-inverse);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.5vw, 36px);
}

.nav__links a {
  font-size: 15px;
  color: var(--text-inverse-muted);
  transition: color 0.15s var(--ease);
}

/* Current-page colour must survive on touch; hover must not stick there and
   masquerade as it. */
.nav__links a[aria-current="page"] {
  color: var(--accent);
}

@media (hover: hover) and (pointer: fine) {
  .nav__links a:hover {
    color: var(--accent);
  }
}

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

.nav__signin {
  font-size: 15px;
  white-space: nowrap;
  color: var(--text-inverse);
  transition: color 0.15s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .nav__signin:hover {
    color: var(--accent);
  }
}

.nav__toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-dark-strong);
  border-radius: 999px;
  background: var(--ink-button);
  color: var(--text-inverse);
}

.nav__mobile-cta,
.nav__mobile-signin,
.nav__icon--close {
  display: none;
}

.nav__toggle[aria-expanded="true"] .nav__icon--open {
  display: none;
}

.nav__toggle[aria-expanded="true"] .nav__icon--close {
  display: block;
}

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

.hero {
  background: var(--ink);
  padding-block: var(--section-y) var(--y-96);
}

.hero__inner {
  display: flex;
  align-items: center;
  gap: 52px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  gap: 28px;
  flex: 0 1 500px;
  min-width: 0;
  max-width: 500px;
}

/* Below this the invoice table has nowhere to go and starts overprinting. */
.hero__panel {
  flex: 1 1 0;
  min-width: 420px;
}

/* The .pen fixes these frame heights, and the slack is visible in the design. */
.page-hero {
  display: flex;
  align-items: center;
  background: var(--ink);
  padding-block: var(--section-y);
}

.page-hero--about {
  min-height: 520px;
}

.page-hero--contact {
  min-height: 390px;
  padding-block: var(--y-80);
}

.section--origin {
  min-height: 410px;
}

.section--principles {
  display: flex;
  align-items: center;
  min-height: 516px;
}

.section--contact-form {
  min-height: 640px;
}

.page-hero > .shell,
.section--principles > .shell {
  flex: 1 1 auto;
}

.page-hero__inner {
  display: flex;
  align-items: center;
  gap: var(--col-gap);
}

.page-hero__copy {
  display: flex;
  flex-direction: column;
  gap: 28px;
  flex: 1 1 auto;
  max-width: 760px;
}

.page-hero .lead {
  max-width: 588px;
}

/* Green-ruled pull quote: About hero, and the "product behavior" note. */
.note {
  border-left: 2px solid var(--accent);
  padding: 8px 0 8px 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  flex: 0 1 415px;
}

.note__quote {
  font-size: 20px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--text-inverse);
}

/* ---------------------------------------------------------- shared panel -- */

/* Vignette internals sit at a fixed small type scale: they reflow, not scale. */
.panel {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  /* Three layers: a tight contact shadow, a mid lift, a wide ambient one. The
     border stays, so the inner box keeps its exact geometry. */
  box-shadow:
    0 1px 2px -1px #0000001f,
    0 10px 20px -10px #00000026,
    0 28px 56px -28px #00000030;
}

/* Vignette heights come from the design. min-height, not height: content that
   grows past them must push rather than disappear behind overflow:hidden. */
.panel--hero {
  min-height: 390px;
  box-shadow: 0 20px 44px -12px #00000078;
}

.panel--bills {
  min-height: 352px;
}

.panel--coding,
.panel--pay {
  min-height: 310px;
  box-shadow:
    0 1px 2px -1px #0000001f,
    0 10px 20px -10px #00000024,
    0 24px 48px -24px #0000002b;
}

.panel--dash {
  min-height: 340px;
}

.panel--dash .panel__head {
  min-height: 57.5px;
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--border);
}

/* Explicit in the design; keeps the invoice table in register below it. */
.panel--hero .panel__head {
  min-height: 61.5px;
}

.panel__title {
  font-size: 14px;
  font-weight: 700;
}

.panel__sub {
  font-size: 11px;
  color: var(--text-muted);
}

.panel__head-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

/* Two badges in the design run a size smaller than the rest. */
.tag--sm {
  font-size: 10px;
}

.tag--positive {
  background: var(--positive-tint);
  border: 1px solid var(--positive-line);
  color: var(--positive);
}

.tag--quiet {
  border: 1px solid var(--border);
  color: var(--text-muted);
}

.tag--flat {
  background: var(--paper-chip);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-family: var(--mono);
  letter-spacing: 0.06em;
}

.pill {
  display: inline-block;
  padding: 4px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.pill--positive {
  background: var(--positive-soft);
  color: var(--positive);
}

.pill--warn {
  background: var(--warn-soft);
  color: var(--warn);
}

.pill--warn-strong {
  background: var(--warn-pill);
  color: var(--warn);
  font-weight: 700;
}

.pill--neutral {
  background: var(--paper-chip-flat);
  color: var(--text-muted);
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
}

/* Small-caps mono labels used throughout the product vignettes. */
.ui-label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text-muted-2);
}

.ui-label--quiet {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.ui-ref {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted-2);
}

/* Generic mini table used by several vignettes. */
.grid-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
}

.grid-row--head {
  background: var(--paper-head);
  border-top: 1px solid var(--border);
  min-height: 29px;
}

.grid-row__main {
  flex: 1 1 0;
  min-width: 0;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cell-name {
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
}

.col-match,
.col-account,
.col-total,
.col-due,
.col-amount,
.cell-name,
.coding__name,
.ui-ref {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------- hero: invoice workflow -- */

.workflow__pipeline {
  display: flex;
  background: #f7f9f7;
  border-bottom: 1px solid var(--border);
  min-height: 83.5px;
  padding: 12px 18px;
}

.workflow__step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding-inline: 16px;
  border-right: 1px solid var(--border);
}

.workflow__step:first-child {
  padding-left: 0;
}

.workflow__step:last-child {
  border-right: 0;
  padding-right: 0;
}

.workflow__step-label {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted-2);
}

.workflow__step--warn .workflow__step-label {
  color: var(--warn);
}

.workflow__step-value {
  font-size: 21px;
  font-weight: 700;
}

.workflow__step-detail {
  font-size: 10px;
  color: var(--text-muted-2);
}

.workflow__main {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

.workflow__list {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.workflow__list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding-inline: 18px;
}

.workflow__list-title {
  font-size: 11px;
  font-weight: 700;
}

.workflow__list-note {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}

.workflow__row {
  min-height: 55.5px;
}

.workflow__row--flagged {
  background: var(--warn-row);
}

.workflow__row .cell-name {
  font-weight: 400;
}

.col-match {
  flex: 0 1 92px;
  min-width: 0;
  font-size: 11px;
  font-weight: 600;
}

.col-account {
  flex: 0 1 104px;
  min-width: 0;
  font-size: 11px;
  color: var(--text-muted);
}

.col-status {
  flex: 0 0 68px;
}

.is-matched {
  color: var(--positive);
}

.is-unmatched {
  color: var(--warn);
}

.workflow__aside {
  width: 250px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--paper-alt);
  border-left: 1px solid var(--border);
}

.workflow__aside-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
}

.workflow__aside-vendor {
  font-size: 13px;
  font-weight: 700;
}

.workflow__aside-amount {
  font-size: 10px;
}

.trail {
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1 1 auto;
  padding: 10px 14px;
}

.trail__steps {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.trail li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--text-muted);
}

.trail svg {
  flex: none;
}

.workflow__aside-action {
  padding: 8px 14px 10px;
}

.btn-solid {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 7px 10px;
  border-radius: 6px;
  background: var(--positive);
  color: var(--text-inverse);
  font-size: 11px;
  font-weight: 700;
  transition:
    background-color 0.15s var(--ease),
    scale 0.1s var(--ease);
}

.btn-solid:active {
  scale: 0.97;
}

@media (hover: hover) and (pointer: fine) {
  .btn-solid:hover {
    background: #1c7549;
  }
}

/* --------------------------------------------------------- category list -- */

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

.category-list {
  display: flex;
  gap: clamp(24px, 5vw, 72px);
}

.category-list__col {
  flex: 1 1 0;
  min-width: 0;
}

.category {
  display: flex;
  gap: 16px;
  padding-block: 12px;
  border-bottom: 1px solid var(--border);
}

.category svg {
  flex: none;
}

.category__info {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.category__title {
  font-size: 16px;
  font-weight: 600;
}

.category__desc {
  font-size: 14px;
  line-height: 1.57;
  color: var(--text-muted);
}

/* Mobile-only mid-page CTA bar. */
.midcta {
  display: none;
  background: var(--ink);
}

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

.midcta__text {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 200px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-inverse);
}

.midcta .btn {
  flex: none;
  height: 48px;
  min-width: 144px;
  padding-inline: 16px;
  font-weight: 700;
}

/* ---------------------------------------------------------- integrations -- */

.map {
  display: flex;
  align-items: stretch;
  min-height: 340px;
  padding-block: 8px;
}

.map__col {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}

.map__row {
  display: flex;
  align-items: center;
}

.card {
  display: flex;
  align-items: center;
  gap: 11px;
  flex: 1 1 0;
  min-width: 0;
  min-height: 59px;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: 6px;
}

.card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 6px;
  background: var(--positive-tint);
}

.card__icon--muted {
  background: var(--paper-sunken);
}

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

.card__name {
  font-size: 12px;
  font-weight: 700;
}

.card__desc {
  font-size: 11px;
  color: var(--text-muted);
}

.card__badge {
  flex: none;
  padding: 4px 6px;
  border-radius: 999px;
  background: var(--paper-sunken);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}

/* Horizontal rails linking the three columns of the map. */
/* 76 = the old 48 plus the 28px the wrap gave back, so a rail now runs from
   its card to the layer edge with nothing left over. The columns absorb the
   change; the cards next to them keep their width. */
.rail {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 76px;
  flex: none;
}

.rail__line {
  flex: 1 1 auto;
  height: 1px;
  background: var(--connector);
}

.rail--muted .rail__line {
  background: var(--border);
}

/* Sized to the layer exactly, so each rail meets the card edge with nothing
   left over. */
.map__layer-wrap {
  width: 274px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.layer {
  width: 274px;
  min-height: 242px;
  display: flex;
  flex-direction: column;
  gap: 17px;
  padding: 22px;
  background: var(--ink-raised);
  border: 1px solid var(--border-dark-strong);
  border-radius: 12px;
}

.layer__name {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-inverse);
}

.layer__title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.5px;
  color: var(--text-inverse);
}

.layer__desc {
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-inverse-muted);
}

.layer__copy {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.layer__steps {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.layer__step {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-inverse);
}

.layer__num {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--accent-on-dark);
}

.layer__rule {
  width: 14px;
  height: 1px;
  background: var(--rule-dark);
  flex: none;
}

.erp {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 0;
  min-width: 0;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: 6px;
}

.erp__title {
  font-size: 12px;
  font-weight: 700;
}

.erp__logos {
  display: flex;
  align-items: stretch;
  flex: 1 1 auto;
}

.erp__logo {
  flex: 1 1 auto;
  min-width: 0;
  flex-wrap: wrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 73px;
  border-right: 1px solid var(--border);
}

.erp__logo:last-child {
  border-right: 0;
}

.odoo {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.7px;
  color: #714b67;
}

.qb__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: #2ca01c;
  color: var(--text-inverse);
  font-size: 10px;
  font-weight: 700;
}

.qb__word {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: -0.25px;
  color: #2ca01c;
}

.zoho {
  display: flex;
  align-items: center;
  gap: 5px;
}

.zoho__blocks {
  display: flex;
  gap: 1px;
}

.zoho__blocks span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  border-radius: 2px;
  color: var(--text-inverse);
  font-size: 10px;
  font-weight: 800;
}

.zoho__word {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--text-muted);
}

/* In flow, indented to the cards' left edge rather than the rail's. The
   matching spacer above keeps the cards optically centred as the design has
   them, without an absolute offset that breaks when a card wraps. */
.map__note {
  margin-top: 1px;
  padding-left: 48px;
  font-size: 13px;
  line-height: 1.3846;
  color: var(--text-inverse-muted);
}

.map__col--systems::before {
  content: "";
  display: block;
  height: 29px;
}

/* Vertical arrows shown only in the stacked (mobile) map. */
.map__arrow {
  display: none;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 999px;
  background: var(--paper-alt);
  border: 1px solid var(--border);
}

/* ---------------------------------------------------------- product copy -- */

.pillar-copy {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.checks {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 8px;
}

.checks li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  color: var(--text-muted);
}

.checks svg {
  flex: none;
}

.behavior {
  border-left: 2px solid var(--accent);
  padding: 4px 0 4px 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.behavior__label {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--positive);
}

.behavior__quote {
  font-size: 19px;
  font-weight: 600;
  line-height: 1.47;
  letter-spacing: -0.4px;
  color: var(--text);
}

/* ------------------------------------------------------------ bills table -- */

.panel__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--border);
}

.chips {
  display: flex;
  align-items: center;
  gap: 6px;
}

.chip {
  padding: 5px 8px;
  border-radius: 999px;
  background: var(--paper-chip);
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
}

.chip--on {
  background: var(--positive-soft);
  color: var(--positive);
  font-weight: 600;
}

.search {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 130px;
  flex: none;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 11px;
  color: var(--text-muted-2);
}

.bills__row {
  gap: 14px;
  padding-inline: 16px;
  min-height: 43.5px;
}

.bills__row--head {
  min-height: 30.5px;
}

.panel--bills .panel__head {
  min-height: 57.5px;
}

.panel--bills .panel__toolbar {
  min-height: 42.5px;
}

.col-total {
  flex: 0 1 100px;
  min-width: 0;
  text-align: right;
  font-size: 11px;
  font-weight: 600;
}

.col-state {
  flex: 0 0 86px;
}

.col-due {
  flex: 0 1 76px;
  min-width: 0;
  text-align: right;
  font-size: 11px;
  color: var(--text-muted);
}

/* --------------------------------------------------------- coding review -- */

.coding__filters {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 38.5px;
  padding: 8px 18px;
  border-bottom: 1px solid var(--border);
}

.panel--coding .panel__head,
.panel--pay .panel__head {
  min-height: 53.5px;
}

.filter {
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--paper);
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
}

.filter--on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--text-inverse);
}

.coding__row {
  gap: 8px;
  padding-inline: 14px;
  min-height: 46.75px;
}

.coding__row--head {
  min-height: 27.5px;
}

.coding__row--head span {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.07em;
  color: var(--text-muted);
}

.coding__name {
  font-size: 10px;
  font-weight: 600;
}

.col-suggested {
  flex: 0 1 116px;
  min-width: 0;
}

.account-chip {
  display: inline-block;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--paper-sunken);
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted);
  white-space: nowrap;
}

.col-amount {
  flex: 0 1 69px;
  min-width: 0;
  text-align: right;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
}

.col-conf {
  flex: 0 0 46px;
  display: flex;
  justify-content: flex-end;
}

.conf {
  padding: 3px 5px;
  border-radius: 999px;
  background: var(--positive-tint);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--positive);
}

.conf--warn {
  background: var(--warn-tint);
  color: var(--warn);
}

/* -------------------------------------------------------------- payments -- */

.pay__summary {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: 65.5px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
}

.pay__amount {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pay__amount-value {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.4px;
}

.pay__meta {
  width: 100px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pay__meta-value {
  font-size: 11px;
  font-weight: 600;
}

.pay__flow {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 81.5px;
  padding: 11px 18px;
  border-bottom: 1px solid var(--border);
}

.pay__flow-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.pay__flow-title {
  font-size: 10px;
  font-weight: 700;
}

.pay__flow-time {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted);
}

.stepper {
  display: flex;
  align-items: center;
}

.stepper li {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 0;
  min-width: 0;
}

.stepper li:last-child {
  flex: none;
}

.stepper__dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 999px;
  background: var(--accent);
}

.stepper__dot--final {
  background: var(--positive);
}

.stepper__copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.stepper__label {
  font-size: 11px;
  font-weight: 600;
}

.stepper__time {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-muted-2);
}

.stepper__line {
  flex: 1 1 auto;
  min-width: 8px;
  height: 1px;
  background: var(--connector);
}

.approvals__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 26.5px;
  padding: 4px 18px;
  background: var(--paper-head);
  border-bottom: 1px solid var(--border);
}

.approvals__policy {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted);
}

.approval {
  gap: 9px;
  min-height: 40px;
}

.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 23px;
  height: 23px;
  flex: none;
  border-radius: 999px;
  background: var(--paper-chip-flat);
  border: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
}

.approval__role {
  font-size: 11px;
  color: var(--text-muted-2);
}

.approval__status {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--positive);
}

/* ------------------------------------------------------------- dashboard -- */

.dash {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1 1 auto;
  padding: 10px 12px;
}

.dash__top {
  display: flex;
  gap: 10px;
}

.dash__box {
  border: 1px solid var(--border);
  border-radius: 6px;
}

.vendors {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.vendors__head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
}

.vendors li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
}

.vendors__rank {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--text-muted-2);
}

.vendors__copy {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.vendors__line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  font-weight: 600;
}

.vendors__amount {
  color: var(--text-muted);
}

.track {
  height: 3px;
  border-radius: 999px;
  background: var(--track);
}

.track > i {
  display: block;
  height: 3px;
  border-radius: 999px;
  background: var(--accent);
}

.spend {
  width: 168px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 10px;
}

.spend__title {
  font-size: 11px;
  font-weight: 700;
}

.spend__body {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Shares as designed; the rest of the sweep is left open. */
.donut {
  width: 70px;
  height: 70px;
  flex: none;
  border-radius: 50%;
  /* Arc spans read off the design's clip paths, with its 4deg separators. */
  background: conic-gradient(
    #22a865 0deg 90deg,
    transparent 90deg 94deg,
    #dd6b55 94deg 120deg,
    transparent 120deg 124deg,
    #e7a735 124deg 182deg,
    transparent 182deg 186deg,
    #2477c5 186deg 278deg,
    transparent 278deg 282deg,
    #22a865 282deg 360deg
  );
  /* Ring runs from 62% to 100% of the radius, as the design's arcs do. */
  -webkit-mask: radial-gradient(circle closest-side, transparent 61.5%, #000 62%);
  mask: radial-gradient(circle closest-side, transparent 61.5%, #000 62%);
}

.legend {
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1 1 0;
  min-width: 0;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: var(--text-muted);
}

.trend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  padding: 8px 10px;
}

.trend__head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  font-weight: 700;
}

.trend__total {
  color: var(--positive);
  font-weight: 600;
}

/* Bar heights are absolute, so the track needs a definite height to sit in. */
.trend__bars {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  height: 86px;
  flex: none;
  padding: 2px 4px 0;
  border-bottom: 1px solid var(--border);
}

.trend__bars i {
  flex: 1 1 0;
  border-radius: 3px 3px 0 0;
  background: var(--bar-soft);
}

.trend__bars i.is-current {
  background: var(--accent);
}

/* ------------------------------------------------------------- customers -- */

/* A continuous run: a logo wall's job is the count, and this takes new logos
   at any number. The mask dissolves both edges so the band reads as endless. */
.logo-band {
  overflow: hidden;
  border-block: 1px solid var(--band-line);
  background: var(--band);
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 7%,
    #000 93%,
    transparent
  );
  mask-image: linear-gradient(
    90deg,
    transparent,
    #000 7%,
    #000 93%,
    transparent
  );
}

.logo-band__track {
  display: flex;
  width: max-content;
  animation: logo-band-scroll 46s linear infinite;
}

/* Pointer convenience: the band holds while the cursor rests on it. */
.logo-band:hover .logo-band__track {
  animation-play-state: paused;
}

/* The set is duplicated in the markup, so half a track is one whole cycle. */
@keyframes logo-band-scroll {
  to {
    transform: translateX(-50%);
  }
}

.logo-band__slot {
  flex: none;
  width: 208px;
  height: 108px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--band-line);
}

@media (max-width: 620px) {
  .logo-band__slot {
    width: 152px;
    height: 88px;
  }
}

/* Under reduced motion the band renders as a static 4x2 grid with the
   duplicate pass hidden. The animation is cancelled by name here: the global
   reduce block collapses durations, and a near-zero duration on an infinite
   marquee resolves to the track's end position. */
@media (prefers-reduced-motion: reduce) {
  .logo-band {
    -webkit-mask-image: none;
    mask-image: none;
    background: var(--band-line);
  }

  .logo-band__track {
    animation: none;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    width: auto;
  }

  .logo-band__slot {
    width: auto;
    min-width: 0;
    height: 108px;
    border-right: 0;
    background: var(--band);
  }

  .logo-band__slot[aria-hidden="true"] {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) and (max-width: 820px) {
  .logo-band__track {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* The site's single non-functional piece of motion, deliberately confined to
   one section. Scroll-driven and CSS-only: no JS, no library, and silently
   absent where view() is unsupported — the band just renders. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @keyframes logo-band-in {
      from {
        opacity: 0;
        translate: 0 8px;
      }
      to {
        opacity: 1;
        translate: 0 0;
      }
    }

    .logo-band {
      animation: logo-band-in linear both;
      /* Timed against the section, so the reveal spans the band's approach
         rather than the 110px of its own height. */
      animation-timeline: --customers;
      animation-range: cover 12% cover 42%;
    }

    .section--customers {
      view-timeline-name: --customers;
    }
  }
}

/* Each logo has its own box in the design, so sizes are set per logo. */
.logo-band img {
  object-fit: contain;
}

.logo--tissolli {
  width: 142px;
  height: 50px;
}

.logo--layn {
  width: 120px;
  height: 34px;
}

.logo--breadfast {
  width: 140px;
  height: 42px;
}

.logo--ariika {
  width: 120px;
  height: 36px;
}

/* The only one the design crops rather than fits. */
.logo-band .logo--lakanto {
  width: 132px;
  height: 44px;
  object-fit: cover;
  object-position: center;
}

.logo--sahl {
  width: 113px;
  height: 58px;
}

.logo--birdnest {
  width: 105px;
  height: 22px;
}

.logo--rabbit {
  width: 58px;
  height: 58px;
}

/* Three logos sit on their own brand-coloured field, as designed. */
.logo-field {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 144px;
  height: 64px;
  flex: none;
  border-radius: 6px;
}

/* Outline, not border: the design's stroke sits outside the 144x64 field. */
.logo-field--layn {
  background: #131e29;
  outline: 1px solid #2f3944;
}

.logo-field--sahl {
  background: #1167e8;
}

.logo-field--rabbit {
  background: #111111;
  outline: 1px solid var(--border-dark-strong);
}


/* -------------------------------------------------------------------- faq -- */

.faq {
  display: flex;
  flex-direction: column;
}

.faq__item {
  border-bottom: 1px solid var(--border);
}

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 16px;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  transition: color 0.15s var(--ease);
}

/* An open row sits on 18px padding with a 14px gap to its answer. */
.faq__item[open] summary {
  padding-top: 18px;
  padding-bottom: 14px;
}

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

@media (hover: hover) and (pointer: fine) {
  .faq__item summary:hover {
    color: var(--positive);
  }
}

.faq__item summary svg {
  flex: none;
  transition: rotate 0.2s var(--ease);
}

.faq__item[open] summary svg {
  rotate: 180deg;
}

/* Chevron and answer share the same 200ms. ::details-content reaches auto
   height through interpolate-size, set on :root. */
.faq__item::details-content {
  block-size: 0;
  overflow: hidden;
  transition:
    block-size 0.2s var(--ease),
    content-visibility 0.2s var(--ease) allow-discrete;
}

.faq__item[open]::details-content {
  block-size: auto;
}

.faq__answer {
  padding-bottom: 18px;
  max-width: 900px;
  font-size: 15px;
  line-height: 1.67;
  color: var(--text-muted);
}

/* -------------------------------------------------------------- final cta -- */

.final {
  background: var(--ink);
  border-top: 1px solid var(--border-dark);
  padding-block: var(--y-72);
  text-align: center;
}

.final__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.final__copy {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 760px;
}

/* ----------------------------------------------------------------- about -- */

.origin {
  display: flex;
  gap: var(--col-gap);
}

.origin > * {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.origin__statement {
  font-size: 24px;
  font-weight: 600;
  line-height: 1.29;
  color: var(--text);
}

.principles {
  display: flex;
  flex-direction: column;
}

.principles li {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-block: 20px;
  border-bottom: 1px solid var(--border);
  font-size: 17px;
  font-weight: 500;
}

.principles li:last-child {
  border-bottom: 0;
}

.principles svg {
  flex: none;
}

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

.team__heading {
  text-align: center;
  max-width: 760px;
  margin-inline: auto;
}

.founders {
  display: flex;
  gap: 24px;
}

.founder {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.founder__caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.founder img {
  width: 100%;
  height: clamp(240px, 31vw, 383px);
  object-fit: cover;
  border-radius: 6px;
}

.founder__name {
  font-size: clamp(24px, 20px + 1vw, 30px);
  font-weight: 700;
  letter-spacing: -0.5px;
}

.founder__role {
  font-size: 16px;
  font-weight: 600;
  color: var(--positive);
}

.record {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 32px 40px;
  /* Stays tinted: the section behind it is white, so a white fill would leave
     the card relying on shadow alone and it disappears. */
  background: var(--paper-alt);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow:
    0 1px 2px -1px #00000014,
    0 12px 28px -14px #00000024;
  text-align: center;
}

.record__title {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.6px;
  line-height: 1.07;
}

.record__intro {
  max-width: 820px;
  font-size: 15px;
  line-height: 1.53;
  color: var(--text-muted);
}

.figures {
  display: flex;
  width: 100%;
}

.figures li {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding-inline: 32px;
  border-left: 1px solid var(--border);
}

.figures li:first-child {
  border-left: 0;
}

.figures b {
  font-size: clamp(26px, 20px + 1.6vw, 32px);
  font-weight: 700;
  letter-spacing: -1.2px;
}

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

/* --------------------------------------------------------------- contact -- */

.contact {
  display: flex;
  gap: var(--col-gap);
  align-items: flex-start;
}

.contact__intro {
  width: 420px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.contact__intro .prose {
  max-width: 360px;
}

.direct {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.direct__prompt {
  font-size: 15px;
  color: var(--text-muted);
}

.direct__value {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
  transition: color 0.15s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .direct__value:hover {
    color: var(--positive);
  }
}

.form {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form__row {
  display: flex;
  gap: 16px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 0;
  min-width: 0;
}

.field label {
  font-size: 14px;
  font-weight: 500;
}

.field input,
.field textarea {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--field-border);
  border-radius: 6px;
  background: var(--paper-alt);
  font: inherit;
  font-size: 16px;
  color: var(--text);
  transition:
    border-color 0.15s var(--ease),
    background-color 0.15s var(--ease);
}

.field input {
  height: 48px;
}

.field textarea {
  height: 132px;
  resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-muted-2);
}

.field input:focus,
.field textarea:focus {
  /* No outline reset here: the global :focus-visible ring is the indicator.
     The border alone measured 2.67:1, under the 3:1 required for one. */
  border-color: var(--accent);
  background: var(--paper);
}

.field input:user-invalid,
.field textarea:user-invalid {
  border-color: #c0392b;
}

.form__submit {
  align-self: flex-start;
  height: 48px;
  padding-inline: 24px;
}

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

.form__note a {
  font-weight: 600;
  color: var(--positive);
}

.form__state {
  padding: 14px 16px;
  border-radius: 6px;
  font-size: 14px;
  line-height: 1.5;
  /* The one moment on the site where a visitor waits. Entry only: the message
     stays once shown. */
  transition:
    opacity 0.22s var(--ease),
    translate 0.22s var(--ease),
    filter 0.22s var(--ease);
}

@starting-style {
  .form__state {
    opacity: 0;
    translate: 0 6px;
    filter: blur(4px);
  }
}

.form__state--ok {
  background: var(--positive-soft);
  color: var(--positive);
}

.form__state--bad {
  background: #fdecea;
  color: #a33228;
}

/* ------------------------------------------------------------------- 404 -- */

.page-hero--404 {
  min-height: 420px;
}


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

.footer {
  background: var(--ink);
  border-top: 1px solid var(--border-dark);
  padding-block: var(--y-72) 36px;
}

.footer__inner {
  display: flex;
  flex-direction: column;
  gap: 48px;
}

.footer__top {
  display: flex;
  gap: 64px;
}

.footer__col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.footer__col .eyebrow {
  margin-bottom: 4px;
}

.footer__col a {
  padding-block: 4px;
  font-size: 14px;
  color: var(--text-inverse);
  transition: color 0.15s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .footer__col a:hover {
    color: var(--accent);
  }
}

.footer__tagline {
  font-size: 14px;
  line-height: 1.57;
  color: var(--text-inverse-muted);
}

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 28px;
  border-top: 1px solid var(--border-dark);
  font-size: 13px;
  color: var(--text-inverse-muted);
}

.footer__social {
  display: flex;
  align-items: center;
  gap: 8px;
  transition: color 0.15s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .footer__social:hover {
    color: var(--accent);
  }
}

/* -------------------------------------------------------- legal stub page -- */

.legal {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}


/* ============================================================ responsive == */

/* The invoice panel only has room for its side pane at the designed width;
   below that the list would overprint its own columns. */
@media (max-width: 1400px) {
  .workflow__aside {
    display: none;
  }

  .col-account {
    display: none;
  }
}

/* Tablet: the map and the wide product rows stop working side by side. */
@media (max-width: 1024px) {
  .hero__inner,
  .page-hero__inner {
    flex-direction: column;
    align-items: stretch;
    gap: 36px;
  }

  .split,
  .split--reverse,
  .origin,
  .contact {
    flex-direction: column;
    align-items: stretch;
  }

  /* Once a row stacks, flex-basis:0 would resolve against height and collapse
     these to nothing. Hand sizing back to their content. */
  .hero__inner > *,
  .page-hero__inner > *,
  .split > *,
  .origin > *,
  .contact > *,
  .map > * {
    flex: 0 0 auto;
  }

  .hero__copy {
    max-width: none;
  }

  /* Only meaningful while the panel sits beside the copy. */
  .hero__panel {
    min-width: 0;
  }

  .contact__intro {
    width: auto;
  }

  .contact__intro .prose {
    max-width: none;
  }

  /* The three columns stack here, and the arrows between them carry the flow. */
  .map {
    flex-direction: column;
    align-items: center;
    min-height: 0;
    gap: 12px;
  }

  /* Stacked, the note sits directly under the cards (the 390 design's order). */
  .map__note {
    padding-left: 0;
  }

  .map__col--systems::before {
    display: none;
  }

  .map__col,
  .map__layer-wrap {
    width: 100%;
  }

  .map__arrow {
    display: flex;
  }

  .rail {
    display: none;
  }

  .layer {
    width: 100%;
    min-height: 0;
  }


  .page-hero--about,
  .page-hero--contact,
  .section--origin,
  .section--principles,
  .section--contact-form {
    min-height: 0;
  }

  .panel--hero,
  .panel--bills,
  .panel--coding,
  .panel--pay,
  .panel--dash {
    min-height: 0;
  }
}

/* Below the tablet layout: single column, hamburger nav. */
@media (max-width: 800px) {
  .nav__links,
  .nav__actions .nav__signin,
  .nav__actions .btn {
    display: none;
  }

  .nav__toggle {
    display: flex;
  }

  .nav__inner {
    padding-block: 14px;
  }

  /* The largest surface on the site that changes state. display transitions
     discretely, which holds the panel rendered through its exit, and
     @starting-style supplies its entry values. Where both are supported the
     panel animates; elsewhere it swaps instantly. */
  .nav__links {
    opacity: 0;
    translate: 0 -8px;
    transition:
      opacity 0.2s var(--ease),
      translate 0.2s var(--ease),
      display 0.2s var(--ease) allow-discrete;
  }

  /* Hamburger panel. Static markup; JS only toggles the class. */
  .nav__links.is-open {
    position: absolute;
    inset: 100% 0 auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    max-height: calc(100dvh - 100%);
    overflow-y: auto;
    overscroll-behavior: contain;
    gap: 0;
    padding: 8px var(--gutter) 24px;
    background: var(--ink);
    border-bottom: 1px solid var(--border-dark);
    opacity: 1;
    translate: 0 0;
  }

  /* Must follow the rule above: at equal specificity the later rule wins the
     starting-style cascade, so placing this first would seed opacity 1 and the
     panel would jump. */
  @starting-style {
    .nav__links.is-open {
      opacity: 0;
      translate: 0 -8px;
    }
  }

  .nav__links.is-open a {
    padding-block: 14px;
    font-size: 17px;
    color: var(--text-inverse);
    border-bottom: 1px solid var(--border-dark);
  }

  .nav__links.is-open .nav__mobile-signin {
    display: block;
  }

  .nav__links.is-open .nav__mobile-cta {
    display: flex;
    justify-content: center;
    margin-top: 20px;
    padding: 15px 26px;
    border-bottom: 0;
    border-radius: 999px;
    background: var(--accent);
    color: var(--ink);
    font-weight: 600;
  }

  .category-list {
    flex-direction: column;
    gap: 0;
  }

  .midcta {
    display: block;
  }

  .founders {
    flex-direction: column;
  }

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

  .category-list > *,
  .founders > *,
  .figures > * {
    flex: 0 0 auto;
  }

  .figures li {
    border-left: 0;
    padding-inline: 0;
  }

  /* Brand takes its own row, the three link columns share the next. */
  .footer__top {
    flex-wrap: wrap;
    gap: 32px 24px;
  }

  .footer__col:first-child {
    flex: 1 1 100%;
  }
}

@media (max-width: 620px) {
  .hero__copy .btn-row .btn {
    flex: 1 1 auto;
    padding-inline: 16px;
  }

  .btn-row {
    flex-wrap: wrap;
  }

  /* Vignette columns the design drops on small screens. */
  .workflow__list-note,
  .search,
  .col-due,
  .approvals__policy {
    display: none;
  }

  .pay__summary {
    flex-wrap: wrap;
    gap: 12px 18px;
  }

  .stepper {
    flex-wrap: wrap;
    gap: 10px 16px;
  }

  .stepper li,
  .stepper li:last-child {
    flex: 1 1 40%;
  }

  .stepper__line {
    display: none;
  }

  .dash__top {
    flex-direction: column;
  }

  .form__row > *,
  .dash__top > * {
    flex: 0 0 auto;
  }

  .spend {
    width: auto;
  }

  .record {
    padding: 24px 20px;
  }

  .form__row {
    flex-direction: column;
  }

  .form__submit {
    align-self: stretch;
  }

  .footer__bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
}

/* Registering the property as an angle is what lets the sweep interpolate. */
@property --sweep {
  syntax: "<angle>";
  initial-value: 360deg;
  inherits: false;
}

/* ------------------------------------------------- mockups, on scroll -- */

/* The dashboards are the product, so they run as they enter view. Everything
   here is scroll-driven and guarded: an inactive timeline with fill: both
   resolves to the final state, which is what unsupported browsers and reduced
   motion each render. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* --- payment trend: bars grow off the axis, left to right --- */
    @keyframes bar-grow {
      from {
        scale: 1 0;
      }
      to {
        scale: 1 1;
      }
    }

    /* The timeline is named on the panel, so every child inherits the panel's
       travel. An `entry` range measures against the subject's own height, which
       for a 70px donut or an 86px bar comes to about 30px of scrolling. */
    .panel--dash {
      view-timeline-name: --dash;
    }

    .trend__bars i {
      transform-origin: bottom;
      animation: bar-grow linear both;
      animation-timeline: --dash;
      /* Scroll-driven animations take their offset from the range, so each bar
         gets its own slice of it. */
      animation-range: cover calc(28% + var(--i, 0) * 1.8%) cover
        calc(52% + var(--i, 0) * 1.8%);
    }

    .trend__bars i:nth-child(1) { --i: 0; }
    .trend__bars i:nth-child(2) { --i: 1; }
    .trend__bars i:nth-child(3) { --i: 2; }
    .trend__bars i:nth-child(4) { --i: 3; }
    .trend__bars i:nth-child(5) { --i: 4; }
    .trend__bars i:nth-child(6) { --i: 5; }
    .trend__bars i:nth-child(7) { --i: 6; }
    .trend__bars i:nth-child(8) { --i: 7; }
    .trend__bars i:nth-child(9) { --i: 8; }
    .trend__bars i:nth-child(10) { --i: 9; }

    /* --- payment trail: the run ticks through, dot by dot --- */
    /* This panel sits under "Every payment. One controlled trail", and the
       trail is that claim, so it runs in sequence. Driven by the panel for the
       same reason as the dashboard: an 18px dot spans a few pixels of its own
       entry. */
    .panel--pay {
      view-timeline-name: --pay;
    }

    @keyframes pay-dot {
      from {
        opacity: 0;
        scale: 0.6;
      }
      to {
        opacity: 1;
        scale: 1;
      }
    }

    @keyframes pay-line {
      from {
        scale: 0 1;
      }
      to {
        scale: 1 1;
      }
    }

    .panel--pay .stepper__dot,
    .panel--pay .stepper__copy {
      animation: pay-dot linear both;
      animation-timeline: --pay;
      animation-range: cover calc(26% + var(--i, 0) * 6%) cover
        calc(31% + var(--i, 0) * 6%);
    }

    .panel--pay .stepper__line {
      /* Draws away from the dot it leaves. */
      transform-origin: left center;
      animation: pay-line linear both;
      animation-timeline: --pay;
      animation-range: cover calc(29% + var(--i, 0) * 6%) cover
        calc(34% + var(--i, 0) * 6%);
    }

    .panel--pay .stepper li:nth-child(1) { --i: 0; }
    .panel--pay .stepper li:nth-child(2) { --i: 1; }
    .panel--pay .stepper li:nth-child(3) { --i: 2; }
    .panel--pay .stepper li:nth-child(4) { --i: 3; }
  }

  /* --- spend donut: the ring draws itself --- */
  /* Guarded on mask-composite separately. The fallback is the full ring, which
     --sweep's 360deg initial value supplies. */
  @supports (animation-timeline: view()) and (mask-composite: intersect) {
    @keyframes donut-draw {
      from {
        --sweep: 0deg;
      }
      to {
        --sweep: 360deg;
      }
    }

    .donut {
      /* The shorthand resets timeline and range, so it comes first, matching
         the order used for the bars and the payment trail. */
      animation: donut-draw linear both;
      animation-timeline: --dash;
      animation-range: cover 26% cover 52%;
      -webkit-mask:
        radial-gradient(circle closest-side, transparent 61.5%, #000 62%),
        conic-gradient(#000 var(--sweep), transparent 0);
      mask:
        radial-gradient(circle closest-side, transparent 61.5%, #000 62%),
        conic-gradient(#000 var(--sweep), transparent 0);
      -webkit-mask-composite: source-in;
      mask-composite: intersect;
    }
  }
}

/* ------------------------------------------------ section reveals -- */

/* Two elements per section, in hierarchy: the heading, then the copy under it.
   Staggering every list as well is the most recognisable "we added animation"
   pattern, and these sections are lists of lists, so it would fire dozens of
   times on one page.

   Headings move and hold opacity 1, for the same reason the hero headline does:
   LCP counts an element once it paints visibly, and a section h2 is this page's
   LCP element. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @keyframes sec-head {
      from {
        translate: 0 16px;
      }
      to {
        translate: 0 0;
      }
    }

    @keyframes sec-copy {
      from {
        translate: 0 10px;
      }
      to {
        translate: 0 0;
      }
    }

    .section .h2 {
      animation: sec-head linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 32%;
    }

    .section .lead {
      animation: sec-copy linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 38%;
    }
  }
}

/* ------------------------------------------------------ view transitions -- */

/* Same-origin navigation morphs between pages. Where it is supported the pair
   cross-fades; elsewhere the navigation is ordinary. */
@view-transition {
  navigation: auto;
}

/* Naming these pairs them across documents, so the chrome holds still while
   the content changes. */
.nav {
  view-transition-name: site-nav;
}

.footer {
  view-transition-name: site-footer;
}

/* Retimes the browser's own cross-fade. The pair composites with
   mix-blend-mode: plus-lighter, which reaches full opacity while the two sides
   stay complementary — so both run one duration, symmetric and untransformed,
   and the composite stays opaque throughout. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: var(--ease);
}

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

/* Seen once per visit, so it can afford to be expressive. The headline moves
   and holds opacity 1: LCP counts an element once it paints visibly, and this
   is the biggest text in the viewport. Everything after it is small enough to
   fade freely. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes hero-rise {
    from {
      translate: 0 14px;
    }
  }

  @keyframes hero-in {
    from {
      opacity: 0;
      translate: 0 12px;
    }
  }

  .hero .display {
    animation: hero-rise 500ms var(--ease) both;
  }

  /* Also translate-only. At shorter viewports the section h2 falls below the
     fold and this paragraph becomes the Largest Contentful Paint element;
     fading it measured 476ms against 260ms for the same content unfaded. */
  .hero .lead {
    animation: hero-rise 500ms var(--ease) 80ms both;
  }

  .hero .btn-row {
    animation: hero-in 500ms var(--ease) 160ms both;
  }

  .hero__panel {
    animation: hero-in 600ms var(--ease) 220ms both;
  }

  /* The four counters land after the panel itself has arrived. */
  @keyframes kpi-in {
    from {
      opacity: 0;
      translate: 0 8px;
      filter: blur(4px);
    }
    to {
      opacity: 1;
      translate: 0 0;
      filter: blur(0);
    }
  }

  .panel--hero .workflow__step-value {
    animation: kpi-in 420ms var(--ease) both;
  }

  .panel--hero .workflow__step:nth-child(1) .workflow__step-value {
    animation-delay: 480ms;
  }

  .panel--hero .workflow__step:nth-child(2) .workflow__step-value {
    animation-delay: 560ms;
  }

  .panel--hero .workflow__step:nth-child(3) .workflow__step-value {
    animation-delay: 640ms;
  }

  .panel--hero .workflow__step:nth-child(4) .workflow__step-value {
    animation-delay: 720ms;
  }

  /* The automation trail lives in the hero panel, in view on arrival, so it is
     timed with the entrance. */
  @keyframes trail-in {
    from {
      opacity: 0;
      translate: -6px 0;
    }
    to {
      opacity: 1;
      translate: 0 0;
    }
  }

  .panel--hero .trail__steps li {
    animation: trail-in 360ms var(--ease) both;
  }

  .panel--hero .trail__steps li:nth-child(1) { animation-delay: 620ms; }
  .panel--hero .trail__steps li:nth-child(2) { animation-delay: 700ms; }
  .panel--hero .trail__steps li:nth-child(3) { animation-delay: 780ms; }
  .panel--hero .trail__steps li:nth-child(4) { animation-delay: 860ms; }
}

@media (prefers-reduced-motion: reduce) {
  /* The view-transition tree sits outside the universal selector below, so the
     navigation morph is switched off by name here. */
  @view-transition {
    navigation: none;
  }

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Forced-colors overrides background, which would erase the white logo artwork
   on its coloured plates and flatten both chart series to one colour. */
@media (forced-colors: active) {
  .logo-field,
  .donut,
  .track > i,
  .trend__bars i,
  .stepper__dot {
    forced-color-adjust: none;
  }

  .btn,
  .field input,
  .field textarea {
    border: 1px solid currentColor;
  }
}
