/* Durevo — brand tokens and layout.
   Spec: docs/superpowers/specs/2026-08-15-durevo-landing-page-design.md

   Colour and type are fixed by the brand guide (2026-07-09-durevo-rebrand-
   design.md, §Colors): green #0c3a2f and gold #ffb902 are what app.json
   already paints the splash and launcher icon with, so they are what a visitor
   sees again thirty seconds later on their own phone. They do not change here.

   THE GROUND DID CHANGE. The page used to be a white marketing page with green
   blocks dropped into it — a layout language that would suit any B2B product.
   It is now dark end to end, the surface behind a till, with the content
   sitting on it as pale PAPER OBJECTS: the counter book, the shelf card. That
   is the one structural idea, and everything below serves it.

   Body stays LIGHT deliberately. The five legal pages share this stylesheet and
   carry no body class of their own; terms.html alone is 59KB of prose, and
   reversing that out on a dark ground would be a readability disaster. So the
   landing page's SECTIONS paint themselves dark, one after another with no gap,
   and a prose page simply never opts in. */

/* --- faces ------------------------------------------------------------ */
/* Three faces, three jobs: Archivo 400 for everything you READ, Archivo
   EXPANDED 700 for everything that SPEAKS, Geist Mono for amounts.

   Note there is no normal-width bold on this site. The expanded face replaced
   Archivo 700 rather than joining it, because the font budget in verify.mjs had
   ~1.6KB of headroom and these files are already latin-subset. The constraint
   turned out to improve the design: with no normal-width bold available, a bold
   run mid-sentence is simply not expressible, so emphasis has to come from the
   display face or from mono numerals. See fetch-fonts.mjs for why a variable
   font is NOT the answer here (measured: it is bigger, not smaller). */

@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo Expanded';
  src: url('/assets/fonts/archivo-expanded-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Geist Mono';
  src: url('/assets/fonts/geist-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Brand, unchanged. */
  --green: #0c3a2f;
  --gold: #ffb902;
  --gold-hover: #e5a702;
  --sage: #699b72;

  /* The counter: deeper than the brand green, so the green surface raised on
     top of it still reads as raised. */
  --counter: #071f19;
  --counter-raised: #0c3a2f;
  --rule-dark: rgba(238, 242, 239, 0.13);
  --on-dark: #eef2ef;
  --on-dark-muted: #9db3aa;

  /* Paper: the artifact cards, and the ground for the legal pages. Biased
     very slightly green rather than a pure grey — a neutral picked, not
     inherited. */
  --paper: #f2f5f1;
  --bg: #fafbf9;
  --border: #dfe4dd;
  --border-paper: #d5ded4;

  --ink: #202222;
  --ink-muted: #4a534d;

  --radius: 8px;
  --sans: 'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --display: 'Archivo Expanded', 'Archivo', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  color-scheme: light;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  margin: 0 0 0.5em;
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.08;
}
h1 {
  font-size: clamp(2.25rem, 6.2vw, 3.9rem);
  letter-spacing: -0.03em;
}
h2 {
  font-size: clamp(1.55rem, 3.6vw, 2.3rem);
  letter-spacing: -0.02em;
}
h3 {
  font-size: 1rem;
  letter-spacing: -0.005em;
}
p {
  margin: 0 0 1rem;
}

/* The brand guide reserves mono for amounts, IDs and receipts, and the app
   already follows it. Carrying that onto the site — every quantity, not just
   captions — is what makes the typography belong to this product. */
.num {
  font-family: var(--mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.wrap {
  width: min(1120px, 100% - 2.5rem);
  margin-inline: auto;
}

a {
  color: var(--green);
  text-underline-offset: 3px;
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

/* --- buttons ---------------------------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--display);
  font-size: 0.97rem;
  font-weight: 700;
  padding: 0.85rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  transition: background-color 180ms ease-out, border-color 180ms ease-out,
    transform 90ms ease-out;
}
/* Motion that answers a tap, rather than motion that plays at you. On a phone
   with no hover state this is the only feedback that the tap registered before
   the Play Store opens. */
.btn:active {
  transform: translateY(1px);
}
/* Gold is the CTA and the mark, nowhere else. Never white text on gold — the
   brand guide notes it fails contrast for anything but large bold type. */
.btn-primary {
  background: var(--gold);
  color: #201a02;
}
.btn-primary:hover {
  background: var(--gold-hover);
}
.btn-ghost {
  background: transparent;
  border-color: rgba(238, 242, 239, 0.34);
  color: var(--on-dark);
  padding: 0.62rem 1.1rem;
}
.btn-ghost:hover {
  border-color: var(--on-dark);
}

/* --- header ----------------------------------------------------------- */

.site-header {
  background: var(--counter);
  color: var(--on-dark);
}
.site-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.05rem 0;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: inherit;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -0.015em;
  text-decoration: none;
}

.site-nav {
  display: flex;
  gap: 1.6rem;
  font-size: 0.92rem;
}
.site-nav a {
  color: var(--on-dark-muted);
  text-decoration: none;
}
.site-nav a:hover {
  color: var(--on-dark);
}
@media (max-width: 52rem) {
  .site-nav {
    display: none;
  }
}

/* --- hero ------------------------------------------------------------- */
/* Two columns: the argument on the left, the counter book on the right. The
   book used to be a section halfway down the page. It is the reason a shop
   owner recognises herself in this product, so it is now the first object on
   screen rather than a reward for scrolling. */

.hero {
  background: var(--counter);
  color: var(--on-dark);
  padding: 3.25rem 0 4.5rem;
}
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 3.5rem;
  align-items: center;
}
.hero-copy {
  max-width: 34rem;
}
.hero h1 {
  margin-bottom: 1.05rem;
}
.h1-gold {
  display: block;
  color: var(--gold);
}
.lede {
  max-width: 33rem;
  margin-bottom: 0;
  font-size: clamp(1.03rem, 2vw, 1.2rem);
  color: #c4d3cc;
}
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.9rem;
}

/* --- badges ----------------------------------------------------------- */
/* Gold outline pills, taken from the Play feature graphic rather than
   invented — it is the brand's own one-line summary of the offer, and the page
   and the store listing should not describe the product differently.
   They replaced an all-caps "FOR SMALL SHOPS" eyebrow, which was decoration;
   these carry the three facts a shopkeeper actually needs before tapping. */

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin: 1.35rem 0 0;
  padding: 0;
  list-style: none;
}
.badges li {
  border: 1px solid rgba(255, 185, 2, 0.45);
  border-radius: 999px;
  padding: 0.32rem 0.85rem;
  font-size: 0.84rem;
  color: var(--gold);
}
/* The year-end promotion badge is the one long enough to wrap on a phone.
   Each half holds together, so it breaks at the dash rather than orphaning
   "November" or splitting the date from its year. */
