/* ============================================================
   GMDS · content pages

   Everything the hero page is, minus the hero. No canvas, no module, no
   model: this page is text somebody came here to read, and it should cost
   what text costs.

   What carries the family resemblance is the type system, not the machinery.
   The same variable width axis on display words, the same tracked capitals
   with a matching text-indent, the same one-pixel hairlines, and the same two
   colours doing the same two jobs: violet is interactive, scarlet is display.

   site.css is loaded first for the tokens, the font face and the nav.
   ============================================================ */

/* --- the room ----------------------------------------------------------
   A fixed backdrop rather than a scrolling one, so nothing repaints while
   the page moves. Three radial washes over the void, in the colours the
   scene emits, which gets the sky of the front page for about a line of CSS
   and no download at all.
   ---------------------------------------------------------------------- */

.page {
  min-height: 100vh; min-height: 100svh;
  background: var(--void);
}

.page::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(60vw 55vh at 12% 4%,  var(--wash-1), transparent 68%),
    radial-gradient(55vw 50vh at 88% 26%, var(--wash-2), transparent 66%),
    radial-gradient(70vw 60vh at 50% 96%, var(--wash-3), transparent 70%),
    var(--void);
  pointer-events: none;
}

/* On a content page the nav is simply present, not gated behind a reveal. */
.nav--static { opacity: 1; translate: none; pointer-events: auto; }

/* And it is solid.

   The hero's bar grounds itself with a gradient that fades to nothing at the
   bottom edge, which is right there: a filled strip would cut the frame in
   half and undo the point of the machine standing in open space. On a page of
   text it is wrong. Copy scrolls up through the transparent half of the bar
   and sits behind the navigation, which reads as two things printed on top of
   each other.

   A fill and a hairline instead. Nothing passes under it. */
.nav--static::before {
  background: var(--void);
  border-bottom: 1px solid var(--edge);
}

/* And it lines up with the page.

   On the hero the bar runs to the edges of the viewport, which is right: the
   rail is out there too and the scene fills the frame. On a content page the
   text lives in a 78rem column and the mark was sitting a hundred pixels
   outside it, so the first word of the navigation and the first word of the
   page started in two different places.

   The strip stays full width. Only the contents move in, to exactly where
   main and the footer put theirs. */
.nav--static {
  padding-inline: calc(max(0px, (100% - 78rem) * 0.5) + clamp(1.2rem, 5vw, 4rem));
}

.page main {
  position: relative; z-index: 1;
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 clamp(1.2rem, 5vw, 4rem);
}

/* --- page head ----------------------------------------------------------
   The title and the carousel controls share a line.

   The controls used to sit under the slide, which put the only clue that this
   was a carousel below a screenshot 775px tall. Nobody scrolls past a picture
   that size hoping there is a second one. Beside the title they are read
   immediately after it, and the counter answers "how many" before you have
   looked at even one.
   ---------------------------------------------------------------------- */

.phead {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  padding: clamp(5.5rem, 13vh, 8rem) 0 clamp(1rem, 2.4vh, 1.5rem);
  border-bottom: 1px solid var(--edge);
}

.phead__text { min-width: 0; }

.phead__kicker {
  margin: 0 0 0.85rem;
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.28em; text-indent: 0.28em;
  text-transform: uppercase;
  color: var(--scarlet-lit);
}

/* The width axis again, as on every display word in this project. 118 rather
   than the hero's 125: this is a page title, not the poster. */
.phead__title {
  margin: 0;
  font-size: clamp(2.2rem, 5.6vw, 4rem);
  font-weight: 800; font-stretch: 118%;
  line-height: 0.94; letter-spacing: -0.035em;
  color: var(--paper);
}

.phead__lede {
  margin: clamp(1rem, 2.4vh, 1.5rem) 0 clamp(1.6rem, 4vh, 2.4rem);
  max-width: 34rem;
  font-size: clamp(0.98rem, 1.2vw, 1.08rem);
  line-height: 1.6;
  color: var(--paper-dim);
}

/* --- the controls -------------------------------------------------------
   No dots. A dot row says how many things exist and nothing about what they
   are, and it is the least usable control on the page at the width where it
   matters most. A counter says the same thing in less space and can be read
   aloud, which is why it carries the live region.
   ---------------------------------------------------------------------- */

.car__bar { display: flex; align-items: center; gap: 0.5rem; flex: none; }

