/* The developer side of Pricemend.
   Deliberately not the consumer app's paper-and-gilt look: someone landing here is evaluating a
   data source, not shopping, and the two propositions should not be mistaken for each other. Same
   ink and same serif for the headings so it is recognisably the same company, but flat, quiet and
   dense where the app is warm and spacious. */

:root {
  --ink: #16120e;
  --ink-soft: #55493d;
  --ink-faint: #8a7c6c;
  --paper: #fbf9f5;
  --panel: #f3efe7;
  --rule: #ded5c6;
  /* One accent, and only one. Green marks everything a reader can act on: links, the active
     tab, the primary button. Nothing else on the page is allowed to compete for the eye, which
     is why the gilt below is no longer an interactive colour. */
  --accent: #36553f;
  --accent-soft: #e7eee9;
  --accent-deep: #2b4433;
  /* Kept for the hero over the painting, where it is part of the picture rather than a signal,
     and for the one amber state the dashboard needs. Never used for a link or a button. */
  --gilt: #8f6b26;
  --code-bg: #1e1a16;
  --code-ink: #ece3d4;
  --display: "IM Fell English", "Iowan Old Style", Georgia, serif;
  --text: "Spline Sans", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

@font-face { font-family: "IM Fell English"; src: url("fonts/im-fell-english-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Spline Sans"; src: url("fonts/spline-sans-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Spline Sans"; src: url("fonts/spline-sans-latin-500-normal.woff2") format("woff2"); font-weight: 500; font-display: swap; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--paper); color: var(--ink);
  font: 400 17px/1.6 var(--text); letter-spacing: 0.1px;
}

/* ---- chrome */
.top {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 14px 20px; border-bottom: 1px solid var(--rule); background: var(--paper);
  position: sticky; top: 0; z-index: 10;
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); }
.brand img { border-radius: 7px; }
.brand span { font: 400 19px/1 var(--display); }
.brand b { font-weight: 400; color: var(--ink-faint); }
.top nav { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.top nav a { color: var(--ink-soft); text-decoration: none; font-size: 15px; }
.top nav a:hover { color: var(--ink); text-decoration: underline; }
.top nav a.ghost { color: var(--ink-faint); border-left: 1px solid var(--rule); padding-left: 18px; }
/* The one nav item that survives on a phone, so it is the one that has to be an action. */
.top nav a.key {
  background: var(--accent); color: #fff; border-radius: 7px; padding: 7px 14px;
}
.top nav a.key:hover { background: var(--accent-deep); color: #fff; text-decoration: none; }

main { max-width: 760px; margin: 0 auto; padding: 0 20px 64px; }
section { padding: 38px 0; border-bottom: 1px solid var(--rule); }
/* The header is sticky, so an anchor link lands its heading underneath it without this. */
section[id], [id] > h2 { scroll-margin-top: 76px; }
section:last-of-type { border-bottom: 0; }

h1 { font: 400 clamp(30px, 6vw, 42px)/1.15 var(--display); margin: 0 0 14px; letter-spacing: -0.2px; }
h2 { font: 400 clamp(22px, 4vw, 27px)/1.25 var(--display); margin: 0 0 12px; }
h3 { font: 500 17px/1.4 var(--text); margin: 24px 0 6px; }
p { margin: 0 0 14px; }
a { color: var(--accent); }
.lede { font-size: 19px; color: var(--ink-soft); }
.note { font-size: 15px; color: var(--ink-faint); }
.fine { font-size: 13px; color: var(--ink-faint); }

/* ---- hero */

.cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }

.btn {
  display: inline-block; padding: 11px 18px; border-radius: 9px; text-decoration: none;
  border: 1px solid var(--rule); color: var(--ink); background: var(--paper); font-size: 15px;
}
.btn:hover { background: var(--panel); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #f6f2e9; }
.btn.primary:hover { filter: brightness(1.12); }

/* ---- code */
pre {
  background: var(--code-bg); color: var(--code-ink); border-radius: 11px; padding: 16px 18px;
  overflow-x: auto; font: 400 13.5px/1.6 var(--mono); margin: 0 0 14px;
}
code { font-family: var(--mono); font-size: 0.92em; }
p code, li code, td code { background: var(--panel); border: 1px solid var(--rule); border-radius: 5px; padding: 1px 5px; }

/* ---- tables */
table { width: 100%; border-collapse: collapse; margin: 6px 0 14px; font-size: 15.5px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--rule); vertical-align: top; }
th { font-weight: 500; color: var(--ink-soft); background: var(--panel); }
td:first-child { white-space: nowrap; }

/* ---- the comparison matrix
   Six columns will not sit inside a 760px reading measure, so this one table is allowed out of
   the column and runs to 1060px. Below 860px it stops being a matrix at all and becomes one card
   per option, because a horizontally scrolling table on a phone hides the half you came for. */
.compare {
  position: relative; left: 50%;
  width: min(1060px, calc(100vw - 40px));
  margin: 18px 0 18px calc(min(1060px, 100vw - 40px) / -2);
  table-layout: fixed; font-size: 14.5px; line-height: 1.45;
}
.compare th:first-child { width: 19%; }
.compare th, .compare td { padding: 13px 14px; }
.compare thead th {
  background: transparent; color: var(--ink-faint);
  font: 500 13px/1.3 var(--text); border-bottom: 1px solid var(--ink-faint);
}
.compare tbody th { background: transparent; color: var(--ink); font-size: 15px; }
.compare .eg { display: block; margin-top: 3px; font-size: 12.5px; color: var(--ink-faint); }
.compare tbody tr.us { background: var(--accent-soft); }
.compare tbody tr.us th { color: var(--accent-deep); }
.compare .yes { color: var(--accent-deep); font-weight: 500; }
.compare .no { color: var(--ink-faint); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }

@media (max-width: 860px) {
  .compare, .compare tbody, .compare tr, .compare th, .compare td { display: block; width: auto; }
  .compare { position: static; left: auto; margin: 18px 0 20px; table-layout: auto; }
  .compare th:first-child { width: auto; }
  .compare thead { display: none; }
  .compare tr {
    border: 1px solid var(--rule); border-radius: 10px; margin-bottom: 14px; padding-bottom: 8px;
  }
  .compare tbody tr.us { border-color: #bcd0c2; }
  .compare tbody th {
    font-size: 17px; padding: 13px 16px 10px; border-bottom: 1px solid var(--rule);
  }
  .compare td {
    border-bottom: 0; padding: 8px 16px;
    display: flex; gap: 16px; align-items: baseline;
  }
  .compare td::before {
    content: attr(data-label); flex: 0 0 38%;
    color: var(--ink-faint); font-size: 13px; line-height: 1.35;
  }
  /* The value is one flex item, not two. Without the span the bold "Yes" and the text after it
     become separate items and the gap opens up in the middle of the sentence. */
  .compare .v { flex: 1 1 auto; text-align: right; }
}

ul.plain { padding-left: 20px; margin: 0; }
ul.plain li { margin-bottom: 10px; }

/* ---- pricing */
/* Three plans across, then the dataset licence as a full-width strip beneath them. It is not a
   fourth tier: it is a contract rather than a subscription, and auto-fit left it stranded in a
   row of its own looking like a bug. */
.tiers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 18px 0; }
/* The base .tier is a column flexbox whose <ul> has flex:1 so the buttons line up across the
   three plans. Both have to be undone here, or the row inherits the column direction and the
   list stretches the card to the height of a plan card with nothing in it. */
.tier:nth-child(4) {
  grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; align-items: center;
  gap: 8px 22px; padding: 16px 18px;
}
.tier:nth-child(4) h3,
.tier:nth-child(4) .price { white-space: nowrap; margin: 0; }
.tier:nth-child(4) .price { font-size: 19px; color: var(--ink-soft); }
.tier:nth-child(4) ul {
  display: flex; flex-wrap: wrap; gap: 0 20px; margin: 0; flex: 1 1 auto; font-size: 14px;
}
.tier:nth-child(4) li { padding: 2px 0 2px 14px; }
.tier:nth-child(4) .btn { margin: 0 0 0 auto; }
@media (max-width: 760px) {
  .tiers { grid-template-columns: 1fr; }
  .tier:nth-child(4) { flex-direction: column; align-items: stretch; }
  .tier:nth-child(4) .btn { margin: 4px 0 0; }
}
.tier {
  border: 1px solid var(--rule); border-radius: 12px; padding: 16px; background: var(--paper);
  display: flex; flex-direction: column;
}
.tier.featured { border-color: var(--accent); background: var(--accent-soft); }
.tier h3 { margin: 0; font: 400 19px/1.2 var(--display); }
.tier .price { font: 400 29px/1.1 var(--display); margin: 6px 0 12px; }
.tier .price span { font: 400 14px/1 var(--text); color: var(--ink-faint); }
.tier ul { list-style: none; padding: 0; margin: 0 0 16px; font-size: 14.5px; color: var(--ink-soft); flex: 1; }
.tier li { padding: 5px 0 5px 18px; position: relative; }
.tier li::before { content: "·"; position: absolute; left: 6px; color: var(--ink-faint); font-weight: 700; }
.tier .btn { text-align: center; }

.end { text-align: center; }
.end .btn { margin-top: 6px; }

/* ---- retailer pages */
blockquote {
  margin: 0 0 12px; padding: 14px 18px; background: var(--panel);
  border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
}
blockquote p { margin: 0; font-style: italic; color: var(--ink-soft); }

ul.plain { margin: 0 0 14px; padding-left: 20px; color: var(--ink-soft); font-size: 15.5px; }
ul.plain li { padding: 2px 0; }

/* Three or four columns of names, so 122 US retailers is a page you can scan rather than scroll. */
ul.retailers {
  list-style: none; padding: 0; margin: 14px 0 0;
  columns: 3 170px; column-gap: 24px; font-size: 15.5px;
}
ul.retailers li { padding: 4px 0; break-inside: avoid; }
ul.retailers a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--rule); }
ul.retailers a:hover { border-bottom-color: var(--accent); color: var(--accent); }
.days { font-size: 12.5px; color: var(--ink-faint); margin-left: 4px; }
/* Not yet read. Greyed rather than hidden: a reader checking whether their shop is in the corpus
   should find it, and find out plainly that the number hasn't been confirmed. These sort below
   the retailers that have been read, so the usable half of each list reads as one block. */
