/* ============================================================================
   SoftSync — lead-magnet modules
   Loaded only on the six lead-magnet pages, via PAGE_STYLES in
   src/lib/pageStyles.ts. Everything here is scoped to a block class that
   appears nowhere else, so nothing in landing.css or pages.css changes.

   Built on landing.css's vocabulary: .wrap, .eyebrow, .lead, .hl, .reveal,
   .section-ink, and the tokens from softsync-tokens.css. No new colours are
   invented — the palette is the same warm cream + near-black ink.
============================================================================ */

/* ── Shared: screen-reader-only text ──────────────────────────────────────
   landing.css has no such utility, and only the spreadsheet block needs one
   (to label the row-number gutter). Defined here rather than added globally so
   the base stylesheet is untouched. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Shared: the small dated source stamp several of these pages carry ─────
   A claim about someone else's price needs a date and a source next to it, or
   it stops being true the week they change it. Deliberately plain and small:
   this is a footnote, not a badge. */
.stamp {
  margin-top: clamp(20px, 3vw, 32px);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-4);
  max-width: 68ch;
}
.stamp a { text-decoration: underline; text-underline-offset: 2px; }
.section-ink .stamp { color: rgba(255, 255, 255, 0.4); }

/* ── Section head shared by the new blocks ───────────────────────────────── */
.mag-head { max-width: 22ch; }
.mag-head--wide { max-width: 34ch; }
/* A third width, for a head that sits over something full-bleed rather than
   over a column. At 34ch a four-line intro stands as a tall narrow strip in the
   left third of a 1140px page and reads as a column that lost its neighbour;
   over the two-column carry-over block, which fills the whole width, that looks
   like a mistake. 50ch still keeps the headline off a single long line, and the
   intro stops short of the 75ch where a measure starts costing you the return
   sweep. */
.mag-head--xwide { max-width: 50ch; }
.mag-head--xwide p.lead { max-width: 76ch; }
.mag-head .eyebrow { margin: 0 0 18px; }
.mag-head p.lead { margin: 20px 0 0; max-width: 58ch; }