.badges .keep {
  white-space: nowrap;
}

@media (max-width: 60rem) {
  .hero-grid {
    grid-template-columns: 1fr;
    gap: 2.75rem;
  }
}

/* --- paper ------------------------------------------------------------ */
/* There is no shared `.paper` surface any more, and its absence is the point.
   A generic pale card was what made both objects on this page look like
   tables: the same rounded rectangle whatever it was standing in for. Each
   object is now the thing it represents — a counter book, a shelf tag — and
   they no longer share anything but the paper colour. */

.paper-label {
  margin: 0 0 1rem;
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* --- the hero stage: the book, and the phone that replaces it --------- */
/* One object carrying the whole pitch. The book a shop already keeps sits at
   an angle underneath; the app sits on top of it.
 *
 * An earlier version drew the book as a plain white rounded card with rows in
 * it, and it read as a table rather than as a book — the thing it is meant to
 * be recognised as. What was missing was not colour but the marks that make an
 * exercise book an exercise book: the red margin rule down the left, a second
 * sheet under the first, and the fact that a book on a counter is never square
 * to the world. All of it is CSS and costs nothing to send. */

.hero-stage {
  position: relative;
  /* The phone alone now. The book moved to .problem-stage, and with it the
     padding that used to hold the two apart and the sheet drawn underneath. */
  max-width: 21rem;
  margin-inline: auto;
}

.counter-book {
  position: relative;
  z-index: 1;
  background: var(--paper);
  color: var(--ink);
  border-radius: 7px;
  /* The left padding clears the margin rule, the way writing in a real book
     starts to the right of it. The right padding stays wide: it began as room
     for a phone that overlapped here, and reads as a margin now the phone has
     gone. */
  padding: 1.3rem 2rem 1.15rem 2.45rem;
  font-size: 0.97rem;
  transform: rotate(-2.8deg);
  box-shadow: 0 24px 48px -26px rgba(0, 0, 0, 0.9);
}
.counter-book::before {
  content: '';
  position: absolute;
  left: 1.55rem;
  top: 0.55rem;
  bottom: 0.55rem;
  width: 1px;
  background: rgba(183, 64, 52, 0.4);
}

.hero-phone {
  position: relative;
  width: 100%;
  transform: rotate(2deg);
}
.hero-phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 15px;
  /* A dark bezel, so it reads as a phone rather than a floating rectangle. */
  border: 4px solid #0f1213;
  background: #0b0b0b;
  box-shadow: 0 28px 52px -20px rgba(0, 0, 0, 0.95);
}
/* The screenshot is a crop; the app continues past it. Fading the cut into the
   page ground says so, where a hard edge would read as a broken image. */