.soon { color: var(--ink-faint); }
.soon-tag {
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-faint); border: 1px solid var(--rule); border-radius: 999px;
  padding: 1px 7px; margin-left: 6px; white-space: nowrap;
}

footer {
  border-top: 1px solid var(--rule); padding: 22px 20px 40px; text-align: center;
  color: var(--ink-faint); font-size: 14px;
}
footer a { color: var(--ink-soft); }

/* ---- phones
   The desktop rhythm was carried straight down to 390px, where it reads as one dense block: a
   header with two crowded rows, a headline filling the width, and every element touching the
   next. Everything below buys back vertical space and makes the tap targets real. */
@media (max-width: 560px) {
  body { font-size: 16px; line-height: 1.65; }
  main { padding: 0 20px 48px; }
  section { padding: 34px 0; }
  h1 { font-size: 30px; line-height: 1.18; margin-bottom: 18px; }
  h2 { font-size: 23px; margin-bottom: 14px; }
  h3 { margin-top: 26px; }
  p { margin-bottom: 16px; }
  .lede { font-size: 17.5px; line-height: 1.6; }

  /* Five links wrapped to a second row, and because the header is sticky those two rows were
     230px of a 844px screen gone on every scroll, forever. A phone header gets one row: the
     brand and the one thing a reader can do. The rest of the links are in the footer. */
  .top { padding: 9px 16px; gap: 10px; flex-wrap: nowrap; }
  .top nav { gap: 0; width: auto; flex-wrap: nowrap; }
  .top nav a { display: none; }
  .top nav a.key { display: inline-block; font-size: 14.5px; padding: 8px 14px; }
  .brand span { font-size: 18px; }

  /* 48px of height is the smallest comfortable target, and full width stops two buttons
     fighting for one line. */
  .btn { display: block; width: 100%; text-align: center; padding: 14px 18px; }
  .cta { gap: 12px; }

  /* A phone is 46 monospace characters wide at this size. Anything wider scrolls sideways,
     which on a touch screen means the reader never finds it. */
  pre { font-size: 12.5px; padding: 14px 14px; border-radius: 10px; }

  /* Two columns inside 350px gave the definitions four words a line and eight rows of it. A
     phone reads a term-and-definition table down the page, not across it. .compare has its own
     treatment at a wider breakpoint and is left alone. */
  table:not(.compare), table:not(.compare) tbody,
  table:not(.compare) tr, table:not(.compare) td { display: block; width: auto; }
  table:not(.compare) thead { display: none; }
  table:not(.compare) tr { padding: 14px 0; border-bottom: 1px solid var(--rule); }
  table:not(.compare) tr:last-child { border-bottom: 0; }
  table:not(.compare) td { border-bottom: 0; padding: 0 0 5px; }
  table:not(.compare) td:first-child { white-space: normal; font-weight: 500; }
  table:not(.compare) td:last-child { padding-bottom: 0; color: var(--ink-soft); }
}