/* ============================================================================
   1 · Feature graveyard  (/no/overkill)
   The other CRM's whole feature list, with the handful a four-person company
   will ever touch left lit and the rest dimmed almost out of sight.

   The dimming is the argument, so it has to be severe — at opacity .8 it reads
   as "a long list", at .18 it reads as "a wall you are paying for". The lit
   rows are NOT just brighter: they are a different size and carry a rule, so
   the contrast survives a greyscale print and a colourblind reader.
============================================================================ */
.graveyard { background: var(--ink); color: #fff; }
.graveyard h2, .graveyard .eyebrow { color: #fff; }
.graveyard .eyebrow { color: rgba(255, 255, 255, 0.45); }
.graveyard .lead { color: rgba(255, 255, 255, 0.7); }

.gy-mask {
  margin-top: clamp(36px, 5vw, 56px);
  position: relative;
}
.gy-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 4;
  column-gap: clamp(20px, 3vw, 44px);
  font-size: 14px;
  line-height: 1.45;
}
.gy-list li {
  break-inside: avoid;
  padding: 5px 0;
}
/* The mass. Not interactive, not readable at a glance, and that is the point. */
.gy-dead {
  color: rgba(255, 255, 255, 0.19);
  letter-spacing: -0.002em;
}
/* The six. */
.gy-live {
  display: flex;
  align-items: baseline;
  gap: 9px;
  color: #fff;
  font-size: 15.5px;
  font-weight: 500;
  padding-left: 11px;
  border-left: 2px solid #fff;
  margin-left: -13px;
}
.gy-live::before {
  content: "";
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #fff;
  transform: translateY(-3px);
}
.gy-count {
  margin: clamp(28px, 4vw, 40px) 0 0;
  font-family: var(--mono);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.55);
}
.gy-count b { color: #fff; font-weight: 500; }

@media (max-width: 900px) { .gy-list { columns: 2; } }
@media (max-width: 560px) {
  .gy-list { columns: 1; font-size: 13.5px; }
  .gy-live { font-size: 15px; }
}

/* ============================================================================
   2 · Price ladder  (/no/overkill)
   The tier jump, drawn as steps. The riser between two steps is the whole
   story, so the height of each step is proportional to its price — a ladder
   where every step is the same height would hide exactly what it is meant to
   show.
============================================================================ */
.ladder {
  margin-top: clamp(36px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(var(--rungs, 3), minmax(0, 1fr));
  gap: clamp(10px, 1.6vw, 18px);
  align-items: end;
}
.rung {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  min-height: 96px;
  padding: 18px;
  border: 1px solid var(--line);
  border-bottom: 3px solid var(--ink-4);
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--bg-raised);
}
/* The tier you are actually pushed onto. */
.rung--jump {
  border-color: var(--ink);
  border-bottom-color: var(--ink);
  background: var(--bg-sunken);
  box-shadow: var(--shadow);
}
.rung-tier {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.rung-price {
  font-size: clamp(24px, 3.4vw, 38px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
}
/* The unit is a block, not an inline run. Two reasons. Astro strips the leading
   space out of `<span> {unit}</span>`, so inline it rendered as "450 krper
   bruker / mnd" — a space in the markup cannot be relied on here. And in a five
   column ladder the column is ~190px while the price alone is ~150px, so an
   inline unit wrapped mid-phrase to "per bruker /" and "mnd". On its own line it
   is one predictable row in every rung. */
.rung-price span { display: block; margin-top: 5px; font-size: 12.5px; font-weight: 400;
  color: var(--ink-3); letter-spacing: 0; }
/* Reserve three lines whatever the note says. The rungs are bottom-aligned, so
   without this the price sits at a different height in every column: a one-line
   note pushes its price down level with the notes beside it, and the row of
   prices, which is the thing being compared, stops being a row. Three is the
   longest note the ladder currently carries; a longer one grows the rung rather
   than breaking, which is the right way for this to fail. */
.rung-note { font-size: 13.5px; line-height: 1.45; color: var(--ink-3); margin: 0;
  min-height: 59px; min-height: 3lh; }
.rung--jump .rung-note { color: var(--ink-2); }

@media (max-width: 700px) {
  .ladder { grid-template-columns: 1fr; align-items: stretch; }
  .rung { min-height: 0; border-radius: var(--radius); border-bottom-width: 1px; }
  .rung--jump { border-left: 3px solid var(--ink); }
  /* One column, so there is no row of prices to keep level and the reserved
     three lines would just be a gap under every short note. */
  .rung-note { min-height: 0; }
}

/* ============================================================================
   3 · Sheet decay  (/no/regnearket)
   A spreadsheet that starts sane on the left and falls apart to the right.

   Real spreadsheet chrome — column letters, row numbers, a frozen first
   column — because the recognition is the emotional payload. Without the
   frozen column you scroll right and lose which customer a row belongs to,
   which is the one thing an actual spreadsheet gets right.
============================================================================ */
.sheet {
  margin-top: clamp(32px, 4vw, 48px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.sheet-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunken);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
}
.sheet-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line-strong); flex: none; }
.sheet-name { color: var(--ink-2); font-weight: 500; }
.sheet-hint { margin-left: auto; display: flex; align-items: center; gap: 6px; color: var(--ink-4); }
.sheet-hint svg { width: 13px; height: 13px; }

.sheet-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.sheet table {
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.5;
  white-space: nowrap;
  min-width: 100%;
}
.sheet th, .sheet td {
  padding: 8px 14px;
  border-right: 1px solid var(--line-2);
  border-bottom: 1px solid var(--line-2);
  text-align: left;
  font-weight: 400;
  color: var(--ink-2);
  background: var(--bg-raised);
}
/* Column letters + row numbers: the grey gutter that says "spreadsheet". */
.sheet .sheet-ref th, .sheet .sheet-ref td,
.sheet .rownum {
  background: var(--bg-sunken);
  color: var(--ink-4);
  font-size: 11px;
  text-align: center;
  padding: 5px 10px;
}
.sheet thead.sheet-cols th {
  background: var(--bg-sunken);
  color: var(--ink);
  font-weight: 500;
  position: relative;
}
/* Frozen first data column, so the customer stays put while the mess scrolls. */
.sheet .col-sticky {
  position: sticky;
  left: 0;
  z-index: 2;
  border-right: 1px solid var(--line-strong);
  box-shadow: 3px 0 6px -4px rgba(0, 0, 0, 0.12);
}
.sheet .rownum { position: sticky; left: 0; z-index: 3; }
.sheet .col-sticky.rownum { z-index: 4; }

/* Four stages of rot. Each stage changes MORE than colour — weight, case and
   letter-spacing shift too, so the decay reads without relying on hue. */
.d-0 { }
.d-1 { color: var(--ink-3); }
.d-2 { color: var(--ink-4); font-style: italic; }
.d-3 { color: #a2402f; font-weight: 500; }
.sheet thead.sheet-cols th.d-2 { color: var(--ink-4); }
.sheet thead.sheet-cols th.d-3 { color: #a2402f; }
.sheet td.cell-flag { background: #fbeceb; color: #a2402f; }
.sheet td.cell-empty { background: repeating-linear-gradient(135deg, transparent, transparent 5px, var(--bg-sunken) 5px, var(--bg-sunken) 6px); }

.sheet-foot {
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-4);
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}

@media (max-width: 560px) {
  .sheet table { font-size: 11.5px; }
  .sheet th, .sheet td { padding: 7px 10px; }
}

/* ============================================================================
   4 · Org.nr reveal  (/no/norsk)
   Nine digits, then everything those nine digits already know.

   The digits are one <span> per character rather than one string, because the
   stagger is what sells it as a lookup rather than a headline. Dotted leaders
   on the resolved rows because that is how a register prints.
============================================================================ */
/* Left, not centred. Centred, the block read as a monument to a number: the
   digits sat in the middle of the page with the resolved rows floating under
   them, and nothing lined up with the heading above or the list below. Ranged
   left it reads as what it is, a lookup returning a record, and the digits, the
   caption and the rows all share one edge with the rest of the page. */
.orgnr { text-align: left; }
.orgnr-digits {
  display: flex;
  justify-content: flex-start;
  gap: clamp(5px, 1vw, 11px);
  margin: clamp(28px, 4vw, 44px) 0 clamp(12px, 2vw, 20px);
  flex-wrap: wrap;
}
.orgnr-digits b {
  font-family: var(--mono);
  font-weight: 500;
  font-size: clamp(28px, 6.4vw, 62px);
  line-height: 1;
  padding: clamp(10px, 1.6vw, 20px) clamp(8px, 1.4vw, 16px);
  min-width: clamp(34px, 6.6vw, 68px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.orgnr-cap {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin: 0;
}

.orgnr-out {
  list-style: none;
  margin: clamp(34px, 5vw, 54px) 0 0;
  padding: 0;
  max-width: 640px;
  text-align: left;
  border-top: 1px solid var(--line);
}
.orgnr-out li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 13px 2px;
  border-bottom: 1px solid var(--line-2);
  font-size: 15px;
}
.orgnr-out .k {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-4);
  flex: none;
}
.orgnr-out .dots {
  flex: 1;
  border-bottom: 1px dotted var(--line-strong);
  transform: translateY(-4px);
  min-width: 20px;
}
.orgnr-out .v { font-weight: 500; color: var(--ink); text-align: right; }

/* ============================================================================
   5 · Bad translations  (/no/norsk)
   English term · what they call it in "Norwegian" · what it is actually called.
============================================================================ */
.xlate {
  margin-top: clamp(32px, 4vw, 48px);
  border-top: 1px solid var(--ink);
}
.xlate-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1.2fr);
  gap: clamp(12px, 2.4vw, 32px);
  align-items: baseline;
  padding: 15px 2px;
  border-bottom: 1px solid var(--line-2);
}
.xlate-head {
  border-bottom: 1px solid var(--line);
  padding-block: 10px;
}
.xlate-head span {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.xlate-en { font-size: 15px; color: var(--ink-3); font-family: var(--mono); }
.xlate-them { font-size: 17px; color: #a2402f; font-weight: 500; }
.xlate-them .strike { text-decoration: line-through; text-decoration-thickness: 1px; opacity: 0.75; }
.xlate-us { font-size: 17px; font-weight: 500; color: var(--ink); }

@media (max-width: 620px) {
  .xlate-row { grid-template-columns: 1fr; gap: 3px; padding: 14px 2px; }
  .xlate-head { display: none; }
  .xlate-en { font-size: 12.5px; }
  .xlate-them::before { content: "deres: "; font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); }
  .xlate-us::before { content: "vårt: "; font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); }
}

/* ============================================================================
   6 · Headcount band  (/no/smaa)
   Ten filled dots, then the sizes we are honestly not for.
============================================================================ */
.band { margin-top: clamp(34px, 5vw, 52px); }
.band-dots {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  align-items: center;
}
.band-dots i {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  flex: none;
  background: var(--ink);
  border: 1px solid var(--ink);
}
.band-dots i.out {
  background: transparent;
  border-color: var(--line-strong);
}
.band-dots .gap { width: 14px; flex: none; }
.band-legend {
  display: flex;
  gap: clamp(18px, 4vw, 48px);
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.band-legend div { max-width: 34ch; }
.band-legend b {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-bottom: 6px;
  font-weight: 500;
}
.band-legend p { margin: 0; font-size: 15.5px; line-height: 1.5; color: var(--ink-2); }
.band-legend div.is-us b { color: var(--ink); }

/* ============================================================================
   7 · Price receipt  (/no/prisen)
   Two till receipts side by side. Theirs is long. Ours is four lines.

   The torn bottom edge is a repeating conic gradient rather than an image, so
   it scales and inverts with the theme. It is decoration and nothing depends
   on it rendering.
============================================================================ */
.receipts {
  margin-top: clamp(36px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(18px, 3vw, 34px);
  align-items: start;
}
.receipt {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: clamp(22px, 3vw, 32px) clamp(20px, 3vw, 30px) 0;
  box-shadow: var(--shadow);
  position: relative;
}
/* Torn edge. Sits under the card and is masked into zigzag teeth. */
.receipt::after {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  bottom: -11px;
  height: 12px;
  background:
    linear-gradient(var(--line), var(--line)) top / 100% 1px repeat-x,
    var(--bg-raised);
  -webkit-mask: repeating-conic-gradient(from -45deg at bottom, #000 0deg 90deg, transparent 90deg 180deg) 0 0 / 14px 12px;
  mask: repeating-conic-gradient(from -45deg at bottom, #000 0deg 90deg, transparent 90deg 180deg) 0 0 / 14px 12px;
}
.receipt--ours { border-color: var(--ink); box-shadow: var(--shadow-lg); }
.receipt--ours::after { background: linear-gradient(var(--ink), var(--ink)) top / 100% 1px repeat-x, var(--bg-raised); }

.receipt h3 {
  font-family: var(--sans);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
}
.receipt-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--ink-4);
  margin: 7px 0 0;
  text-transform: uppercase;
}
.receipt-lines {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 13px;
}
.receipt-lines li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 9px 0;
  border-bottom: 1px dotted var(--line-strong);
  color: var(--ink-2);
}
.receipt-lines .rl-label { flex: 1; min-width: 0; white-space: normal; }
.receipt-lines .rl-amount { flex: none; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.receipt-lines .rl-note {
  display: block;
  font-size: 11px;
  color: var(--ink-4);
  margin-top: 3px;
  font-family: var(--sans);
  letter-spacing: 0;
}
.receipt-lines li.rl-forced .rl-amount { color: #a2402f; }
.receipt-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
  padding: 18px 0 clamp(22px, 3vw, 30px);
  border-top: 2px solid var(--ink);
}
.receipt-total .rt-k {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.receipt-total .rt-v {
  font-size: clamp(26px, 3.6vw, 38px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.receipt-foot {
  margin: -6px 0 clamp(22px, 3vw, 28px);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-3);
}

/* ============================================================================
   8 · Stack list  (/no/stack)
   One job per row: the pick, why, and the honest alternative.
============================================================================ */
.stack { margin-top: clamp(32px, 4vw, 48px); border-top: 1px solid var(--ink); }
.stack-row {
  display: grid;
  grid-template-columns: minmax(0, 0.5fr) minmax(0, 1.5fr) minmax(0, 0.75fr);
  gap: clamp(12px, 2.4vw, 34px);
  align-items: start;
  padding: clamp(18px, 2.4vw, 26px) 2px;
  border-bottom: 1px solid var(--line-2);
}
/* The one row that is us. Marked, not hidden — the page's whole claim is that
   it does not quietly sell. */
.stack-row--ours { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); padding-left: 16px; }
.stack-job {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding-top: 5px;
}
.stack-pick { font-size: clamp(19px, 2.2vw, 24px); font-weight: 600; letter-spacing: -0.022em; margin: 0; }
.stack-why { margin: 7px 0 0; font-size: 15.5px; line-height: 1.5; color: var(--ink-2); }
.stack-alt { font-size: 14px; line-height: 1.5; color: var(--ink-3); padding-top: 6px; }
.stack-alt b {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
  font-weight: 500;
  margin-bottom: 4px;
}
.stack-ours-tag {
  display: inline-block;
  margin-left: 9px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 500;
  color: #fff;
  background: var(--ink);
  padding: 3px 7px;
  border-radius: var(--radius-sm);
  vertical-align: 3px;
}

/* The independence pledge. A bordered note, not a badge — it is a promise the
   reader should be able to hold us to, so it reads as prose. */
.pledge {
  margin-top: clamp(32px, 4vw, 48px);
  border: 1px solid var(--ink);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 3vw, 32px);
  background: var(--bg-raised);
  max-width: 62ch;
}
.pledge b {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-bottom: 10px;
  font-weight: 500;
}
.pledge p { margin: 0; font-size: 16.5px; line-height: 1.6; color: var(--ink-2); }
.pledge p + p { margin-top: 12px; }

@media (max-width: 760px) {
  .stack-row { grid-template-columns: 1fr; gap: 6px; }
  .stack-row--ours { padding-left: 14px; }
  .stack-alt { padding-top: 10px; }
}

/* ============================================================================
   9 · Principles (3-up)
   The block type has existed in the Studio schema since the start with no
   component behind it. Three of these pages want exactly this shape, so it is
   finally drawn: a hairline over each column, heading, text.
============================================================================ */
.principles-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: clamp(24px, 3.6vw, 52px);
  margin-top: clamp(30px, 4vw, 46px);
}
.principles-3 > div { border-top: 2px solid var(--ink); padding-top: 20px; }
.principles-3 h3 { font-size: clamp(20px, 2.2vw, 25px); margin: 0 0 10px; letter-spacing: -0.024em; }
.principles-3 p { margin: 0; font-size: 16px; line-height: 1.6; color: var(--ink-2); }
.section-ink .principles-3 > div { border-top-color: #fff; }
.section-ink .principles-3 p { color: rgba(255, 255, 255, 0.72); }

/* ============================================================================
   10 · Consultant chain  (/no/salesforce)
   A small request, and the chain it turns into.

   Two columns per request: a numbered rail on their side that grows taller with
   every step, one line on ours. The height difference is the argument, which is
   why the rail is vertical and numbered rather than a wrapping row of pills —
   the first attempt at this wrapped ten steps into a blob and hid the very
   thing it was drawing.
============================================================================ */
.cc-score {
  display: flex;
  align-items: stretch;
  gap: clamp(18px, 4vw, 48px);
  margin-top: clamp(30px, 4vw, 44px);
  padding: clamp(20px, 3vw, 28px) 0;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--line);
}
.cc-score-cell { display: flex; flex-direction: column; gap: 4px; }
.cc-score-cell b {
  font-size: clamp(36px, 6vw, 68px);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 0.95;
  font-variant-numeric: tabular-nums;
  color: var(--ink-4);
}
.cc-score-cell span {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cc-score-cell--ours b { color: var(--ink); }
.cc-score-div { width: 1px; background: var(--line); flex: none; }

.cc-list { margin-top: clamp(8px, 2vw, 18px); }
.cc-row { padding: clamp(28px, 4vw, 44px) 0; border-bottom: 1px solid var(--line-2); }
.cc-ask {
  font-size: clamp(21px, 2.7vw, 30px);
  font-weight: 600;
  letter-spacing: -0.026em;
  line-height: 1.22;
  margin: 0 0 clamp(20px, 3vw, 28px);
  max-width: 34ch;
}
.cc-ask::before { content: "\201c"; color: var(--ink-4); }
.cc-ask::after  { content: "\201d"; color: var(--ink-4); }

.cc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(20px, 4vw, 56px);
  align-items: start;
}
.cc-side-label {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cc-side-n {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--ink-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}

/* The rail. Counter drawn by CSS so the markup stays a plain <ol>. */
.cc-rail { list-style: none; margin: 0; padding: 0; counter-reset: rail; }
.cc-rail li {
  counter-increment: rail;
  position: relative;
  padding: 0 0 13px 34px;
  font-size: 15px;
  line-height: 1.4;
  color: var(--ink-2);
}
.cc-rail li::before {
  content: counter(rail, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 1px;
  width: 22px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-4);
  text-align: right;
}
/* The connector: a hairline from each number to the next. */
.cc-rail li::after {
  content: "";
  position: absolute;
  left: 10px;
  top: 17px;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
}
.cc-rail li:last-child { padding-bottom: 0; }
.cc-rail li:last-child::after { display: none; }
.cc-rail li:last-child { color: var(--ink); font-weight: 500; }

.cc-toll {
  margin: 16px 0 0;
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #a2402f;
  background: #fbeceb;
  border-radius: var(--radius-sm);
  padding: 6px 10px;
}

/* Our side sits on the sunken surface so the eye reads it as the short answer,
   not as a second list. */
.cc-side--us {
  background: var(--bg-sunken);
  border-left: 3px solid var(--ink);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: clamp(16px, 2.4vw, 22px);
}
.cc-side--us .cc-side-label { color: var(--ink); }
.cc-answer { margin: 0; font-size: clamp(16px, 1.9vw, 19px); line-height: 1.5; color: var(--ink); }
.cc-answer--none { color: var(--ink-3); }

@media (max-width: 760px) {
  .cc-grid { grid-template-columns: 1fr; gap: 20px; }
  .cc-score-cell b { font-size: clamp(32px, 12vw, 48px); }
}

/* ============================================================================
   11 · Never done  (/no/salesforce)
   A setup checklist that never finishes.

   Percentage is computed from the list in the component, so the bar and the
   ticks can never disagree. Done and remaining are two labelled columns: mixed
   into one list it reads as a to-do list, split it shows which column is
   longer, which is the point.
============================================================================ */
.nd { margin-top: clamp(32px, 4vw, 48px); }
.nd-meter {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: clamp(20px, 3vw, 28px);
  box-shadow: var(--shadow-sm);
}
.nd-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.nd-label {
  display: block;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.nd-count { margin: 6px 0 0; font-size: 14px; color: var(--ink-4); }
.nd-pct { font-size: clamp(34px, 5vw, 54px); font-weight: 600; letter-spacing: -0.035em; line-height: 1; font-variant-numeric: tabular-nums; }
.nd-bar { height: 8px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; border: 1px solid var(--line); }
.nd-fill { height: 100%; background: var(--ink); border-radius: 999px; }
.nd-since { margin: 14px 0 0; font-size: 14px; color: var(--ink-3); }

.nd-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(22px, 4vw, 56px);
  margin-top: clamp(26px, 3.5vw, 40px);
}
.nd-col h3 {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.nd-col h3 span {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--ink-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
.nd-col ul { list-style: none; margin: 0; padding: 0; font-size: 15px; }
.nd-col li { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; line-height: 1.45; }
.nd-col .box {
  flex: none;
  width: 15px; height: 15px;
  margin-top: 3px;
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  background: var(--bg-raised);
  position: relative;
}
.nd-col--done { color: var(--ink-4); }
.nd-col--done .box { background: var(--ink-4); border-color: var(--ink-4); }
.nd-col--done .box::after {
  content: "";
  position: absolute;
  left: 4px; top: 1px;
  width: 5px; height: 9px;
  border: solid var(--bg-raised);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(40deg);
}
.nd-col--open h3 { color: var(--ink); border-bottom-color: var(--ink); }
.nd-col--open li { color: var(--ink-2); }

@media (max-width: 700px) { .nd-cols { grid-template-columns: 1fr; gap: 26px; } }

/* ============================================================================
   12 · Crossed logo  (/no/salesforce)
   Someone else's mark, struck through, with the line that earns it.
============================================================================ */
.xlogo { text-align: center; }
.xlogo--dark { background: var(--ink); color: #fff; }
.xlogo--dark h2 { color: #fff; }
.xlogo--dark .eyebrow { color: rgba(255, 255, 255, 0.45); }
.xlogo--dark .lead { color: rgba(255, 255, 255, 0.72); }
.xlogo--dark .stamp { color: rgba(255, 255, 255, 0.4); }
.xlogo-inner { max-width: 720px; margin: 0 auto; }
.xlogo-inner h2 { margin-top: clamp(26px, 3.5vw, 38px); }
.xlogo-inner .lead { margin: 18px auto 0; max-width: 52ch; }
.xlogo-inner .stamp { margin-inline: auto; }

.xlogo-mark {
  position: relative;
  display: inline-block;
  padding: clamp(10px, 2vw, 18px) clamp(14px, 2.6vw, 26px);
}
.xlogo-mark img {
  display: block;
  width: auto;
  max-width: min(100%, 320px);
  height: auto;
  /* The mark is not ours to restyle, so it is left alone apart from being
     dimmed slightly, which keeps the strike readable over it. */
  opacity: 0.72;
}
.xlogo--dark .xlogo-mark img { filter: invert(1) grayscale(1); opacity: 0.62; }
.xlogo-strike { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.xlogo-strike line { stroke: #a2402f; stroke-width: 3; stroke-linecap: round; }
.xlogo--dark .xlogo-strike line { stroke: #e8916f; }
@media (prefers-reduced-motion: no-preference) {
  .reveal .xlogo-strike line { stroke-dasharray: 200; stroke-dashoffset: 200; }
  .reveal.in .xlogo-strike line { stroke-dashoffset: 0; transition: stroke-dashoffset .5s var(--ease) .25s; }
}

/* ============================================================================
   13 · Browser frame  (/no/chrome)
   The extension drawn where it lives: a panel docked over the page you already
   had open.

   Markup rather than a screenshot, because a screenshot shows one site and the
   argument is that it works on any of them. Window chrome follows sheetDecay's
   precedent rather than inventing a second vocabulary for the same idea.
============================================================================ */
.bf {
  margin-top: clamp(32px, 4vw, 48px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.bf-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunken);
}
.bf-dots { display: flex; gap: 6px; flex: none; }
.bf-dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-strong); }
.bf-url {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 13px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bf-url svg { width: 12px; height: 12px; flex: none; color: var(--ink-4); }
/* The pinned toolbar button the panel comes out of. */
.bf-pin {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: var(--radius-sm);
  background: var(--bg-inset, var(--bg-hover));
  border: 1px solid var(--line-strong);
}
.bf-pin img { width: 14px; height: 14px; }

.bf-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); }
.bf-page { padding: clamp(18px, 2.6vw, 30px); border-right: 1px solid var(--line); min-width: 0; }
.bf-shot { width: 100%; height: auto; border-radius: var(--radius); border: 1px solid var(--line); }

/* The abstraction of "somebody's profile". Nobody reads it; they recognise it. */
.bf-mock { display: flex; flex-direction: column; gap: 11px; }
.bf-mock-head { display: flex; align-items: center; gap: 13px; margin-bottom: 8px; }
.bf-mock-avatar { width: 44px; height: 44px; border-radius: 50%; background: var(--bg-inset, var(--bg-sunken)); border: 1px solid var(--line); flex: none; }
.bf-mock-head span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bf-mock-head b { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.bf-mock-head i { font-style: normal; font-size: 13px; color: var(--ink-4); }
.bf-mock-line { height: 9px; border-radius: 999px; background: var(--bg-sunken); }

/* The panel. Sits on the sunken surface so it reads as over the page, not in it. */
.bf-panel {
  background: var(--bg-sunken);
  padding: clamp(14px, 2vw, 18px);
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
.bf-panel header { display: flex; align-items: center; gap: 8px; }
.bf-panel header span {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.bf-status {
  margin-left: auto;
  font-style: normal;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 3px 8px;
  white-space: nowrap;
}

.bf-fields { margin: 0; display: flex; flex-direction: column; }
.bf-field { display: flex; flex-direction: column; gap: 3px; padding: 8px 0; border-bottom: 1px solid var(--line-2); }
.bf-field:last-child { border-bottom: 0; }
.bf-field dt {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.bf-field dd { margin: 0; display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--ink); min-width: 0; }
/* Where the value came from. This is the line that makes the Norwegian point. */
.bf-source {
  flex: none;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 2px 5px;
}
/* A field still being fetched. */
.bf-ghost { display: block; width: 68%; height: 10px; border-radius: 999px; background: var(--bg-raised); border: 1px dashed var(--line-strong); }

.bf-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.bf-actions span {
  font-size: 11.5px;
  color: var(--ink-2);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 10px;
}
.bf-cta {
  display: block;
  text-align: center;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  padding: 11px 14px;
  font-size: 13.5px;
  font-weight: 500;
}

/* The same panel, other addresses. Makes "any page" visible without five
   more frames. */
.bf-urls { margin-top: clamp(20px, 3vw, 28px); }
.bf-urls-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin: 0 0 12px;
}
.bf-urls ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.bf-urls li {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 12px;
}

@media (max-width: 760px) {
  .bf-body { grid-template-columns: 1fr; }
  .bf-page { border-right: 0; border-bottom: 1px solid var(--line); }
  .bf-panel { gap: 12px; }
}

/* ============================================================================
   14 · Price calculator  (/no/kalkulator)
   The receipt on /no/prisen with the dials exposed.

   Laid out as two columns that hold their own arithmetic rather than as one
   table with a shared row grid. A table implies the two sides are commensurate,
   and they are not: the left column is in the vendor's currency and the right
   is in kroner, and nothing here converts between them. Two separate receipts
   say that without a sentence.

   The controls carry `hidden` in the markup and are unhidden by the script.
   With JavaScript off the reader gets every vendor stacked at the default seat
   count, which is a complete answer, rather than a row of buttons that do
   nothing.
============================================================================ */
.pc { margin-top: clamp(32px, 4vw, 48px); }

/* ── Controls ─────────────────────────────────────────────────────────────
   Sits above the cards on a rule, so it reads as instrumentation rather than
   as the first row of the comparison. */
.pc-controls {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(20px, 4vw, 48px);
  align-items: flex-end;
  padding-bottom: clamp(18px, 2.4vw, 24px);
  margin-bottom: clamp(22px, 3vw, 30px);
  border-bottom: 1px solid var(--line);
}
.pc-ctl-label {
  display: block;
  margin-bottom: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pc-step {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  overflow: hidden;
}
.pc-step button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 18px;
  line-height: 1;
  padding: 0 16px;
  cursor: pointer;
  transition: background .15s var(--ease);
}
.pc-step button:hover:not(:disabled) { background: var(--bg-hover); }
.pc-step button:disabled { color: var(--ink-4); cursor: default; }
.pc-num {
  min-width: 3.2ch;
  padding: 10px 4px;
  text-align: center;
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-inline: 1px solid var(--line);
}

/* Segmented year picker. Same shape as the pricing page's billing toggle, but
   without the sliding pill — three static options do not need choreography. */
.pc-seg {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  overflow: hidden;
}
.pc-seg button {
  appearance: none;
  border: 0;
  border-left: 1px solid var(--line);
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 14px;
  padding: 11px 16px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.pc-seg button:first-child { border-left: 0; }
.pc-seg button:hover { background: var(--bg-hover); }
.pc-seg button.on { background: var(--ink); color: #fff; }

/* ── Vendor tabs ─────────────────────────────────────────────────────────── */
.pc-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: clamp(20px, 3vw, 28px);
}
.pc-tabs button {
  appearance: none;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--ink-3);
  font: inherit;
  font-size: 14px;
  padding: 8px 16px;
  cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.pc-tabs button:hover { border-color: var(--ink-4); color: var(--ink); }
.pc-tabs button.on { background: var(--ink); border-color: var(--ink); color: #fff; }

/* ── The two receipts ────────────────────────────────────────────────────── */
.pc-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(18px, 3vw, 32px);
  align-items: start;
}
.pc-them { display: grid; gap: clamp(18px, 3vw, 32px); }

.pc-card {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: clamp(20px, 3vw, 30px);
  box-shadow: var(--shadow-sm);
}
/* Ours carries the emphasised left edge, the same device the receipts on
   /no/prisen use to mark which column is our own. */
.pc-card--ours {
  border-left: 3px solid var(--ink);
  background: var(--bg-sunken);
}

.pc-card-head { padding-bottom: 16px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.pc-card-name {
  margin: 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pc-card--ours .pc-card-name { color: var(--ink); }
.pc-card-plan {
  margin: 8px 0 0;
  font-size: clamp(16px, 2vw, 19px);
  line-height: 1.4;
  color: var(--ink);
}

.pc-lines { list-style: none; margin: 0; padding: 0; }
.pc-lines li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line-2);
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--ink-3);
}
.pc-lines b {
  flex: none;
  font-weight: 500;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.pc-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  margin: 18px 0 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pc-total b {
  font-family: var(--sans);
  font-size: clamp(24px, 3.6vw, 34px);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-transform: none;
  font-variant-numeric: tabular-nums;
}

/* The seat cliff. Same warm red as the consultant chain's toll, because it is
   the same kind of fact: a cost the vendor's own page does not show you. */
.pc-cliff {
  margin: 14px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: #a2402f;
  background: #fbeceb;
  border-radius: var(--radius-sm);
  padding: 9px 12px;
}

.pc-unpriced { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.pc-unpriced-label {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.pc-unpriced ul { list-style: none; margin: 0; padding: 0; }
.pc-unpriced li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-2);
}
.pc-unpriced em { display: block; font-style: normal; font-size: 12.5px; color: var(--ink-4); margin-top: 2px; }
/* The question mark is the argument, so it is set at the same weight as a real
   number rather than as a placeholder. */
.pc-unpriced b {
  flex: none;
  font-size: 19px;
  font-weight: 600;
  color: var(--ink-4);
}

.pc-src { margin: 18px 0 0; font-family: var(--mono); font-size: 11.5px; color: var(--ink-4); }
.pc-src a { color: var(--ink-3); text-decoration: underline; text-underline-offset: 2px; }
.pc-ournote { margin: 16px 0 0; font-size: 14px; line-height: 1.55; color: var(--ink-3); }
.pc-foot { margin-top: clamp(22px, 3vw, 30px); font-size: 15px; line-height: 1.6; color: var(--ink-2); max-width: 62ch; }

@media (max-width: 880px) {
  .pc-body { grid-template-columns: 1fr; }
  .pc-controls { gap: 22px; }
}

/* ============================================================================
   15 · Step clock  (/no/bytte)
   A rail of time-stamped steps that ends.

   The end marker is a different shape from the steps on purpose. Both pages
   that want this device are arguing that something FINISHES, and a last row
   drawn like all the others reads as a list that was truncated.

   The connector hairline runs between steps and stops before the end marker,
   so the eye arrives at the full stop rather than falling past it.
============================================================================ */
.sc-rail {
  list-style: none;
  margin: clamp(32px, 4vw, 48px) 0 0;
  padding: 0;
}
.sc-step {
  display: grid;
  grid-template-columns: minmax(120px, 160px) minmax(0, 1fr);
  gap: clamp(16px, 3vw, 36px);
  position: relative;
  padding: 0 0 clamp(24px, 3vw, 34px) 0;
}
/* The connector, hung off the boundary between the two columns. */
.sc-step::before {
  content: "";
  position: absolute;
  left: clamp(120px, 14vw, 160px);
  top: 9px;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
  transform: translateX(-1px);
}
.sc-step:last-child::before { bottom: 12px; }

.sc-when { text-align: right; padding-right: clamp(16px, 3vw, 36px); position: relative; }
/* The dot sits on the connector, not beside it. */
.sc-when::after {
  content: "";
  position: absolute;
  right: -4px;
  top: 5px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bg);
  border: 1.5px solid var(--ink);
  transform: translateX(50%);
}
.sc-time {
  display: block;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
}
.sc-who {
  display: inline-block;
  margin-top: 7px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
.sc-label { margin: 0; font-size: clamp(17px, 2.1vw, 21px); line-height: 1.35; color: var(--ink); }
.sc-detail { margin: 8px 0 0; font-size: 15px; line-height: 1.6; color: var(--ink-3); max-width: 54ch; }

/* The full stop. Offset into the content column and given the ink surface, so
   it terminates the rail instead of continuing it. */
.sc-end {
  margin-left: clamp(120px, 14vw, 160px);
  padding: clamp(18px, 2.6vw, 24px) clamp(20px, 3vw, 28px);
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  max-width: 46ch;
}
.sc-end-label { margin: 0; font-size: clamp(18px, 2.3vw, 23px); line-height: 1.3; }
.sc-end-detail { margin: 8px 0 0; font-size: 14.5px; line-height: 1.6; color: rgba(255, 255, 255, 0.72); }

@media (max-width: 700px) {
  .sc-step { grid-template-columns: 1fr; gap: 8px; padding-bottom: 26px; }
  .sc-step::before { left: 0; top: 24px; }
  .sc-when { text-align: left; padding-right: 0; display: flex; align-items: center; gap: 10px; }
  .sc-when::after { display: none; }
  .sc-what { padding-left: 18px; }
  .sc-end { margin-left: 0; }
}

/* ============================================================================
   16 · Carry over  (/no/bytte and its children)
   What comes across, and what stays behind.

   Both columns are drawn at the same weight. The instinct is to dim the losses
   so the gains look better, and that is exactly what would cost the block its
   job: a reader who has moved a system before is looking for the second column
   first, and finding it greyed out tells them it is not meant to be read.
============================================================================ */
.co-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  margin-top: clamp(32px, 4vw, 48px);
}
.co-col h3 {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin: 0 0 6px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-strong);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}
.co-col h3 span {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--ink-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
/* Both modifiers exist and are deliberately identical. They are here so that
   the next person to open this file finds the decision written down rather than
   discovering two unstyled class names and "fixing" them: dimming the losses
   column is the obvious change to make, and it is the one change that would
   break the block. If a difference is ever needed, it belongs in the mark, not
   in the type or the opacity. */
.co-col--in,
.co-col--out { /* intentionally the same weight */ }

.co-col ul { list-style: none; margin: 0; padding: 0; }
.co-col li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line-2);
}
.co-col li:last-child { border-bottom: 0; }
.co-text b { display: block; font-weight: 500; font-size: 15.5px; line-height: 1.4; color: var(--ink); }
.co-text em { display: block; font-style: normal; font-size: 13.5px; line-height: 1.5; color: var(--ink-3); margin-top: 3px; }

/* Two marks, distinguishable without colour: an arrow that goes somewhere and
   a bar that does not. Colour is confirmation, never the only signal. */
.co-mark {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 2px;
  border-radius: 50%;
  position: relative;
}
.co-mark--in {
  background: var(--ink);
  --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.2 6.4 4.9 9.1 9.8 3.4' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* A real path, masked out of the disc, rather than two rotated borders.
   The border trick draws the two arms of a tick as the corner of a box turned
   40 degrees, so each arm is a parallelogram: the ends are cut on the diagonal
   instead of square, the short arm and the long arm meet at a notch rather than
   a point, and at 17px on a 2x screen the whole thing lands off the pixel grid
   and goes soft. Nobody can say what is wrong with it, everybody can see that
   something is. This is the same tick as a stroked path with round caps and a
   mitred join, so it is symmetrical at any size and stays crisp.
   Masked, not filled, so the arms keep taking their colour from the disc
   behind them and the two marks still agree in a forced-colours mode. */
.co-mark--in::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--bg-raised);
  -webkit-mask: var(--tick) center / 9px 9px no-repeat;
  mask: var(--tick) center / 9px 9px no-repeat;
}
.co-mark--out { border: 1.5px solid var(--line-strong); background: var(--bg-raised); }
.co-mark--out::after {
  content: "";
  position: absolute;
  left: 3.5px; top: 6.2px;
  width: 7px; height: 1.5px;
  background: var(--ink-4);
}

@media (max-width: 720px) {
  .co-cols { grid-template-columns: 1fr; gap: 30px; }
}

/* The selected plan's own caveat, sitting with the plan name rather than in the
   footnotes: on some ladders the cheapest plan cannot do the job the reader
   came for, and that has to be readable at the same moment as the price. */
.pc-card-caveat {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-3);
}

/* ── Versus ledger (the comparison pages) ─────────────────────────────────
   Three lists and a verdict. Structurally the same two-column device as
   .co-cols above, and for the same reason: the admission column has to read at
   exactly the weight of the boast column or the boast stops being believed.

   So .vl-col--us and .vl-col--them are deliberately identical, the same way
   .co-col--in and .co-col--out are, and the note there applies here word for
   word. Dimming theirs is the obvious tidy-up and it is the one change that
   breaks the block. If a difference is ever wanted it goes in the mark.

   The marks are distinguishable without colour, again as above: ours is a
   filled disc, theirs is a ring. Somebody reading this in greyscale, or with a
   colour vision deficiency, still gets both facts. */
.vl-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  margin-top: clamp(32px, 4vw, 48px);
}
.vl-col h3,
.vl-both h3 {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin: 0 0 6px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-strong);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}
.vl-col h3 span,
.vl-both h3 span {
  flex: none;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--ink-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
/* Both modifiers exist and are intentionally the same weight. See the comment
   at the top of this section before changing either. */
.vl-col--us,
.vl-col--them { /* intentionally the same weight */ }

.vl-col ul { list-style: none; margin: 0; padding: 0; }
.vl-col li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line-2);
}
.vl-col li:last-child { border-bottom: 0; }
.vl-text b { display: block; font-weight: 500; font-size: 15.5px; line-height: 1.4; color: var(--ink); }
.vl-text em { display: block; font-style: normal; font-size: 13.5px; line-height: 1.5; color: var(--ink-3); margin-top: 3px; }

.vl-mark {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 2px;
  border-radius: 50%;
  position: relative;
}
.vl-mark--us { background: var(--ink); }
.vl-mark--them { border: 1.5px solid var(--ink-4); }

/* The parity list is one row of small print rather than a third column: these
   are the things nobody wins on, so giving them a column of their own would
   claim a third of the page for a draw. Full width, two-up, quieter type. */
.vl-both {
  margin-top: clamp(32px, 4vw, 48px);
  padding-top: clamp(24px, 3vw, 32px);
  border-top: 1px solid var(--line-2);
}
.vl-both ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 4px clamp(20px, 3vw, 40px);
}
.vl-both li { padding: 11px 0; border-bottom: 1px solid var(--line-2); }
.vl-both li b { display: block; font-weight: 500; font-size: 14.5px; line-height: 1.4; color: var(--ink-2); }
.vl-both li em { display: block; font-style: normal; font-size: 13px; line-height: 1.5; color: var(--ink-4); margin-top: 3px; }

/* The verdict. Boxed and last, because it is the one paragraph on the page
   that argues against the page, and burying it in body copy is the same as
   deleting it. */
.vl-verdict {
  margin-top: clamp(32px, 4vw, 48px);
  padding: clamp(22px, 3vw, 30px);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-sunken);
}
.vl-verdict h3 {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.vl-verdict p {
  margin: 0;
  font-size: clamp(16px, 1.6vw, 18.5px);
  line-height: 1.55;
  color: var(--ink);
  max-width: 62ch;
}

.vl-src a { color: var(--ink-3); text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 720px) {
  .vl-cols { grid-template-columns: 1fr; gap: 30px; }
}

/* ── Skill brief (the comparison pages' lead argument) ────────────────────
   A table of quotations. The quote is the evidence the page rests on, so it is
   set in the mono face at reading size rather than shrunk into a caption, and
   the consequence sits beside it in plain type. Two voices, deliberately: one
   is the machine being briefed, the other is us explaining why.

   Mono for the quote is not decoration. It marks the text as something copied
   out of a system rather than written for the page, which is exactly the claim
   being made about it. */
.sb-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px clamp(16px, 3vw, 28px);
  margin-top: clamp(24px, 3vw, 36px);
}
.sb-chips { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; }
.sb-chips li {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 10px;
  background: var(--bg-raised);
}
.sb-addr { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0; }
.sb-addr span {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.sb-addr code {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--ink-2);
  background: var(--bg-sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  /* An address is one token. Wrapping it mid-path makes it unreadable and
     uncopyable, so it scrolls on a narrow screen instead. */
  overflow-x: auto;
  white-space: nowrap;
  max-width: 100%;
}

.sb-rows { margin-top: clamp(28px, 4vw, 44px); border-top: 1px solid var(--line-strong); }
.sb-head,
.sb-row {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 44px);
}
.sb-head {
  padding: 12px 0;
  border-bottom: 1px solid var(--line-2);
}
.sb-head span {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.sb-row {
  padding: clamp(18px, 2.5vw, 26px) 0;
  border-bottom: 1px solid var(--line-2);
  align-items: start;
}
.sb-row:last-child { border-bottom: 0; }

.sb-tag {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.sb-quote blockquote {
  margin: 0;
  font-family: var(--mono);
  font-size: clamp(13px, 1.35vw, 14.5px);
  line-height: 1.65;
  color: var(--ink);
  padding-left: 14px;
  border-left: 2px solid var(--ink-4);
}
/* Drawn, so an editor never types them and they cannot end up doubled. */
.sb-quote blockquote::before { content: "\201C"; }
.sb-quote blockquote::after { content: "\201D"; }

.sb-prevents p {
  margin: 0;
  font-size: clamp(14.5px, 1.5vw, 16px);
  line-height: 1.55;
  color: var(--ink-2);
}

.sb-foot {
  margin: clamp(24px, 3vw, 34px) 0 0;
  font-size: clamp(15px, 1.6vw, 17px);
  line-height: 1.6;
  color: var(--ink);
  max-width: 66ch;
}

@media (max-width: 720px) {
  /* The column headings only make sense over two columns. Stacked, each row
     labels itself with the skill tag, so the header would be a lie. */
  .sb-head { display: none; }
  .sb-row { grid-template-columns: 1fr; gap: 14px; }
  .sb-prevents p { color: var(--ink-3); }
}

/* ── Compare index (/compare) ─────────────────────────────────────
   A card is a "SoftSync vs" line and a name. Nothing else.

   The version before this carried the thesis, the figure, the figure's unit
   and the concession on every card: five text elements times twelve cards, on
   a page whose whole job is to let a reader find their own vendor and click
   it. It read as messy because it was, and it was competing with the twelve
   pages it exists to send you to.

   Card look is still `.trust-card` from landing.css, down to the padding, the
   radius and the shadow, so a reader arriving from /european or /no/norsk
   meets a card they have seen. Four across rather than that grid's three:
   the card is a name now, and three columns of one short line each left the
   cards wider than their content by a long way. If the card look changes in
   landing.css, change it here in the same commit.

   The departure is the name, set large as a wordmark instead of a 17px
   heading, because this grid stands in for the logo wall a reader expects on
   a compare hub: twelve vendors, four usable logo files between them, and two
   of the gaps at HubSpot and Microsoft. See CompareIndex.astro for the whole
   argument, including why this is Inter rather than the display serif. */
.ci-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(14px, 1.6vw, 20px);
  margin: clamp(28px, 4vw, 44px) 0 0;
  padding: 0;
  list-style: none;
}
/* Used headless on /compare, where the page hero already says what the list
   is. With no heading above it the grid is the first thing in the wrap, and
   its top margin would double the section padding. */
.ci-grid:first-child { margin-top: 0; }
.ci-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(20px, 2.2vw, 28px);
  box-shadow: var(--shadow-sm);
}