.hero-phone::after {
  content: '';
  position: absolute;
  inset: auto 4px 4px 4px;
  height: 4.5rem;
  border-radius: 0 0 11px 11px;
  background: linear-gradient(to top, var(--counter), rgba(7, 31, 25, 0));
}

@media (max-width: 60rem) {
  .hero-stage {
    max-width: 26rem;
  }
}

/* --- the counter book's rows ------------------------------------------ */
/* Names left, dates in the middle, amounts right in mono — the way the page
   of a real book is laid out. */

.ledger-row,
.ledger-total {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 4.6rem);
  gap: 0.7rem;
  align-items: baseline;
  padding: 0.62rem 0;
}
.ledger-row {
  border-top: 1px solid var(--border-paper);
}
.ledger-row span:last-child,
.ledger-total span:last-child {
  text-align: right;
}
.ledger-when {
  font-size: 0.84rem;
  color: var(--ink-muted);
}
.ledger-total {
  margin-top: 0.35rem;
  border-top: 2px solid var(--ink);
  grid-template-columns: minmax(0, 1fr) minmax(0, 4.6rem);
  /* Body face, not the display face. Partly because "Owed to the shop" in
     expanded type wraps to two lines in a book this narrow — but mostly
     because it is truer: in a real ledger the total is written in the same
     hand as everything above it, and the double rule and the figure are what
     mark it as the total. */
  font-family: var(--sans);
}
.ledger-total .num {
  font-family: var(--mono);
  font-size: 1.02rem;
}

/* On a phone the book has about 350px to live in, so it sheds the date column
   and sets a size down — who owes and how much are the two facts, and the date
   is the one a shopkeeper already knows.

   This block used to squeeze the phone in beside the book at 34% width. The
   book has its own band now, and the rules that made room for the phone here
   outlived the layout: they kept 30% of the hero stage as padding for a phone
   that was no longer there, which shrank it to 87px on a 375px screen. */
