/*
  ShyPipe landing — the whole design system, in one cached file.

  ── Why this is external and the app's is not ─────────────────────────────

  This started inline in each page, which is right for one or two hand-written
  files and wrong at nine. The threshold was reached the moment /hjelp/ existed:
  eight kilobytes duplicated per page, and a token change meaning nine edits
  that must not disagree.

  One file, one cache. _headers gives it a long max-age; the filename is stable
  because the CSS changes about as often as the copy does, and a hashed name
  would mean regenerating every page that links to it.

  ── The tokens come from the app's PIPE CANVAS ────────────────────────────

  Not from its ordinary surface tokens. The canvas tokens are already absolute
  dark values that deliberately do NOT invert with the theme — the board is a lit
  surface you look into, and flipping it white would make it a different feature
  rather than a light one. That property is exactly what a dark-only marketing
  site needs, so the two agree by construction instead of by somebody
  remembering to keep them in step.
*/

/*
  ── Tokens ────────────────────────────────────────────────────────────

  Lifted from the app's PIPE CANVAS, not from its ordinary surface tokens,
  and that is the whole trick to this page not feeling like a brochure
  bolted onto a different product.

  The canvas tokens are already absolute dark values that deliberately do
  NOT invert with the theme — the board is a lit surface you look into, the
  way a map table is, and flipping it white would make it a different
  feature rather than a light one. That property is exactly what a
  dark-only marketing page needs, so the two agree by construction instead
  of by somebody remembering to keep them in step.

  --brand is kobolt-500, the app's default accent. It is ~3.6:1 on the
  surface: fine for fills and large type, NOT enough for body text. That is
  what --brand-ink is for at ~6.3:1. Never use --brand on small text.
*/
:root {
  --surface: #0f1319;
  --surface-2: #141924;
  --surface-3: #1c2431;
  --line: #2e3a4d;
  --line-soft: #232c3a;
  --dot: #2a3444;

  --ink: #e7ecf3;
  --ink-2: #94a2b8;
  /* 5.6:1 — the canvas's own --pipe-ink-faint sits at 3.5:1, which is fine
 for a label beside a shape and not fine for a sentence. */
  --ink-3: #7d8a9e;

  --brand: #4e64cd;
  --brand-ink: #7186dc;
  --brand-soft: rgba(78, 100, 205, 0.12);

  --due: #d99a2b;
  --leak: #b4544e;
  --good: #4c9a6a;

  --radius: 12px;
  --radius-lg: 18px;
  --maxw: 1080px;
  --pad: clamp(20px, 5vw, 40px);
}

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

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

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
  font-weight: 700;
}

h1 {
  font-size: clamp(2.1rem, 6vw, 3.6rem);
}
h2 {
  font-size: clamp(1.5rem, 3.6vw, 2.2rem);
}
h3 {
  font-size: 1.05rem;
  font-weight: 600;
}

p {
  margin: 0;
}

a {
  color: var(--brand-ink);
  text-underline-offset: 3px;
}

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

.container {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}

section {
  padding: clamp(56px, 9vw, 104px) 0;
}

/* A band one shade up, for alternating sections. */
.band {
  background: var(--surface-2);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}

.eyebrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand-ink);
  margin: 0 0 14px;
}

.lead {
  color: var(--ink-2);
  font-size: clamp(1.02rem, 2vw, 1.2rem);
  max-width: 58ch;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 12px;
  top: 12px;
  z-index: 100;
  background: var(--surface-3);
  padding: 10px 16px;
  border-radius: var(--radius);
}

/* ── Buttons ─────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: var(--radius);
  font-size: 0.96rem;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition:
background-color 0.15s ease,
border-color 0.15s ease,
transform 0.15s ease;
}

.btn-primary {
  background: var(--brand);
  color: #fff;
}
.btn-primary:hover {
  background: #5c72d8;
}

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

/* ── Header ──────────────────────────────────────────────────────── */

header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(15, 19, 25, 0.86);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-soft);
}

.nav {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-top: 12px;
  padding-bottom: 12px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}
.brand img {
  width: 32px;
  height: 32px;
  display: block;
}

.nav .btn {
  padding: 8px 16px;
  font-size: 0.9rem;
}

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

.hero {
  position: relative;
  padding-top: clamp(48px, 8vw, 88px);
}