/* Every card the same. There was a per-card accent here, four house tones
   grouping the twelve by kind, and it went because a reader does not see a
   grouping, they see that some labels are orange and some are not and wonder
   what they did differently. Twelve identical labels ask no question. The
   grouping it encoded is still in the footer, in words.

   Not .eyebrow: that class is 11.5px uppercase with wide tracking, which at
   card size and twelve repeats turns the grid into a wall of small capitals.
   Sentence case reads as the first half of the name below it. */
.ci-vs {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink);
}

/* The wordmark. Inter at 600 with tracking pulled in hard, which is what
   nearly every real wordmark is: a geometric sans, tight, one weight up from
   body. The first version of this was the display serif, on the grounds that
   `.logo--ph` in landing.css already sets a name that way. Wrong twice over.
   `.logo--ph` is 22px in a scrolling marquee, where it reads as a caption,
   and a display serif is a heading face: at 30px in a card it does not read
   as a mark, it reads as a heading that wandered in.

   `text-wrap: balance` matters more here than it looks: "Microsoft Dynamics
   365" and "Building it yourself" are three words at 30px in a four-up grid,
   and the default break leaves one orphan word on its own line.

   Two lines are reserved whether or not a name needs them, so all twelve
   boxes are the height of the Microsoft one. Grid items already stretch to
   match their own row, which is why this was not obvious: the first two rows
   were equal to each other and the third was taller, and one taller row at
   the bottom reads as a mistake rather than as a size. */
