/* ============================================================================
   Floom — the product page
   ----------------------------------------------------------------------------
   One layout for the four products (Fund Operations, Deal Intelligence,
   Portfolio Intelligence, Fund Modeling), drawn from the product-page
   wireframe; only the words and the product surfaces change from page to page.

     hero       the product's name, the promise, the lede, one wide surface,
                and two buttons under it
     rows       three of them: the words on the left (headline at the top,
                the detail at the foot), the surface on the right
     carousel   a centred headline over three square slides, the neighbours
                peeking in at either edge
     panel      a centred headline over one wide window
     after      the rest of the demo page in the same vocabulary: one more
                row where a page has one, the connected products, the
                questions, the closing call

   The wireframe is 1280 wide; every measure below is its pixel value at that
   width, carried as a share of the window so the page keeps its proportions
   from a laptop to a large display. Surfaces are the product's own, built
   from floom-surface.css; this file only frames them.
   ========================================================================== */

.pp{
  --pp-plate: color-mix(in srgb, var(--black) 4.5%, transparent);
  --pp-hair: color-mix(in srgb, var(--black) 12%, transparent);
  --pp-copy: clamp(15px, 1.17vw, 17.81px);
  display: block;
  color: var(--black);
}
.pp-wrap{
  width: var(--fl-wrap);   /* the 12-column grid */
  margin-inline: auto;
}

/* ── type ─────────────────────────────────────────────────────────────────
   Upper case and light, as the wireframe sets them; the source text stays in
   sentence case so a screen reader and a search engine read it as written. */
.pp-h1, .pp-h2, .pp-display{
  margin: 0;
  font-family: var(--font-display);
  font-weight: 450;
  line-height: 1.3;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--black);
}
.pp-h1{ font-size: var(--fl-t-display); max-width: var(--fl-span-8); margin-inline: auto; text-wrap: pretty; }
.pp-h2{ font-size: var(--fl-t-title2); max-width: 16em; text-wrap: pretty; }
.pp-display{ font-size: var(--fl-t-title1); max-width: var(--fl-span-6); margin-inline: auto; text-align: center; text-wrap: pretty; }