.car__count {
  margin: 0 0.6rem 0 0;
  font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--paper-mut);
  font-variant-numeric: tabular-nums;
}
.car__count b { color: var(--paper); font-weight: 800; }
.car__count i { font-style: normal; padding: 0 0.4em; opacity: 0.45; }
.car__count em { font-style: normal; }

/* Drawn with two borders on a rotated box rather than a glyph or an icon
   file: no font to load, no second request, and it sits on the same
   one-pixel grammar as the hairlines around it. */
.car__arrow {
  position: relative;
  flex: none;
  width: 2.75rem; height: 2.75rem;      /* 44px, the smallest reliable target */
  padding: 0;
  border: 1px solid var(--edge);
  background: none;
  cursor: pointer;
  transition: border-color 240ms var(--ease-out), background 240ms var(--ease-out);
}
.car__arrow span {
  position: absolute; top: 50%; left: 50%;
  width: 0.5rem; height: 0.5rem;
  border-left: 1px solid var(--paper);
  border-bottom: 1px solid var(--paper);
  transform: translate(-30%, -50%) rotate(45deg);
}
.car__arrow--next span { transform: translate(-70%, -50%) rotate(-135deg); }

.car__arrow:hover:not(:disabled),
.car__arrow:focus-visible:not(:disabled) {
  border-color: var(--violet);
  background: var(--violet-a14);
}

/* Disabled, not hidden. An arrow that vanishes at the end shifts the counter
   sideways and makes the whole control feel broken. */
.car__arrow:disabled { cursor: default; opacity: 0.26; }

/* --- carousel -----------------------------------------------------------
   One product at a time. The slides sit in a row and the row is translated,
   so moving costs a composite and nothing else. Showing and hiding would
   force layout on every press.
   ---------------------------------------------------------------------- */

.car { margin: 0 0 clamp(2rem, 5vh, 3rem); }

.car__viewport {
  overflow: hidden;
  touch-action: pan-y;                 /* a drag on the picture is a swipe */
  -webkit-user-select: none; user-select: none;
}

.car__track {
  display: flex;
  margin: 0; padding: 0;
  list-style: none;
  transition: transform 620ms var(--ease);
  will-change: transform;
}

.car__slide {
  flex: 0 0 100%;
  min-width: 0;
  opacity: 0.26;
  transition: opacity 480ms var(--ease-out);
}
.car__slide.is-at { opacity: 1; }

/* --- the slide ----------------------------------------------------------- */

.shot__link { display: block; text-decoration: none; color: inherit; }

/* The frame carries the border and the clipping, not the image, so the
   browser is not compositing a rounded picture on every hover frame. */
.shot__frame {
  display: block;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--edge);
  background: var(--surface);
  box-shadow: 0 24px 70px var(--shadow);
  transition: border-color 320ms var(--ease-out), box-shadow 320ms var(--ease-out);
}
.shot__frame img {
  display: block;
  width: 100%; height: auto;
  /* Capped. A tall screenshot at full height takes the whole viewport and
     pushes everything that explains it below the fold. */
  max-height: 60vh;
  object-fit: cover; object-position: top center;
  transform: scale(1);
  transition: transform 620ms var(--ease-out);
  will-change: transform;
}

.shot__link:hover .shot__frame,
.shot__link:focus-visible .shot__frame {
  border-color: var(--violet-a55);
  box-shadow: 0 30px 90px var(--shadow-lg);
}
.shot__link:hover .shot__frame img,
.shot__link:focus-visible .shot__frame img { transform: scale(1.028); }

/* Name, sentence and destination in one grid under the picture, in the order
   the questions arrive: what is it, what does it do, where does it go. */
.shot__meta {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: clamp(0.9rem, 3vw, 2.5rem);
  padding: clamp(1rem, 2.4vh, 1.4rem) 0 0;
}

.shot__name {
  font-size: clamp(1.4rem, 3vw, 2.1rem);
  font-weight: 800; font-stretch: 118%;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--paper);
}

.shot__line {
  font-size: clamp(0.9rem, 1.05vw, 1rem);
  line-height: 1.55;
  color: var(--paper-dim);
  max-width: 40rem;
}