@media (max-width: 40rem) {
  .counter-book {
    padding: 1.05rem 1.2rem 0.95rem 1.9rem;
    font-size: 0.9rem;
  }
  .counter-book::before {
    left: 1.15rem;
  }
  .ledger-row,
  .ledger-total {
    grid-template-columns: minmax(0, 1fr) minmax(0, 4rem);
    gap: 0.55rem;
  }
  /* The date is the first thing to go: who owes and how much are the two
     facts, and the date is the one a shopkeeper already knows. */
  .ledger-when {
    display: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .ledger-row {
    animation: ledger-in 420ms ease-out both;
  }
  .ledger-row:nth-of-type(2) {
    animation-delay: 60ms;
  }
  .ledger-row:nth-of-type(3) {
    animation-delay: 120ms;
  }
  .ledger-row:nth-of-type(4) {
    animation-delay: 180ms;
  }
  @keyframes ledger-in {
    from {
      opacity: 0;
      transform: translateY(5px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }

  /* The one orchestrated moment on the page: the names arrive one by one and
     then the total lands under them. That IS the product — the book everyone
     keeps, adding itself up — so it is the single thing worth animating. The
     rest of the page deliberately has no entrance animation; a fade-and-rise
     on every section is decoration, and it reads as decoration. */
  .ledger-total {
    animation: total-land 460ms cubic-bezier(0.2, 0.8, 0.3, 1) 260ms both;
  }
  @keyframes total-land {
    from {
      opacity: 0;
      transform: translateY(-3px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }
}

/* --- motion: hover ---------------------------------------------------- */
/* Guarded on `hover: hover` and `pointer: fine`. A touch screen reports a
   phantom hover on tap and then STAYS in it until you touch elsewhere, so
   without this guard every one of these cards would stick half-lifted on the
   phones this site is mostly read on.
 *
 * The screenshots do the interesting thing: the fade over the bottom of each
 * one RETREATS on hover, so more of the actual screen appears. The lift is
 * just the invitation — the payload is that you see further into the app the
 * longer you look at it, which is the one thing this section is for. */
@media (hover: hover) and (pointer: fine) {
  .feature-shot img {
    transition: transform 340ms cubic-bezier(0.2, 0.75, 0.3, 1), box-shadow 340ms ease-out;
  }
  .feature-shot::after {
    transition: height 340ms cubic-bezier(0.2, 0.75, 0.3, 1);
  }
  .feature-card:hover .feature-shot img {
    transform: translateY(-7px) scale(1.014);
    box-shadow: 0 32px 60px -28px rgba(0, 0, 0, 0.95);
  }
  .feature-card:hover .feature-shot::after {
    height: 2.25rem;
  }
  .feature-card p {
    transition: color 340ms ease-out;
  }
  .feature-card:hover p {
    color: var(--on-dark);
  }

  /* The paper objects straighten when you look at them, the way you would
     square up a book on a counter to read it. They rotate back on their own. */
  .counter-book,
  .price-tag,
  .hero-phone {
    transition: transform 420ms cubic-bezier(0.2, 0.75, 0.3, 1),
      box-shadow 420ms ease-out;
  }
  .problem-stage:hover .counter-book {
    transform: rotate(-0.9deg) translateY(-4px);
  }
  .hero-stage:hover .hero-phone {
    transform: rotate(1.4deg) translateY(-7px);
  }
  .price-tag:hover {
    transform: rotate(-0.5deg) translateY(-5px);
    box-shadow: 0 34px 62px -26px rgba(0, 0, 0, 0.95);
  }
}

/* --- motion: the shots rise as they arrive ---------------------------- */
/* Scroll-driven, and CSS-only. `animation-timeline` runs on the compositor in
   Chromium rather than the main thread, which matters more here than usual:
   the audience is on low-end Android, and a scroll handler in JS is exactly
   what makes those phones stutter. Where it is unsupported the rule never
   applies and the images are simply visible — the content never depends on
   the animation having run. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .feature-card {
      animation: shot-rise linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 30%;
    }
    @keyframes shot-rise {
      from {
        opacity: 0.4;
        transform: translateY(1.5rem);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }
  }
}

/* --- eyebrow ---------------------------------------------------------- */
/* The one place small caps earn their keep: naming which of the page's five
   arguments you are standing in. Not a decorative label above every heading —
   only sections that make a distinct claim carry one. */

.eyebrow {
  margin: 0 0 0.7rem;
  font-family: var(--display);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--sage);
}

/* --- the problem ------------------------------------------------------ */
/* Named before any feature, because a shopkeeper recognises the questions
   before they recognise the product.
 *
 * The counter book lives HERE, not in the hero. In the hero it shared a narrow
 * column with the phone and the two fought: the phone covered "Owed to the
 * shop", and the customer names wrapped. A band of its own solves by layout
 * what two rounds of padding could only mitigate. */

.problem {
  background: var(--counter-raised);
  color: var(--on-dark);
  padding: 4rem 0 4.5rem;
}
.problem-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3.5rem;
  align-items: center;
}
.problem-copy {
  max-width: 30rem;
}
.problem-copy h2 {
  margin-bottom: 1.4rem;
}

/* Questions, not bullets. No marker: a disc would make them a list of features
   when they are things being asked out loud across a counter. */
.problem-questions {
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--rule-dark);
}
.problem-questions li {
  padding: 0.72rem 0;
  border-bottom: 1px solid var(--rule-dark);
  color: var(--on-dark-muted);
}
.problem-answer {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  color: var(--gold);
}

.problem-stage {
  position: relative;
  max-width: 27rem;
  margin-inline: auto;
  /* Room below and right for the sheet underneath to show. Percentages, so the
     whole object scales with its column instead of breaking at a breakpoint. */
  padding: 0 4% 7% 0;
}
/* The sheet underneath. A single page is a form; a stack is a book. */
.problem-stage::before {
  content: '';
  position: absolute;
  left: 0;
  right: 4%;
  top: 0;
  bottom: 7%;
  background: #e2e8e1;
  border-radius: 7px;
  transform: rotate(2.4deg) translate(7px, 7px);
  box-shadow: 0 12px 30px -22px rgba(0, 0, 0, 0.9);
  z-index: 0;
}

@media (max-width: 60rem) {
  .problem-grid {
    grid-template-columns: 1fr;
    gap: 2.75rem;
  }
  .problem-stage {
    max-width: 24rem;
  }
}

/* --- features --------------------------------------------------------- */
/* Four real screens. The grid replaced both a three-up screenshot strip and a
   five-row ruled list that repeated what the screenshots already showed. */

.features-section {
  background: var(--counter);
  color: var(--on-dark);
  padding: 4rem 0 4.5rem;
}
.section-intro {
  max-width: 34rem;
  margin-bottom: 2.5rem;
}
.section-intro p {
  margin: 0;
  color: var(--on-dark-muted);
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.5rem;
}
.feature-card {
  margin: 0;
  background: var(--counter-raised);
  border: 1px solid var(--rule-dark);
  border-radius: 12px;
  overflow: hidden;
}
.feature-card h3 {
  margin: 1.1rem 1.15rem 0.4rem;
  color: var(--gold);
  font-size: 1.02rem;
}
.feature-card p {
  margin: 0 1.15rem 1.25rem;
  font-size: 0.92rem;
  color: var(--on-dark-muted);
}

/* A 4:5 window on a 540x740 screenshot shows about 91% of it. A square window
   was tried first and showed only the top 73% — which on these four screens is
   the header and the filter chips, the dimmest part of each, with every bright
   figure cut off below the fold. The card went almost black. What identifies
   an app screen is its numbers, so the window has to reach them. */
.feature-shot {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: #0b0b0b;
  /* A hairline, so the screen reads as a device face set into the card rather
     than a dark hole punched in it. */
  box-shadow: inset 0 0 0 1px rgba(238, 242, 239, 0.09);
}
.feature-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}
/* The screenshot is a crop; the app continues past it. Fading the cut into the
   card says so, where a hard edge would read as a broken image. */
.feature-shot::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 2.4rem;
  background: linear-gradient(to top, var(--counter-raised), rgba(12, 58, 47, 0));
}