.ci-mark {
  margin: 5px 0 0;
  min-height: 2.3em;
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.035em;
  color: var(--ink);
  text-wrap: balance;
}
.ci-mark a { color: inherit; text-decoration: none; }
/* Stretched over the card so the whole thing is the target, without wrapping
   block content in an anchor. */
.ci-mark a::after { content: ""; position: absolute; inset: 0; }
/* Hover moves the whole surface rather than animating an ornament. The card
   is two lines of text, so the only honest affordance is the box itself. */
.ci-card:has(a:hover) { background: var(--bg-hover); border-color: var(--line-strong); }
.ci-card:has(a:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }

/* The pledge is a note, not a panel. It earns its place by being true rather
   than by being boxed, and a bordered block here competed with the cards. */
.ci-pledge { margin: clamp(28px, 3.4vw, 40px) 0 0; max-width: 64ch; }
.ci-pledge p { margin: 8px 0 0; font-size: 13.5px; line-height: 1.55; color: var(--ink-4); }
.ci-pledge .eyebrow { margin: 0; }

@media (prefers-reduced-motion: no-preference) {
  .ci-card { transition: background .2s var(--ease), border-color .2s var(--ease); }
}

@media (max-width: 1080px) {
  .ci-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 880px) {
  .ci-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
  .ci-grid { grid-template-columns: 1fr; }
  /* A full-width card fits the longest name on one line, so the reserved
     second line would be dead space under all twelve. */
  .ci-mark { min-height: 0; }
}