.shot__go {
  position: relative;
  flex: none;
  padding-bottom: 0.25rem;
  font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.18em; text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--paper-mut);
  white-space: nowrap;
  transition: color 260ms var(--ease-out);
}
.shot__go::after {
  content: '';
  position: absolute; left: 0; right: 0.18em; bottom: 0;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 380ms var(--ease-out);
}
.shot__link:hover .shot__go,
.shot__link:focus-visible .shot__go { color: var(--scarlet-lit); }
.shot__link:hover .shot__go::after,
.shot__link:focus-visible .shot__go::after { transform: none; }

/* The closing slide is a statement, not a product, so its frame stops
   pretending to be a screenshot. */
.shot__frame--soon {
  box-shadow: none;
  background: oklch(42% 0.13 292);
  display: grid; place-items: center;
  aspect-ratio: 16 / 7;
}
.shot__frame--soon img {
  width: min(46%, 22rem); height: auto; max-height: none; object-fit: contain;
}
.car__slide--soon .shot__link { cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .car__track, .car__slide, .shot__frame, .shot__frame img,
  .shot__go, .shot__go::after { transition: none; }
  .shot__link:hover .shot__frame img { transform: none; }
}

/* --- clients ------------------------------------------------------------
   A number on its own is a boast. What makes this a section rather than a
   line of bragging is saying what the number was measured against, so the
   three commitments are not decoration: they are the definition of "the same
   standard", and without them the sentence above them asks to be taken on
   faith.

   Not three cards. Three columns divided by a hairline, with the number doing
   the work a border would otherwise do. Identical bordered tiles with an icon
   on top is the shape every agency page already has.
   ---------------------------------------------------------------------- */

.clients {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: start;
  padding: clamp(2.5rem, 6vh, 3.5rem) 0 clamp(3.5rem, 9vh, 5.5rem);
  border-top: 1px solid var(--edge);
}

/* Placed, not auto-placed. The head comes first in the markup and claims
   column 2, which pushes an auto-placed stat into a row of its own and leaves
   a hole the height of the headline above it. */
.clients__stat { grid-column: 1; grid-row: 1; }

.clients__figure {
  margin: 0;
  font-size: clamp(3.6rem, 11vw, 7rem);
  font-weight: 800; font-stretch: 118%;
  line-height: 0.82; letter-spacing: -0.05em;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}
/* The plus modifies the number, it is not a digit of it, so it is set small
   and lifted rather than left sitting on the baseline at full size. */
.clients__figure sup {
  font-size: 0.4em;
  vertical-align: super;
  color: var(--scarlet-lit);
  margin-left: 0.04em;
}

.clients__label {
  margin: 0.7rem 0 0;
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.28em; text-indent: 0.28em;
  text-transform: uppercase;
  color: var(--paper-mut);
}

.clients__head { grid-column: 2; max-width: 40rem; }

.clients__kicker {
  margin: 0 0 0.8rem;
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.28em; text-indent: 0.28em;
  text-transform: uppercase;
  color: var(--scarlet-lit);
}

.clients__title {
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  font-weight: 800; font-stretch: 110%;
  line-height: 1.1; letter-spacing: -0.03em;
  color: var(--paper);
}

/* The variant with no spec list under it, used to close a post. The call to
   action lives in the head there, so it needs the space the closing row would
   otherwise have given it. */
.clients--slim .pnext__cta { margin-top: clamp(1.4rem, 3.2vh, 2rem); }

.clients__note {
  margin: 1.1rem 0 0;
  font-size: clamp(0.94rem, 1.1vw, 1.02rem);
  line-height: 1.65;
  color: var(--paper-dim);
  max-width: 36rem;
}

/* --- the three ----------------------------------------------------------- */

.clients__specs {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  list-style: none;
  margin: clamp(2.2rem, 6vh, 3.4rem) 0 0;
  padding: clamp(2rem, 5vh, 2.8rem) 0 0;
  border-top: 1px solid var(--edge);
  counter-reset: spec;
}

.clients__specs li {
  padding: 0 clamp(1.2rem, 3vw, 2.4rem);
  border-left: 1px solid var(--edge);
}
/* The first column sits on the page's own left edge, so a rule there would be
   a stray line rather than a divider. */
.clients__specs li:first-child { padding-left: 0; border-left: 0; }

.clients__n {
  display: block;
  margin-bottom: 0.9rem;
  font-size: 0.68rem; font-weight: 800;
  letter-spacing: 0.2em; text-indent: 0.2em;
  color: oklch(64% 0.21 300);
  font-variant-numeric: tabular-nums;
}