/*
  The dot texture lives on a PSEUDO-ELEMENT, not on .hero itself.

  mask-image masks the whole element, CONTENT INCLUDED. With the fade on
  .hero the text faded with it, and the ShyBucks line at the bottom of the
  section came out half-transparent. The mask was only ever meant for the
  texture, so the texture is what it is applied to now.

  Fading it downward still matters: a texture that runs the whole page
  stops reading as texture and starts reading as noise.
*/
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle, var(--dot) 1px, transparent 1px);
  background-size: 24px 24px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 100%);
}

/* Above the texture, and unmasked. */
.hero > .container {
  position: relative;
  z-index: 1;
}

.hero-grid {
  display: grid;
  gap: clamp(32px, 5vw, 56px);
  align-items: center;
}

@media (min-width: 900px) {
  .hero-grid {
    grid-template-columns: 1fr 1fr;
  }

  /*
    ── Overskriften skal brekke der <br> sier, og ingen andre steder ────────

    Fra 900px deles hero i to kolonner, og overskriften har plutselig bare
    halve bredden å gå på. Med den globale h1-størrelsen (opptil 3,6rem) er
    «Fire positive svar.» bredere enn kolonnen, så «svar.» havnet alene på
    egen linje. Tre linjer der det var ment to, og den ene med ett ord.

    Løsningen er størrelsen, ikke nowrap. `white-space: nowrap` ville flyttet
    problemet til et overløp som stikker ut av kolonnen, og det er verre enn
    en stygg brekking. 4vw med tak på 3,2rem holder begge setningene innenfor
    kolonnen i hele området fra 900px og oppover.

    Under 900px er hero én kolonne i full bredde, og den globale
    clamp(2.1rem, 6vw, 3.6rem) gjelder som før.
  */
  .hero h1 {
    font-size: clamp(2.1rem, 4vw, 3.2rem);
  }
}

.hero h1 {
  margin-bottom: 18px;
  /* Ingen orddeling i en overskrift. Et bindestrek-brutt «prospekterings-»
     i 50px bold er verre enn en kort linje. */
  hyphens: none;
}

.hero .cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.cta-note {
  margin-top: 14px;
  font-size: 0.86rem;
  color: var(--ink-3);
}

/* ── The pipe mockup ─────────────────────────────────────────────────
   MOCKUP CONVENTION — read before adding or removing one.
   Each mockup is self-contained between a pair of banner comments and owns
   a class prefix nothing else touches (.pipe-*, .row-*). Its markup is one
   aria-hidden block. To remove: delete the CSS banner block and the markup.
   There is deliberately no third place to remember.
   An animated mockup carries its own prefers-reduced-motion rule INSIDE
   its own block, freezing it in a state that still reads correctly.
   ────────────────────────────────────────────────────────────────────── */

.mock {
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: 1px solid var(--line);
  box-shadow: 0 40px 70px -40px rgba(0, 0, 0, 0.9);
  overflow: hidden;
}

.mock-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  background: var(--surface-3);
  border-bottom: 1px solid var(--line);
}
.mock-dots {
  display: flex;
  gap: 6px;
}
.mock-dots i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line);
}
.mock-url {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  font-size: 0.7rem;
  color: var(--ink-3);
  padding: 4px 12px;
  text-align: center;
}

.pipe-canvas {
  position: relative;
  aspect-ratio: 4 / 3.4;
  background-color: var(--surface);
  background-image: radial-gradient(circle, var(--dot) 1px, transparent 1px);
  background-size: 22px 22px;
  overflow: hidden;
}