@media (max-width: 64rem) {
  .feature-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 34rem) {
  .feature-grid {
    grid-template-columns: 1fr;
  }
}

/* --- built for Zimbabwe ----------------------------------------------- */
/* The page's one light band. Five dark sections in a row read as one long
   section; a break here gives the two claims that are most specific to this
   market their own ground instead of another dark card on a dark page.
   Both objects inside carry their own surface already, so nothing had to be
   redrawn to stand on paper. */

.zimbabwe {
  background: var(--paper);
  color: var(--ink);
  padding: 4rem 0 3.5rem;
}
.zw-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem;
}
.zw-card {
  margin: 0;
  background: #fff;
  border: 1px solid var(--border-paper);
  border-radius: 14px;
  padding: 1.9rem 1.9rem 2.1rem;
}
.zw-card h2 {
  margin-bottom: 0.9rem;
  font-size: 1.62rem;
}
.zw-card p {
  color: var(--ink-muted);
}
.zw-card .eyebrow {
  color: var(--green);
}
.zw-card .price-tag {
  margin-top: 1.6rem;
}

/* Roles as a ladder, widest access at the top. The order is the information —
   this IS a sequence, unlike the feature grid, which is why it is ordered and
   the grid is not numbered. */
.roles {
  margin: 1.6rem 0 0.9rem;
  padding: 0;
  list-style: none;
  border: 1px solid var(--border-paper);
  border-radius: 10px;
  overflow: hidden;
}
.roles li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.78rem 1rem;
  background: var(--bg);
}
.roles li + li {
  border-top: 1px solid var(--border-paper);
}
.role-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.92rem;
}
.role-scope {
  font-size: 0.82rem;
  color: var(--ink-muted);
  text-align: right;
}
.roles-note {
  margin: 0;
  font-size: 0.88rem;
  color: var(--ink-muted);
}

/* --- trust ------------------------------------------------------------ */
/* Carries NO count, deliberately: a hard number with no date beside it is a
   figure that silently stops being true the first time a shop stops trading,
   and nothing on the page would say so. The kinds of shop are checkable and
   do not rot. */