.clients__specs h3 {
  margin: 0 0 0.6rem;
  font-size: clamp(1rem, 1.35vw, 1.18rem);
  font-weight: 800; font-stretch: 106%;
  line-height: 1.25; letter-spacing: -0.015em;
  color: var(--paper);
}

.clients__specs p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--paper-dim);
}

/* --- the close ----------------------------------------------------------- */

.clients__end {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  margin-top: clamp(2.2rem, 6vh, 3.4rem);
  padding-top: clamp(1.4rem, 3vh, 2rem);
  border-top: 1px solid var(--edge);
}
.clients__end p {
  margin: 0;
  font-size: clamp(1rem, 1.3vw, 1.15rem);
  font-weight: 700; font-stretch: 106%;
  letter-spacing: -0.01em;
  color: var(--paper);
}

.pnext__cta {
  display: inline-flex; align-items: center;
  padding: 0.75rem 1.4rem;
  background: var(--violet);
  color: var(--void); text-decoration: none;
  font-size: 0.7rem; font-weight: 800;
  letter-spacing: 0.12em; text-indent: 0.12em;
  text-transform: uppercase;
  box-shadow: 0 0 0 0 var(--violet-a50);
  transition: box-shadow 320ms var(--ease-out), background 260ms var(--ease-out);
}
.pnext__cta:hover,
.pnext__cta:focus-visible {
  background: var(--violet-lit-b);
  box-shadow: 0 0 0 3px var(--violet-a28);
}

@media (max-width: 860px) {
  /* Two up, then one. Three columns of body copy below this width gives each
     of them about six words a line. */
  .clients__specs { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2rem; }
  .clients__specs li:nth-child(odd) { padding-left: 0; border-left: 0; }
}

@media (max-width: 560px) {
  .clients { grid-template-columns: 1fr; }
  .clients__stat { grid-column: 1; grid-row: auto; }
  .clients__head { grid-column: 1; }
  .clients__specs { grid-template-columns: 1fr; row-gap: 1.8rem; }
  .clients__specs li { padding-left: 0; border-left: 0; }
  .clients__end { flex-direction: column; align-items: flex-start; }
}

/* --- blog listing -------------------------------------------------------
   A list, not a grid of cards. Three tiles in a row makes every post look the
   same size and the same weight, which is a design that hides the one thing a
   reader is deciding: is this one worth opening. A row gives the excerpt the
   width to answer that.
   ---------------------------------------------------------------------- */

.plist {
  list-style: none;
  margin: 0 0 clamp(3rem, 8vh, 5rem);
  padding: 0;
  border-top: 1px solid var(--edge);
}

.plist__item { border-bottom: 1px solid var(--edge); }

.plist__link {
  display: grid;
  grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
  gap: clamp(1.2rem, 4vw, 3rem);
  align-items: start;
  padding: clamp(1.6rem, 4vh, 2.4rem) 0;
  text-decoration: none; color: inherit;
}

.plist__shot {
  display: block;
  overflow: hidden;
  border: 1px solid var(--edge);
  background: var(--surface);
}
.plist__shot img {
  display: block;
  width: 100%; height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover; object-position: top center;
  transform: scale(1);
  transition: transform 620ms var(--ease-out);
}
.plist__shot--none {
  aspect-ratio: 16 / 9;
  background:
    radial-gradient(70% 90% at 30% 10%, oklch(38% 0.15 300 / 0.6), transparent 70%),
    var(--surface);
}
.plist__link:hover .plist__shot img,
.plist__link:focus-visible .plist__shot img { transform: scale(1.03); }

.plist__body { display: grid; gap: 0.55rem; }

.plist__meta {
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.22em; text-indent: 0.22em;
  text-transform: uppercase;
  color: var(--paper-mut);
}
.plist__dot { padding: 0 0.4em; opacity: 0.5; }

.plist__title {
  font-size: clamp(1.3rem, 2.6vw, 2rem);
  font-weight: 800; font-stretch: 112%;
  line-height: 1.12; letter-spacing: -0.025em;
  color: var(--paper);
  transition: color 260ms var(--ease-out);
}
.plist__link:hover .plist__title,
.plist__link:focus-visible .plist__title { color: var(--violet-soft); }

.plist__line {
  font-size: clamp(0.94rem, 1.1vw, 1.02rem);
  line-height: 1.6;
  color: var(--paper-dim);
  max-width: 42rem;
}