/*
  The funnel: four bands, each narrower than the one above it.

  Laid out as a centred COLUMN with flex inside each band, not as a pile of
  absolutely-positioned labels and dots. The first version placed every
  element by percentage and the result was exactly what that always
  produces — labels sitting on top of the shapes they name, a node outside
  the funnel it was supposed to be inside, and a bottom label the same
  colour as the band behind it.
*/
.pipe-funnel {
  position: absolute;
  /* The bottom inset clears the badge. space-between pushes the last band
 to the funnel bottom, so anything less than the badge height put the
 two side by side. */
  inset: 14px 0 76px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.pipe-stage {
  width: var(--w);
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 7px 10px 9px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

.pipe-label {
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  /* --ink-2, not --ink-3: on the band fill rather than the canvas, the
 fainter token drops under 3:1 and the bottom label disappeared. */
  color: var(--ink-2);
  white-space: nowrap;
}
.pipe-count {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* The dots belonging to a stage, on their own row under its label. */
.pipe-dots-row {
  display: flex;
  gap: 7px;
  align-items: center;
  min-height: 9px;
}

.pipe-node {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--brand-ink);
  flex: none;
}
/* Hollow = they replied and gave nothing. The shape IS the warning. */
.pipe-node.hollow {
  background: transparent;
  border: 1.5px solid var(--due);
}
.pipe-node.lost {
  background: var(--leak);
}
.pipe-node.won {
  background: var(--good);
}

/*
  The connector between two bands, and the thing that travels down it.

  An earlier version drifted dots across the whole board and they crossed
  the stage labels on the way, which is motion fighting the thing it
  decorates. The joint is the one place a dot can move without covering
  anything, so that is where the movement lives now.

  translateY on a pseudo-element: no layout, runs on the compositor, and
  costs nothing on a page that is otherwise static.
*/
.pipe-join {
  position: relative;
  width: 2px;
  height: 16px;
  background: linear-gradient(to bottom, var(--line), var(--line-soft));
  border-radius: 2px;
}

.pipe-join::after {
  content: '';
  position: absolute;
  left: -2px;
  top: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand-ink);
  animation: pipe-flow 2.4s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

@keyframes pipe-flow {
  0% {
transform: translateY(-4px);
opacity: 0;
  }
  25% {
opacity: 1;
  }
  70% {
opacity: 1;
  }
  100% {
transform: translateY(16px);
opacity: 0;
  }
}

/*
  The point of the whole product, in one shape: a hollow node filling in.
  They gave something. Runs on its own slower cycle so it does not read as
  part of the drift.
*/
.pipe-commit {
  animation: pipe-commit 9s ease-in-out infinite;
}

@keyframes pipe-commit {
  0%,
  45% {
background: transparent;
border-color: var(--due);
box-shadow: none;
  }
  55%,
  92% {
background: var(--good);
border-color: var(--good);
box-shadow: 0 0 0 5px rgba(76, 154, 106, 0.22);
  }
  100% {
background: transparent;
border-color: var(--due);
box-shadow: none;
  }
}

.pipe-badge {
  position: absolute;
  /* BOTTOM right. At the top it sat on the widest band, which is the one
 part of the funnel that has no spare room. The bands narrow downward,
 so the bottom corners are the only reliably empty space. */
  right: 12px;
  bottom: 12px;
  background: rgba(17, 21, 29, 0.9);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 7px 10px;
  font-size: 0.66rem;
  color: var(--ink-2);
  line-height: 1.5;
}
/*
  The number counts DOWN when the commit lands, and that pairing is the
  whole product in four seconds: one of the warm-and-empty ones finally
  gave something, so there is one fewer to worry about.

  Grid-stacked rather than absolutely positioned, so the badge sizes to the
  widest state instead of to whichever value happens to render first. Same
  9s cycle as .pipe-commit, so the two are one event rather than two things
  that happen to move.
*/
.pipe-tally {
  display: inline-grid;
  font-variant-numeric: tabular-nums;
}
.pipe-tally i {
  grid-area: 1 / 1;
  font-style: normal;
  animation: pipe-tally 9s ease-in-out infinite;
}
.pipe-tally i:last-child {
  animation-name: pipe-tally-alt;
}

@keyframes pipe-tally {
  0%, 45% { opacity: 1; }
  55%, 92% { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes pipe-tally-alt {
  0%, 45% { opacity: 0; }
  55%, 92% { opacity: 1; }
  100% { opacity: 0; }
}

.pipe-badge strong {
  color: var(--due);
  display: block;
  font-size: 0.74rem;
}

@media (prefers-reduced-motion: reduce) {
  /* Frozen already-committed. The story still reads. */
  .pipe-join::after {
animation: none;
opacity: 0;
  }
  .pipe-tally i {
animation: none;
opacity: 0;
  }
  .pipe-tally i:last-child {
opacity: 1;
  }
  .pipe-commit {
animation: none;
background: var(--good);
border-color: var(--good);
  }
}
/* ── end pipe mockup ─────────────────────────────────────────────── */

/* ── Feature grid ────────────────────────────────────────────────── */

.grid-3 {
  display: grid;
  gap: 18px;
  margin-top: 40px;
}
@media (min-width: 760px) {
  .grid-3 {
grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 22px;
}
.band .card {
  background: var(--surface-3);
}
.card h3 {
  margin-bottom: 8px;
}
.card p {
  color: var(--ink-2);
  font-size: 0.94rem;
}

.step-n {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--brand-ink);
  display: block;
  margin-bottom: 10px;
}

/* ── Two-column prose rows ───────────────────────────────────────── */

.row {
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
}
@media (min-width: 900px) {
  .row {
grid-template-columns: 1fr 1fr;
  }
  .row.flip > *:first-child {
order: 2;
  }
}

.row h2 {
  margin-bottom: 16px;
}
.row p + p {
  margin-top: 14px;
}
.row p {
  color: var(--ink-2);
}

.checks {
  list-style: none;
  padding: 0;
  margin: 20px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.checks li {
  display: flex;
  gap: 10px;
  color: var(--ink-2);
  font-size: 0.94rem;
}
.checks svg {
  flex: none;
  margin-top: 4px;
  color: var(--brand-ink);
}

/* ── Price ───────────────────────────────────────────────────────── */

.price-grid {
  display: grid;
  gap: 18px;
  margin-top: 36px;
}
@media (min-width: 720px) {
  .price-grid {
grid-template-columns: repeat(4, 1fr);
  }
}
.price {
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 18px;
  text-align: center;
}
.price .kr {
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.price .sb {
  color: var(--ink-2);
  font-size: 0.88rem;
  margin-top: 2px;
}
.price .bonus {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.72rem;
  color: var(--good);
  border: 1px solid rgba(76, 154, 106, 0.35);
  border-radius: 999px;
  padding: 1px 8px;
}

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

footer {
  border-top: 1px solid var(--line-soft);
  padding: 44px 0;
  color: var(--ink-3);
  font-size: 0.88rem;
}
.foot {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 28px;
  align-items: baseline;
}
.foot nav {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-left: auto;
}
footer a {
  color: var(--ink-2);
  text-decoration: none;
}
footer a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* ── Article pages: legal, help, om-roboten ───────────────────────────────
   The landing page is a grid of sections; these are documents. Narrower
   measure, tighter heading rhythm, and the table styles the sub-processor
   list needs. */

.doc {
  max-width: 720px;
}

.doc h2 {
  font-size: 1.18rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 42px 0 12px;
}

.doc h3 {
  font-size: 1rem;
  margin: 28px 0 8px;
}

.doc p {
  margin: 0 0 16px;
  color: var(--ink-2);
}

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

.doc ul,
.doc ol {
  margin: 0 0 16px;
  padding-left: 22px;
  color: var(--ink-2);
}

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

.doc code {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.86em;
  background: var(--surface-3);
  padding: 1px 5px;
  border-radius: 4px;
}

.updated {
  color: var(--ink-3);
  font-size: 0.88rem;
  margin-bottom: 34px;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 16px;
  font-size: 0.92rem;
}

th,
td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
  color: var(--ink-2);
}

th {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--line);
}

/* Wide content scrolls inside its own box; the page body never does. */
.scroller {
  overflow-x: auto;
}

.note {
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin: 0 0 16px;
}

.note.warn {
  border-left-color: var(--due);
}

.note p:last-child {
  margin-bottom: 0;
}

/* ── Breadcrumbs ─────────────────────────────────────────────────────── */

.crumbs {
  font-size: 0.82rem;
  color: var(--ink-3);
  margin-bottom: 18px;
}

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

.crumbs a:hover {
  text-decoration: underline;
}

/* ── Help index ──────────────────────────────────────────────────────── */

.help-grid {
  display: grid;
  gap: 14px;
  margin-top: 28px;
}

@media (min-width: 700px) {
  .help-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.help-card {
  display: block;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 18px 20px;
  text-decoration: none;
  transition: border-color 0.15s ease;
}

.help-card:hover {
  border-color: var(--brand);
}

.help-card strong {
  display: block;
  color: var(--ink);
  font-size: 1rem;
  margin-bottom: 5px;
}

.help-card span {
  color: var(--ink-2);
  font-size: 0.9rem;
}

/* ── FAQ ─────────────────────────────────────────────────────────────── */

.faq {
  margin-top: 34px;
  border-top: 1px solid var(--line-soft);
}

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

.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 18px 34px 18px 0;
  font-weight: 600;
  font-size: 1rem;
  position: relative;
}

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

/* A plus that becomes a minus. Rotating one bar is cheaper than swapping
   two icons, and it animates. */
.faq summary::after,
.faq summary::before {
  content: '';
  position: absolute;
  right: 6px;
  top: 50%;
  width: 13px;
  height: 2px;
  background: var(--ink-3);
  border-radius: 2px;
  transition: transform 0.2s ease;
}

.faq summary::before {
  transform: rotate(90deg);
}

.faq details[open] summary::before {
  transform: rotate(0deg);
}

.faq details p {
  margin: 0 0 18px;
  color: var(--ink-2);
  max-width: 62ch;
}