/* The consumer app follows the system theme; this page is a document and stays light, so a dark
   system setting doesn't produce a half-inverted page nobody checked. */
@media (prefers-color-scheme: dark) {
  :root { color-scheme: light; }
}


/* ======================================================================
   Home page: the split hero
   The claim on the left, an actual response body on the right. A developer
   deciding whether this solves their problem wants to read JSON, not prose
   about JSON, so the payload is the hero image as much as the painting is.

   --plate is the painting, set in one place so it can be swapped without
   hunting through the file. Rembrandt, "The Parable of the Rich Fool" (1627),
   also called "The Money Changer"; public domain. A man checking a coin by
   candlelight against the paperwork piled around him, which is the product.
   The canvas is already almost black at the edges, so the wash over it is
   light: the job here is to protect the text, not to darken a dark painting.
   ====================================================================== */
:root { --plate: url("img/richfool.jpg"); --plate-pos: 50% 34%; }

body.home .hero {
  position: relative; isolation: isolate;
  margin: 0 calc(50% - 50vw); padding: 48px 32px 38px;
  border-bottom: 1px solid var(--rule);
}
body.home .hero::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  background: var(--plate) var(--plate-pos) / cover no-repeat;
}
/* Warm wash rather than neutral black: the painting's own browns carry through it, and the
   bottom edge lands exactly on the paper the rest of the page is printed on. */