.plist__go {
  position: relative;
  justify-self: start;
  margin-top: 0.35rem;
  padding-bottom: 0.25rem;
  font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.18em; text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--paper-mut);
  transition: color 260ms var(--ease-out);
}
.plist__go::after {
  content: '';
  position: absolute; left: 0; right: 0.18em; bottom: 0;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 380ms var(--ease-out);
}
.plist__link:hover .plist__go,
.plist__link:focus-visible .plist__go { color: var(--scarlet-lit); }
.plist__link:hover .plist__go::after,
.plist__link:focus-visible .plist__go::after { transform: none; }

/* Empty listing. Says what is happening and sends the reader somewhere that
   is not empty, rather than apologising in grey. */
.pempty {
  padding: clamp(2.5rem, 8vh, 4.5rem) 0 clamp(3.5rem, 10vh, 6rem);
  border-top: 1px solid var(--edge);
  max-width: 40rem;
}
.pempty h2 {
  margin: 0 0 0.9rem;
  font-size: clamp(1.35rem, 2.5vw, 1.95rem);
  font-weight: 800; font-stretch: 108%;
  line-height: 1.15; letter-spacing: -0.025em;
  color: var(--paper);
}
.pempty p {
  margin: 0 0 1.6rem;
  font-size: clamp(0.94rem, 1.1vw, 1.02rem);
  line-height: 1.65;
  color: var(--paper-dim);
}

/* --- a post -------------------------------------------------------------
   One column at a reading measure, because that is the entire job. The
   backdrop and the type system carry the family resemblance; nothing else
   here needs to perform.
   ---------------------------------------------------------------------- */

/* The reading column, centred in the page. 44rem is about 70 characters at
   this size, which is the measure; the page around it is 78rem because the
   products carousel needs the width. Pinning the article to the left of that
   container leaves a third of the screen empty on one side and nothing on the
   other, which reads as a layout that broke rather than one that chose. */
.pnarrow { max-width: 44rem; margin: 0 auto; }

.pback {
  display: inline-block;
  margin: clamp(5.5rem, 13vh, 8rem) 0 1.5rem;
  font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.18em; text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--paper-mut); text-decoration: none;
  transition: color 240ms var(--ease-out);
}
.pback:hover, .pback:focus-visible { color: var(--paper); }

.post { max-width: none; }              /* .pnarrow owns the measure now */

.post__head { padding-bottom: clamp(1.4rem, 3vh, 2rem); }

.post__meta {
  margin: 0 0 1rem;
  font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.22em; text-indent: 0.22em;
  text-transform: uppercase;
  color: var(--paper-mut);
}
.post__meta span { padding: 0 0.4em; opacity: 0.5; }

.post__title {
  margin: 0;
  font-size: clamp(2rem, 5vw, 3.4rem);
  font-weight: 800; font-stretch: 118%;
  line-height: 1.02; letter-spacing: -0.035em;
  color: var(--paper);
}

.post__lede {
  margin: 1.2rem 0 0;
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  line-height: 1.55;
  color: var(--paper-dim);
}

.post__shot {
  margin: 0 0 clamp(1.6rem, 4vh, 2.4rem);
  border: 1px solid var(--edge);
  overflow: hidden;
  background: var(--surface);
}
.post__shot img { display: block; width: 100%; height: auto; }

/* --- the prose ---------------------------------------------------------
   Set once, for the tags clean_body allows and nothing else. An editor
   cannot reach past this list, so this list is the whole design.
   ---------------------------------------------------------------------- */

.post__body {
  font-size: clamp(1rem, 1.15vw, 1.08rem);
  line-height: 1.75;
  color: var(--paper-dim);
}
.post__body > :first-child { margin-top: 0; }
.post__body p { margin: 0 0 1.35em; }

.post__body h2, .post__body h3 {
  margin: 2.2em 0 0.6em;
  font-weight: 800; font-stretch: 108%;
  line-height: 1.2; letter-spacing: -0.02em;
  color: var(--paper);
}
.post__body h2 { font-size: clamp(1.3rem, 2.2vw, 1.7rem); }
.post__body h3 { font-size: clamp(1.1rem, 1.7vw, 1.3rem); }

.post__body strong, .post__body b { color: var(--paper); font-weight: 700; }