/* ── Object cap (/attio-alternative) ─────────────────────────────────────
   Rows of chips with one line drawn across all of them at the same position.
   The line is the block: three rows cut in the same place is what shows the
   ceiling belongs to the plan rather than to the example.

   Chips are the .trust-card .state pill recipe from landing.css, borrowed
   whole so this looks like the rest of the site rather than like a chart
   somebody dropped in. The overflow chips are the same pill with a dashed
   border and the ink dropped one step: legible, clearly outside, not hidden.
   Greying them to nothing would delete the argument.

   The line itself is an ::after on the capAt-th chip rather than an absolutely
   positioned overlay, so it survives the chips wrapping to a second row on a
   narrow screen. An overlay would sit in the wrong place the moment anything
   reflowed. */
.oc-chart { margin-top: clamp(28px, 4vw, 44px); }

.oc-cap-label { margin: 0 0 14px; }
.oc-cap-label span {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 4px 11px;
}

.oc-rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-strong); }
.oc-row { padding: clamp(16px, 2.2vw, 24px) 0; border-bottom: 1px solid var(--line-2); }
.oc-row:last-child { border-bottom: 0; }

.oc-trade {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.oc-trade span {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.oc-chips { list-style: none; display: flex; flex-wrap: wrap; gap: 7px; margin: 0; padding: 0; }
.oc-chip {
  position: relative;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-2);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 11px;
}
.oc-chip--over {
  color: var(--ink-4);
  background: transparent;
  border-style: dashed;
}

/* The cap, drawn off the last chip that fits. Sits in the gap, so it reads as
   a divider between chips rather than a strike through one of them. */
.oc-line {
  position: absolute;
  top: -5px;
  bottom: -5px;
  right: -4px;
  width: 2px;
  background: var(--ink);
  border-radius: 2px;
}

.oc-over-label {
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-4);
}