body.home .hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(98deg,
      rgba(12,9,5,.93) 0%, rgba(12,9,5,.88) 20%, rgba(12,9,5,.42) 34%,
      rgba(12,9,5,.04) 48%, rgba(12,9,5,.04) 60%,
      rgba(12,9,5,.38) 72%, rgba(12,9,5,.58) 88%, rgba(12,9,5,.62) 100%),
    linear-gradient(180deg, rgba(12,9,5,.34) 0%, rgba(12,9,5,0) 24%, rgba(12,9,5,.20) 74%, var(--paper) 100%);
}

.hero-grid {
  display: grid; grid-template-columns: minmax(0, 390px) minmax(0, 430px);
  justify-content: space-between; gap: 40px; align-items: start;
  max-width: 1280px; margin: 0 auto;
}
.hero-say { max-width: 32ch; }
.audience { max-width: 1280px; margin: 34px auto 0; }

body.home .hero h1 {
  font-size: clamp(32px, 4.4vw, 46px); line-height: 1.08; color: #fdf8ee;
  margin: 0 0 16px; text-shadow: 0 2px 20px rgba(14,9,5,.55);
}
body.home .hero .lede { color: #ded2bd; font-size: 18px; max-width: 42ch; }
body.home .hero .note { color: #b9ab93; max-width: 44ch; }
body.home .hero .note a { color: #a8c7b2; }

/* Counts as a line of prose, not a row of stat tiles. They are supporting evidence for the
   sentence above them, and sized accordingly. */
.hero .facts {
  list-style: none; display: flex; flex-wrap: wrap; gap: 0 22px;
  margin: 22px 0 14px; padding: 0; font-size: 15px;
}
.hero .facts li + li { position: relative; }
.hero .facts li + li::before {
  content: ""; position: absolute; left: -12px; top: 50%; width: 1px; height: 13px;
  margin-top: -6px; background: rgba(246,239,226,.26);
}
.hero .facts a { color: #cfc2ab; text-decoration: none; }
.hero .facts a:hover { color: #fdf8ee; }
.hero .facts b { color: #fdf8ee; font-weight: 500; font-size: 17px; }

body.home .hero .cta { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 0; }
body.home .hero .btn {
  border-color: rgba(246,239,226,.38); color: #f6efe2; background: rgba(18,12,7,.34);
  backdrop-filter: blur(2px);
}
body.home .hero .btn:hover { border-color: #f6efe2; background: rgba(18,12,7,.5); }
body.home .hero .btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
body.home .hero .btn.primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); }

/* ---- the response card */
.demo {
  background: rgba(18,14,10,.86); border: 1px solid rgba(246,239,226,.16); border-radius: 10px;
  overflow: hidden; box-shadow: 0 18px 50px rgba(12,8,4,.45); backdrop-filter: blur(3px);
}
.demo-tabs { display: flex; border-bottom: 1px solid rgba(246,239,226,.14); }
.demo-tabs button {
  flex: 1; appearance: none; background: none; border: 0; cursor: pointer;
  padding: 11px 8px; font: 400 14px/1 var(--text); color: #a99a84;
  border-bottom: 2px solid transparent;
}
.demo-tabs button:hover { color: #ded2bd; }
.demo-tabs button[aria-selected="true"] { color: #fdf8ee; border-bottom-color: var(--accent); }
.demo-tabs button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.demo-body { padding: 14px 16px 16px; }
.demo .req {
  margin: 0 0 10px; font: 400 12.5px/1.6 var(--mono); color: #9d8f7a;
}
.demo .req br + * , .demo .req { white-space: normal; }
.demo .req span {
  color: #cdbf9a; border: 1px solid rgba(205,191,154,.4); border-radius: 3px;
  padding: 0 5px; margin-right: 7px;
}
.demo pre {
  margin: 0; background: none; padding: 0; overflow-x: auto;
  font: 400 13px/1.65 var(--mono); color: var(--code-ink);
}
.demo code { background: none; padding: 0; color: inherit; }

/* ---- the two-audiences line */
.audience {
  margin: 30px 0 0; font-size: 14px; color: #a2937d;
  display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
}
.audience span, .audience a {
  border: 1px solid rgba(246,239,226,.2); border-radius: 999px; padding: 5px 13px;
}
.audience span { color: #e6dac4; background: rgba(246,239,226,.09); }
.audience a { color: #c2b49c; text-decoration: none; }
.audience a:hover { color: #fdf8ee; border-color: rgba(246,239,226,.5); }

/* Below this the two columns would squeeze the face out anyway, so the painting goes back to
   being a backdrop and the content stacks over it. */
@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; gap: 28px; max-width: 640px; }
  .hero-say { max-width: none; }
  body.home .hero { padding-top: 36px; }
  body.home .hero::after {
    background:
      linear-gradient(180deg, rgba(14,10,6,.55) 0%, rgba(14,10,6,.80) 42%, rgba(14,10,6,.90) 78%, var(--paper) 100%);
  }
}
@media (max-width: 560px) {
  .demo pre { font-size: 12px; }
  .demo-body { padding: 14px 14px 18px; }
  .demo-tabs button { padding: 14px 6px; }

  /* On a wide screen the painting sits behind a single column of text and there is room for
     both. On a 390px phone the hero is 1300px of text over the same canvas, so the painting
     became a dark smear nobody could read as a painting and the text sat on top of the face.
     Give it its own band instead: a crisp strip at the top, cropped to the man and the candle,
     then flat dark panel underneath where the words go. The picture is finally visible and the
     text is finally legible, which the overlap achieved for neither. */
  body.home .hero { padding: 214px 20px 40px; background: #0e0a06; }
  body.home .hero::before { inset: 0 0 auto 0; height: 190px; background-position: 50% 0; }
  body.home .hero::after {
    inset: auto 0 0 0; height: calc(100% - 150px);
    background: linear-gradient(180deg, rgba(14,10,6,0) 0%, #0e0a06 26px, #0e0a06 86%, var(--paper) 100%);
  }
  body.home .hero h1 { font-size: 31px; line-height: 1.16; margin-bottom: 18px; }
  body.home .hero .lede { margin-bottom: 26px; }
  body.home .hero .cta { margin: 0 0 28px; }
  /* The counts were jammed against the buttons above and the note below. They are a quiet line
     of evidence, so give them air on both sides and let them wrap without colliding. */
  .hero .facts { gap: 10px 20px; margin: 0 0 22px; }
  .hero .facts li + li::before { display: none; }
  body.home .hero .note { margin-bottom: 0; }
  .hero-grid { gap: 34px; }
  .audience { margin-top: 30px; gap: 10px; }
}
/* The painting is decoration. Anyone asking for more contrast gets the flat panel the rest of
   the page already uses. */
@media (prefers-contrast: more) {
  body.home .hero::before { display: none; }
  body.home .hero::after { background: var(--code-bg); }
}