.post__body a {
  color: var(--violet-soft);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.post__body a:hover { color: var(--paper); }

.post__body ul, .post__body ol { margin: 0 0 1.35em; padding-left: 1.3em; }
.post__body li { margin: 0 0 0.5em; }
.post__body li::marker { color: var(--paper-mut); }

/* A rule and a step in, not a coloured slab down one side. */
.post__body blockquote {
  margin: 1.8em 0;
  padding: 0 0 0 1.4rem;
  border-left: 1px solid var(--violet-a50);
  font-size: 1.08em;
  line-height: 1.6;
  color: var(--paper);
}
.post__body blockquote p:last-child { margin-bottom: 0; }

.post__body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88em;
  padding: 0.1em 0.35em;
  background: var(--edge-soft);
  color: var(--paper);
}
.post__body pre {
  margin: 0 0 1.35em;
  padding: 1rem 1.1rem;
  overflow-x: auto;                      /* a long line scrolls, the page does not */
  background: var(--surface-2);
  border: 1px solid var(--edge);
  font-size: 0.86rem; line-height: 1.6;
}
.post__body pre code { padding: 0; background: none; }

.post__tags {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  list-style: none;
  margin: clamp(2rem, 5vh, 3rem) 0 0;
  padding: 0;
}
.post__tags li {
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--edge);
  font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.14em; text-indent: 0.14em;
  text-transform: uppercase;
  color: var(--paper-mut);
}

.post + .clients { margin-top: clamp(3rem, 8vh, 5rem); }

@media (prefers-reduced-motion: reduce) {
  .plist__shot img, .plist__title, .plist__go, .plist__go::after { transition: none; }
  .plist__link:hover .plist__shot img { transform: none; }
}

@media (max-width: 760px) {
  /* Picture over text. Two columns at this width leaves the excerpt about
     twenty characters, which is not an excerpt. */
  .plist__link { grid-template-columns: 1fr; gap: 1rem; }
}

/* --- pager --------------------------------------------------------------
   Numbered pages, not a Load More button. A reader who wants the oldest post
   can reach it, a crawler can walk the archive from the first page, and Back
   does what it says. Infinite scroll trades all three for a scroll bar that
   lies about how much is left.
   ---------------------------------------------------------------------- */

.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin: 0 0 clamp(3rem, 8vh, 5rem);
  padding-top: clamp(1.4rem, 3vh, 2rem);
}

.pager__step {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--edge);
  font-size: 0.64rem; font-weight: 700;
  letter-spacing: 0.18em; text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--paper); text-decoration: none;
  transition: border-color 240ms var(--ease-out), background 240ms var(--ease-out);
}
.pager__step:hover, .pager__step:focus-visible {
  border-color: var(--violet);
  background: var(--violet-a14);
}
/* Present and dimmed at the ends rather than removed, so the row does not
   jump sideways when you reach the last page. */
.pager__step.is-off { opacity: 0.28; }

.pager__nums {
  display: flex; align-items: center; gap: 0.3rem;
  list-style: none; margin: 0; padding: 0;
}

.pager__num {
  display: grid; place-items: center;
  min-width: 2.4rem; height: 2.4rem;
  padding: 0 0.5rem;
  border: 1px solid transparent;
  font-size: 0.8rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--paper-mut); text-decoration: none;
  transition: color 240ms var(--ease-out), border-color 240ms var(--ease-out);
}
.pager__num:hover, .pager__num:focus-visible {
  color: var(--paper); border-color: var(--edge);
}
.pager__num.is-at { color: var(--paper); border-color: var(--violet); }

@media (max-width: 560px) {
  .pager { justify-content: center; }
  .pager__nums { order: -1; width: 100%; justify-content: center; }
}

/* --- narrow -------------------------------------------------------------
   Declared per block rather than left to chance. The index loses its
   description column before it wraps, and the prose drops to one column
   before the measure gets too short to read.
   ---------------------------------------------------------------------- */

@media (max-width: 760px) {
  /* Name over sentence over link. Three columns at this width leaves each of
     them about nine characters. */
  .shot__meta { grid-template-columns: 1fr; gap: 0.5rem; }
  .shot__go { justify-self: start; }
}

@media (max-width: 640px) {
}

/* The line the form shows when somebody arrived from a service page. Hidden
   until script fills it in, because an empty box above the first field is
   worse than no box. */
.form__about {
  margin: 0 0 1.2rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--violet-edge);
  background: var(--violet-a14);
  color: var(--paper);
  font-size: 0.82rem; font-weight: 700;
  letter-spacing: 0.04em;
}