.oc-ours {
  margin: clamp(24px, 3vw, 34px) 0 0;
  max-width: 62ch;
  font-size: clamp(16px, 1.7vw, 18.5px);
  line-height: 1.55;
  color: var(--ink);
}

@media (max-width: 520px) {
  /* At this width every row wraps, and a 2px rule inside a wrapped group of
     chips reads as a mistake rather than a cap. The dashed chips still carry
     the distinction, and the count beside the trade still carries the number. */
  .oc-line { display: none; }
}

/* yesAnswers sets its own measure rather than using .mag-head, so its lead
   never inherited the 20px every other block's lead gets and sat flush under
   the heading. Same values as .mag-head p.lead, applied where they are needed
   rather than by widening the block's scope. */
.yes-lead {
  margin: 20px 0 0;
  max-width: 62ch;
  font-size: clamp(16px, 1.7vw, 18.5px);
  line-height: 1.6;
  color: var(--ink-2);
}

/* timeLite sets its own measure like yesAnswers does, so its lead needs the
   same 20px the .mag-head blocks get for free. Same values as .yes-lead. */
.tl-lead {
  margin: 20px 0 0;
  max-width: 62ch;
  font-size: clamp(16px, 1.7vw, 18.5px);
  line-height: 1.6;
  color: var(--ink-2);
}