.trust {
  margin-top: 3.25rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--border-paper);
  text-align: center;
}
.trust-lead {
  margin: 0 0 1rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.02rem;
}
.trust-kinds {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.55rem 0.7rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.trust-kinds li {
  padding: 0.34rem 0.85rem;
  border: 1px solid var(--border-paper);
  border-radius: 999px;
  background: var(--bg);
  font-size: 0.85rem;
  color: var(--ink-muted);
}

@media (max-width: 52rem) {
  .zw-grid {
    grid-template-columns: 1fr;
  }
}

/* --- the price tag ---------------------------------------------------- */
/* A shelf-edge price tag: gold band, punched hole, and the two prices sitting
   side by side as equals, because that is the claim the section is making.

   The version this replaced listed Cost, Sell, Sell in ZWL and Profit as four
   identical rows under the heading "Two prices. One item." — so the two prices
   looked exactly like the two numbers that are not the point. Cost and profit
   are now a footnote, which is what they are. */

.price-tag {
  position: relative;
  max-width: 26rem;
  background: var(--paper);
  color: var(--ink);
  border-radius: 11px;
  overflow: hidden;
  transform: rotate(-1.6deg);
  box-shadow: 0 26px 52px -26px rgba(0, 0, 0, 0.9);
}

.tag-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--gold);
  color: #201a02;
  padding: 0.75rem 1.15rem;
}
/* The punched hole is GONE. Sitting at the left of the gold band, immediately
   before the product name, it read as a bullet point rather than a hole — and
   the band, the tilt and the shadow already say "tag" without it. One
   accessory removed. */
.tag-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.01em;
}
.tag-stock {
  margin-left: auto;
  font-size: 0.79rem;
  white-space: nowrap;
  opacity: 0.72;
}

.tag-prices {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.tag-price {
  padding: 1.6rem 1rem 1.35rem;
  text-align: center;
}
.tag-price + .tag-price {
  border-left: 1px solid var(--border-paper);
}
.tag-price .num {
  display: block;
  font-size: clamp(1.7rem, 4.8vw, 2.35rem);
  letter-spacing: -0.025em;
}
/* USD and ZiG are currency codes, not a styling choice dressed as a label.
   (It said ZWL until the 2026-09-25 rename, one commit after the markup it
   describes stopped saying it.) */
.tag-cur {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--display);
  font-size: 0.68rem;
  letter-spacing: 0.15em;
  color: var(--ink-muted);
}

.tag-foot {
  display: flex;
  justify-content: center;
  gap: 1.6rem;
  border-top: 1px solid var(--border-paper);
  padding: 0.65rem 1.15rem 0.3rem;
  font-size: 0.87rem;
  color: var(--ink-muted);
}
.tag-rate {
  margin: 0;
  padding: 0 1.15rem 0.8rem;
  text-align: center;
  font-size: 0.78rem;
  color: var(--ink-muted);
}

/* --- get the app ------------------------------------------------------ */

.get {
  background: var(--counter);
  color: var(--on-dark);
  padding: 4.5rem 0 5rem;
  text-align: center;
}
.get-inner {
  max-width: 34rem;
  margin-inline: auto;
}
/* The real launcher icon, so the thing to look for in the Play listing is
   already familiar by the time they get there. */
.get-icon {
  width: 64px;
  height: 64px;
  border-radius: 14px;
  margin-bottom: 1.1rem;
}
.get p {
  color: var(--on-dark-muted);
}
.get .btn {
  margin-top: 0.75rem;
  font-size: 1.02rem;
  padding: 1rem 2rem;
}
.get-reassure {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.5rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.88rem;
  color: var(--on-dark-muted);
}
.get-platform {
  margin: 1.1rem 0 0;
  font-size: 0.88rem;
}

/* --- footer ----------------------------------------------------------- */

.site-footer {
  background: var(--counter);
  color: var(--on-dark);
  border-top: 1px solid var(--rule-dark);
  padding: 2.25rem 0;
}
.site-footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}
.footer-links a {
  color: var(--on-dark-muted);
  font-size: 0.9rem;
}
.footer-links a:hover {
  color: var(--on-dark);
}
.footer-legal {
  margin: 0;
  width: 100%;
  font-size: 0.82rem;
  color: var(--on-dark-muted);
}

/* --- prose (the legal pages) ------------------------------------------ */
/* These never opt into the dark ground. terms.html alone is 59KB of text. */

.prose {
  max-width: 44rem;
  padding: 3rem 0 4rem;
}
.prose h2 {
  margin-top: 2.25rem;
  color: var(--green);
}
.prose .notice {
  border-left: 3px solid var(--gold);
  padding-left: 1rem;
  color: var(--ink-muted);
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