.pp-copy, .pp-sub, .pp-lede, .pp-dl{
  margin: 0;
  font-family: var(--font);
  font-size: var(--pp-copy);
  font-weight: 450;
  line-height: 1.3;
  color: var(--fl-ink-soft, #767270);
}
.pp-copy{ color: var(--gray-900, #312E2E); }
.pp-copy b, .pp-sub b{ font-weight: 600; color: var(--black); }
.pp-copy + .pp-copy{ margin-top: 12px; }
.pp-lede{ max-width: 40em; margin: 24px auto 0; color: var(--gray-900, #312E2E); }
.pp-sub{ max-width: 42em; margin: var(--fl-gap-stand) auto 0; text-align: center; color: var(--gray-900, #312E2E); }

.pp-eyebrow{
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0;
  font-family: var(--font);
  font-size: 14px; font-weight: 500; line-height: 1;
  color: var(--black);
}
.pp-eyebrow .pp-sq{ width: 8px; height: 8px; flex: none; background: var(--accent); }
.pp-eyebrow .pp-tag{ color: var(--fl-ink-soft, #767270); font-weight: 450; }

/* ── the buttons ──────────────────────────────────────────────────────────
   The site's own pair (floom-apple.css .ap-btn): the solid one and the ghost,
   small radius, capitals, the label and its arrow travelling together on
   hover. The ghost was made for the home page's dark ramp (white glass); on a
   light page it takes the nav control's light-page values instead, so the
   pair reads the same way the nav's own button does over this ground. */
.pp-cta{ display: flex; flex-wrap: wrap; justify-content: center; gap: round(clamp(8px, 1.1vw, 16px), 4px); }
.pp .ap-btn-ghost,
.pp .ap-btn-ghost:hover,
.pp .ap-btn-ghost:focus-visible{
  color: var(--black);
  background: rgba(24, 24, 24, .06);
  border: 1px solid rgba(24, 24, 24, .10);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.pp .ap-btn:focus-visible{ outline: 2px solid var(--accent); outline-offset: 3px; }
/* A label longer than a phone is wide wraps rather than running off the
   screen. The travel needs a one-line box, so there the real label stands
   alone; a touch screen has no hover to play it on anyway. */
@media (max-width: 480px){
  .pp .ap-btn{ white-space: normal; max-width: 100%; text-align: left; line-height: 1.3; }
  .pp .ap-swap, .pp .ap-swap > span{ height: auto; line-height: 1.3; overflow: visible; transform: none; }
  .pp .ap-swap-b{ display: none !important; }
}

/* the way on, in the site's own link (floom-story.css .st-link) */
.pp-links{ display: flex; flex-wrap: wrap; gap: 12px 28px; margin-top: 24px; }
.pp-link{
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font);
  font-size: 15.79px; font-weight: 600; line-height: 1;
  color: var(--black);
  transition: color .24s var(--th-ease, cubic-bezier(.2, .7, .2, 1));
}
.pp-link:is(:hover, :focus-visible){ color: var(--accent); }
.pp-center .pp-links{ justify-content: center; }

/* ── the plate ────────────────────────────────────────────────────────────
   The wireframe's grey boxes: a recessed ground with the product's own
   surface standing on it. The surface keeps its natural size; the plate
   keeps the wireframe's proportion while the surface fits, and grows with it
   when it does not (an aspect-ratio box takes its content's height as its
   minimum), so nothing is ever clipped. */
.pp-plate{
  position: relative;
  display: grid;
  place-items: center;
  padding: round(clamp(16px, 2.5vw, 40px), 4px);
  border-radius: 4px;
  background: var(--pp-plate);
}
.pp-plate > .prod-ui{
  width: 100%;
  background: #FFFFFF;
  box-shadow: 0 1px 2px rgba(24, 24, 24, .04), 0 18px 40px -18px rgba(24, 24, 24, .16);
}
.pp-cap{
  margin: 16px 0 0;
  font-family: var(--font);
  font-size: 12.41px; font-weight: 450; line-height: 1.3;
  color: var(--fl-ink-soft, #767270);
}
.pp-center .pp-cap, .pp-hero .pp-cap{ text-align: center; }

/* ── hero ─────────────────────────────────────────────────────────────────*/
.pp-hero{
  padding-top: round(calc(var(--fl-nav-h, 92px) + clamp(40px, 5vw, 80px)), 8px);
  text-align: center;
}
html.is-sheet .pp-hero{ padding-top: round(clamp(56px, 7.6vw, 104px), 8px); }
.pp-hero .pp-h1{ margin-top: var(--fl-gap-eyebrow); }
.pp-stage{
  aspect-ratio: 1198 / 531;
  text-align: left;
}
.pp-stage > .prod-ui{ max-width: 1100px; }
@media (min-width: 1200px){ .pp-stage > .prod-ui{ zoom: 1.08; } }
.pp-hero .pp-cta{ margin-top: 28px; }
/* The scene after the standfirst: the gap a head keeps from what it
   introduces. Two classes, so it outranks the scene kit's `.aa{ margin: 0 }`,
   which loads after this file and otherwise sets the scene flush against
   the standfirst. */
.pp-hero .pp-stage{ margin-top: var(--fl-gap-head); }

/* ── rows ─────────────────────────────────────────────────────────────────*/
.pp-rows{
  display: grid;
  gap: round(clamp(56px, 7vw, 104px), 8px);
  padding-top: round(clamp(88px, 12vw, 160px), 8px);
}
/* Words over columns 1–4, the picture (or cards, or questions) over 5–12. */
.pp-row{
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--fl-col-gap);
  scroll-margin-top: 96px;
}
.pp-row > .pp-row-text{ grid-column: 1 / span 4; grid-row: 1; }
.pp-row > :not(.pp-row-text){ grid-column: 5 / -1; grid-row: 1; }
/* Three cards cannot each take whole columns of eight, so a row of three
   gives its words columns 1–3 and its cards 4–12, three columns each. */
.pp-row:has(> .pp-cards.is-3) > .pp-row-text{ grid-column: 1 / span 3; }
.pp-row:has(> .pp-cards.is-3) > .pp-cards{ grid-column: 4 / -1; }
.pp-row-text{
  display: flex; flex-direction: column; justify-content: space-between;
  gap: 32px;
  min-width: 0;
}
.pp-row-foot{ max-width: 25em; }
/* Never stretched: a stretched aspect-ratio box takes its WIDTH from the
   stretched height, so a tall surface would widen the plate past its column.
   Pinned to the top it keeps the column's width and grows downward instead;
   the words beside it stretch to whatever height that comes to. */
.pp-media{ aspect-ratio: 784 / 513; min-width: 0; align-self: start; }

/* The rows alternate, as the wireframe lays them out: words then picture,
   picture then words, words then picture. Every second row with a picture
   turns round, in the rows block and in the rows after the panel alike; the
   columns keep their widths, only their sides change. */
.pp-rows > .pp-row:nth-child(even) > .pp-row-text,
.pp-after > .pp-row:has(> .pp-media):nth-child(even) > .pp-row-text{ grid-column: 9 / -1; }
.pp-rows > .pp-row:nth-child(even) > .pp-media,
.pp-after > .pp-row:has(> .pp-media):nth-child(even) > .pp-media{ grid-column: 1 / span 8; }

/* ── steps ────────────────────────────────────────────────────────────────
   The product pages' three steps, read one after another: a list of them
   held at the left while each is read on the right, its title, its words
   and its screen stacked in one column. The page splits down the middle —
   the heading and the steps start at the half — and the list sits at the
   left edge of the empty half, so the words have air on both sides.

   As a step crosses the middle of the window its name darkens and an orange
   thread draws under it, at the pace of the scroll; when the next step takes
   over, the finished thread runs off to the right (floom-product.js). The
   names are links to their steps, so the list also works as a contents. */
.pp-steps{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);   /* columns 1–6 and 7–12 */
  column-gap: var(--fl-col-gap);
  padding-top: var(--fl-pad-section);
}
.pp-steps-h{
  grid-column: 2;
  margin: 0;
  max-width: 15em;
  font-family: var(--font-display);
  font-size: var(--fl-t-title1);
  font-weight: 450;
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--black);
  /* the head → content gap every section head on the site uses (40–64), so
     the heading sits closer to its first step than the steps sit to each
     other (72–112). It was 152 plus the list's 56 — further from its first
     step than any step from the next, which read as detached (2026-11-05). */
  margin-bottom: var(--fl-gap-head);
}
.pp-steps-side{ grid-column: 1; grid-row: 2; min-width: 0; }
.pp-steps-nav{
  position: sticky;
  top: 96px;
  display: grid;
  justify-items: start;
  gap: 16px;
}
.pp-step-link{
  display: grid;
  gap: 8px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 450;
  line-height: 1.3;
  color: color-mix(in srgb, var(--black) 40%, transparent);
  text-decoration: none;
  transition: color .5s var(--th-ease, cubic-bezier(.2, .7, .2, 1));
}
.pp-step-link:hover,
.pp-step-link.is-on{ color: var(--black); }
.pp-step-link:focus-visible{ outline: 2px solid var(--accent); outline-offset: 4px; }
/* a hairline the width of the list, and the thread drawn along it */
.pp-step-bar{
  position: relative;
  display: block;
  width: clamp(150px, 13vw, 190px);
  height: 1px;
  background: var(--pp-hair);
}
.pp-step-bar i{
  position: absolute;
  left: 0; top: -1px;
  width: 100%; height: 3px;
  background: var(--accent);
  transform-origin: 0 50%;
  transform: scaleX(var(--p, 0));
}
.pp-step-link.is-past .pp-step-bar i{
  transform-origin: 100% 50%;
  transform: scaleX(0);
  transition: transform .5s var(--th-ease, cubic-bezier(.2, .7, .2, 1));
}
.pp-steps-list{
  grid-column: 2;
  grid-row: 2;
  display: grid;
  gap: round(clamp(72px, 7.5vw, 112px), 8px);
  min-width: 0;
}
.pp-step{ display: grid; min-width: 0; scroll-margin-top: 96px; }
.pp-step-h{
  margin: 0;
  max-width: 20em;
  font-family: var(--font-display);
  font-size: var(--fl-t-title2);
  font-weight: 450;
  line-height: 1.3;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: pretty;
  color: var(--black);
}
.pp-step-copy{ max-width: 30em; margin-top: var(--fl-gap-stand); }
.pp-step-copy .pp-list{ margin-top: 20px; }
.pp-step-copy .pp-dl{ margin-top: 24px; }
.pp-step-copy .pp-links{ margin-top: 20px; }
/* Each step's picture, framed the way granola.ai frames its own: a square
   with 16px corners on a ground of its own — the Back to the Source picture
   (the brand's own ramp), a different part of it behind each step (--bx) —
   and on it the step's app scene (floom-artifact.css), squared to 784 x 784
   with its ground left to the picture: its cards set in from the top and
   left and running off the right and the bottom, so the screen reads close,
   not shrunk to fit. */
.pp-step-media{
  position: relative;
  container-type: inline-size;
  margin: round(clamp(24px, 2.5vw, 32px), 4px) 0 0;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 16px;
  background: var(--ap-ink) url(/assets/focus-bg.webp) var(--bx, 0%) 50% / cover no-repeat;
}
/* the scene's own figure rule sets no margin; the step keeps its gap */
.pp-step-media.aa{ margin: round(clamp(24px, 2.5vw, 32px), 4px) 0 0; }

@media (prefers-reduced-motion: reduce){
  .pp-step-link,
  .pp-step-link.is-past .pp-step-bar i{ transition: none; }
}

/* the detail at the foot: a short label beside its line */
.pp-dl{
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 24px 20px;
  margin-top: 36px;
  color: var(--black);
}
.pp-dl dt{ font-weight: 450; color: var(--black); }
/* labels too long to sit beside their line go above it */
.pp-dl.is-stack{ grid-template-columns: minmax(0, 1fr); gap: 4px; }
.pp-dl.is-stack dd + dt{ margin-top: 16px; }
.pp-dl.is-stack dt{ font-weight: 500; }
.pp-dl dd{ margin: 0; color: var(--gray-900, #312E2E); }
.pp-dl dd q{ quotes: none; }
.pp-list{
  list-style: none; margin: 32px 0 0; padding: 0;
  display: grid; gap: 16px;
  font-family: var(--font); font-size: var(--pp-copy); font-weight: 450; line-height: 1.3;
  color: var(--gray-900, #312E2E);
}
.pp-list li{ display: grid; grid-template-columns: 8px minmax(0, 1fr); gap: 16px; align-items: baseline; }
.pp-list li::before{ content: ""; width: 6px; height: 6px; background: var(--accent); transform: translateY(-2px); }

/* ── the centred band: a headline, its line, and what it introduces ───────*/
.pp-band{ padding-top: var(--fl-pad-section); }
.pp-center{ text-align: center; }

/* the jump list some pages open with: three numbered destinations */
.pp-jumps{
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: var(--fl-gap-head) auto 0;
  max-width: var(--fl-span-8);   /* columns 3–10 */
  border-top: 1px solid var(--pp-hair);
  text-align: left;
}
.pp-jump{
  display: grid; gap: 8px;
  padding: 24px 24px 8px 0;
  font-family: var(--font);
}
.pp-jump + .pp-jump{ padding-left: 24px; border-left: 1px solid var(--pp-hair); }
.pp-jump-n{ font-size: 12.41px; font-weight: 500; letter-spacing: 0.05em; color: var(--accent); }
.pp-jump-t{
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font-display); font-size: 17.81px; font-weight: 450; line-height: 1.3;
  text-transform: uppercase; color: var(--black);
}

/* ── carousel ─────────────────────────────────────────────────────────────
   Slides that run sideways as the page scrolls down (floom-product.js). The
   band holds a window-tall frame, clear of the bar, with the words over the
   slides and the dots under them; the page scrolls the slides' travel while
   it holds, the slide in the middle being read and its neighbours showing at
   either edge. Each slide is its name over its scene, sized so the scene
   stands whole in the frame (the script sets --pp-w, capped here, and
   --pp-h, the tallest slide's height, so the plates read as one row). */
.pp-car{
  --pp-w: min(63.8vw, 860px);
  --pp-g: round(clamp(16px, 3.75vw, 48px), 4px);
  position: relative;
  margin-top: var(--fl-gap-head);
  /* clip, not hidden: a hidden box can still be scrolled, and focusing a
     control inside it scrolled the whole track sideways off its slide */
  overflow: hidden;
  overflow: clip;
  outline: none;
}
.pp-car-track{
  display: flex;
  align-items: flex-start;
  gap: var(--pp-g);
  width: max-content;
  will-change: translate;
}
.pp-slide{
  flex: 0 0 var(--pp-w);
  width: var(--pp-w);
  min-height: var(--pp-h, 0px);
  display: flex; flex-direction: column;
  gap: round(clamp(16px, 2.2vw, 28px), 4px);
  place-items: stretch;
  text-align: left;
  user-select: none;
  transition: opacity .5s ease;
}
.pp-car.is-ready .pp-slide:not(.is-on){ opacity: .5; cursor: pointer; }
.pp-car.is-ready .pp-slide:not(.is-on):hover{ opacity: .72; }
.pp-slide-h{ display: grid; gap: 8px; max-width: 34em; }
.pp-slide-h h3{
  margin: 0;
  font-family: var(--font-display); font-size: var(--fl-t-title3); font-weight: 450; line-height: 1.3;
  letter-spacing: -0.02em; text-transform: uppercase; color: var(--black);
}
.pp-slide-h p{ margin: 0; font-family: var(--font); font-size: var(--pp-copy); font-weight: 450; line-height: 1.3; color: var(--gray-900, #312E2E); }
.pp-slide > .prod-ui{ width: 100%; }
@media (min-width: 1100px){ .pp-slide > .prod-ui{ zoom: 1.1; } }

/* The held frame. The band's own top space moves inside the frame, so the
   frame holds from the moment the band reaches the top of the window. */
.pp-band.is-pan{
  padding-top: 0;
  height: calc(100svh + var(--pp-travel, 0px));
  view-timeline: --pp-pan block;
}
.pp-pin{
  position: sticky;
  top: 0;
  height: 100svh;
  /* safe: a frame that cannot fit runs off the foot, never under the bar */
  display: flex; flex-direction: column; justify-content: safe center;
  padding: calc(var(--fl-nav-h, 92px) + 8px) 0 round(clamp(16px, 2.5vw, 32px), 4px);
  box-sizing: border-box;
}
/* Held, the words over the slides take as little height as they can, so the
   slides keep the most: the headline on one line where it fits, its line and
   its link side by side under it. */
.pp-band.is-pan .pp-wrap{
  display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline;
  column-gap: 28px;
}
.pp-band.is-pan .pp-display{ flex: 0 0 100%; max-width: none; }
.pp-band.is-pan .pp-sub{ margin: 16px 0 0; }
.pp-band.is-pan .pp-links{ margin-top: 16px; }
.pp-band.is-pan .pp-car{ margin-top: round(clamp(24px, 3.3vw, 40px), 8px); }
/* On a short window the slides need the dots' row more than the reader does:
   the scroll moves them and shows where it is, and the arrow keys still do. */
@media (max-height: 819.98px){
  .pp-band.is-pan .pp-car-nav{ display: none; }
}
/* where the browser has scroll timelines the track rides the band's; the
   script moves it elsewhere */
@keyframes pp-pan{
  from{ translate: var(--pp-x0, 0px) 0; }
  to{ translate: var(--pp-x1, 0px) 0; }
}
.pp-band.is-timeline .pp-car-track{
  animation: pp-pan linear both;
  animation-timeline: --pp-pan;
  animation-range: contain 0% contain 100%;
}

.pp-car-nav{
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin-top: round(clamp(24px, 2.5vw, 32px), 4px);
}
.pp-car-dots{ display: flex; gap: 8px; }
.pp-car-dot, .pp-car-arrow{
  border: 0; padding: 0; background: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.pp-car-dot{ width: 28px; height: 28px; display: grid; place-items: center; }
.pp-car-dot::before{
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: color-mix(in srgb, var(--black) 22%, transparent);
  transition: background-color .3s ease, width .3s var(--fl-ease-out, ease);
}
.pp-car-dot[aria-current="true"]::before{ width: 22px; border-radius: 4px; background: var(--black); }
.pp-car-arrow{
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pp-plate);
  color: var(--black);
  transition: background-color .25s ease;
}
.pp-car-arrow:hover{ background: color-mix(in srgb, var(--black) 9%, transparent); }
.pp-car-dot:focus-visible, .pp-car-arrow:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 50%; }
.pp-car-count{
  min-width: 4.5em;
  font-family: var(--font); font-size: 12.41px; font-weight: 500; letter-spacing: 0.05em;
  color: var(--fl-ink-soft, #767270); text-align: center;
}

/* ── connected products ───────────────────────────────────────────────────*/
.pp-cards{ display: grid; grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr)); gap: var(--fl-col-gap); }   /* two cards over columns 5–12 = four columns each */
.pp-card{
  display: flex; flex-direction: column; justify-content: space-between; gap: 40px;
  min-height: clamp(180px, 17vw, 240px);
  padding: round(clamp(16px, 2vw, 28px), 4px);
  border-radius: 4px;
  background: var(--pp-plate);
  color: var(--black);
  transition: background-color .3s ease;
}
.pp-card:hover, .pp-card:focus-visible{ background: color-mix(in srgb, var(--black) 8%, transparent); }
.pp-card:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
.pp-card-k{
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-size: var(--fl-t-title3); font-weight: 450; line-height: 1.3;
  letter-spacing: -0.02em; text-transform: uppercase;
}
.pp-card-k .pp-flag{ font-family: var(--font); font-size: 11.01px; letter-spacing: 0.05em; color: var(--accent); }
.pp-card-d{ display: block; margin-top: 8px; font-family: var(--font); font-size: var(--pp-copy); font-weight: 450; line-height: 1.3; color: var(--gray-900, #312E2E); }
.pp-card-go{
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font); font-size: 15.79px; font-weight: 600; line-height: 1;
}
.pp-card-go .th-arrow{ color: var(--accent); }

/* ── questions: the home page's accordion, floom-faq.css ─────────────────*/

/* ── the sections after the wireframe sit on the same rhythm ──────────────*/
.pp-after{ display: grid; gap: round(clamp(72px, 9vw, 128px), 8px); padding-top: round(clamp(96px, 10vw, 140px), 8px); }

/* ── in the sheet ─────────────────────────────────────────────────────────
   The sheet drops the site's nav and footer (floom-ui.css). A product page
   keeps its footer: the page ends the way the wireframe ends it, on the
   footer, inside the sheet's own scroll. */
html.is-sheet body.pp-page .ft-reveal,
html.is-sheet body.pp-page footer{ display: block !important; }

/* ── narrow ───────────────────────────────────────────────────────────────*/
@media (max-width: 900px){
  .pp-row{ row-gap: 28px; }
  /* one column: the placement's own selectors, so these outrank nothing and
     lose to nothing — a looser selector here left the rows side by side */
  .pp-row > .pp-row-text,
  .pp-row > :not(.pp-row-text),
  .pp-rows > .pp-row:nth-child(even) > .pp-row-text,
  .pp-rows > .pp-row:nth-child(even) > .pp-media,
  .pp-after > .pp-row:has(> .pp-media):nth-child(even) > .pp-row-text,
  .pp-after > .pp-row:has(> .pp-media):nth-child(even) > .pp-media,
  .pp-row:has(> .pp-cards.is-3) > .pp-row-text,
  .pp-row:has(> .pp-cards.is-3) > .pp-cards{ grid-column: 1 / -1; grid-row: auto; }
  /* one column: the words come first on every row, whichever side they had */
  .pp-row-text{ justify-content: flex-start; gap: 0; }
  .pp-row-foot{ max-width: 36em; margin-top: 16px; }
  /* one column: the heading, then each step in turn; a held list of three
     names beside nothing would only take room from the screens */
  .pp-steps{ grid-template-columns: minmax(0, 1fr); }
  .pp-steps-h, .pp-steps-list{ grid-column: 1; }
  .pp-steps-side{ display: none; }
  /* one column now, so the step's words are placed on the page grid: columns
     1–8 (1–10 on a tablet, all twelve on a phone) */
  .pp-step-h, .pp-step-copy{ max-width: var(--fl-span-8); }
  .pp-row-text .pp-h2{ max-width: var(--fl-span-8); }   /* a row's heading, now over the page grid */
  .pp-dl{ margin-top: 24px; }
  .pp-media, .pp-stage{ aspect-ratio: auto; }
  .pp-cards{ grid-template-columns: minmax(0, 1fr); }
  .pp-card{ min-height: 0; gap: 28px; }
  .pp-jumps{ grid-template-columns: minmax(0, 1fr); }
  .pp-jump + .pp-jump{ padding-left: 0; border-left: 0; border-top: 1px solid var(--pp-hair); }
  .pp-jump{ padding: 16px 0; }
}
@media (max-width: 720px){
  /* a surface's side-by-side parts stack on a phone, as the app's own do */
  .pp .pu-cols, .pp .pu-cols.is-wide-left, .pp .pu-cols.is-wider-left, .pp .pu-cols.is-wide-right{ grid-template-columns: minmax(0, 1fr); }
  .pp-car{ --pp-w: 86vw; --pp-g: 12px; }
  .pp-plate{ padding: 8px; }
}
@media (prefers-reduced-motion: reduce){
  .pp-slide, .pp-card{ transition: none; }
}

/* a formula quoted in the words: the site's own face, not the browser's
   default monospace */
.pp code{ font-family: var(--mono); font-size: inherit; font-weight: 500; color: var(--black); overflow-wrap: anywhere; }

/* a card with nowhere to go yet (a client that is coming soon) */
.pp-card.is-static, .pp-card.is-static:hover{ background: var(--pp-plate); cursor: default; }
.pp-card-go.is-quiet{ color: var(--fl-ink-soft, #767270); font-weight: 450; }

/* the plate under a surface you can work says so, quietly, in its margin */
.pp-try{
  position: absolute; left: round(clamp(16px, 2.5vw, 40px), 4px); bottom: round(clamp(8px, 0.9vw, 12px), 4px);
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0;
  font-family: var(--font); font-size: 12.41px; font-weight: 500; line-height: 1;
  color: var(--fl-ink-soft, #767270);
}
.pp-try::before{ content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
@media (max-width: 900px){ .pp-try{ position: static; grid-row: 2; justify-self: start; margin-top: 8px; } }
