/* ===========================================================================
   Pressure Point launch pages. Shared module system.

   Every page sets its own palette by declaring the tokens below in its own
   :root. This file never hardcodes a colour that a variant might want to
   change, so one stylesheet serves both the dark performance pages and the
   light editorial pages.

   Tokens a page must set:
     --pp-bg      page background
     --pp-bg2     raised surface
     --pp-bg3     sunken surface
     --pp-ink     primary text
     --pp-ink2    secondary text
     --pp-ink3    tertiary text, captions, sources
     --pp-line    hairline
     --pp-line2   stronger hairline
     --pp-acc     accent
     --pp-acc-ink text that sits on the accent
     --pp-acc-dim accent at low alpha, for washes
     --pp-cond    condensed display family
     --pp-body    body family
   =========================================================================== */

/* ---------- reveal ----------
   Gated on .js, which an inline head script adds before this sheet is parsed.
   Without JavaScript nothing is ever hidden, so the page is complete on arrival
   rather than blank. Hiding content that only a script can bring back is the
   most expensive mistake an animated page can make. */
.js .pp-r{opacity:0;transform:translateY(18px);transition:opacity .62s cubic-bezier(.2,.7,.3,1),transform .62s cubic-bezier(.2,.7,.3,1)}
.js .pp-r.in{opacity:1;transform:none}
.pp-r-1{transition-delay:.06s}.pp-r-2{transition-delay:.12s}.pp-r-3{transition-delay:.18s}
.pp-r-4{transition-delay:.24s}.pp-r-5{transition-delay:.30s}.pp-r-6{transition-delay:.36s}
@media(prefers-reduced-motion:reduce){
  .js .pp-r{opacity:1;transform:none;transition:none}
  .pp-bar i,.pp-band i,.pp-ring circle,.pp-chain-line i{transition:none !important;animation:none !important}
}

/* ---------- tilt and highlight ----------
   Applied by script to card surfaces, mouse pointers only. The lit state is
   what carries the highlight and the lift; the resting state deliberately
   declares no transform at all, so it never fights the reveal above it.

   The highlight is a background-image rather than a pseudo element, for two
   reasons. These cards are shared across nine pages and several of them already
   use ::before and ::after for rules and quote marks, and a background layer
   sits under the type for free without a stacking context to manage. */
.pp-tilt{transition:transform .55s cubic-bezier(.2,.8,.3,1),box-shadow .4s ease,
  border-color .4s ease;transform-style:preserve-3d}
/* Three classes deep on purpose. Most of these cards are also reveal targets,
   and `.js .pp-r.in{transform:none}` above would otherwise outrank a two class
   selector and flatten the tilt back out. Same weight, declared later, wins. */
.pp-tilt.lit,.js .pp-tilt.lit{
  transform:perspective(1100px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(0);
  /* Short and linear while the pointer is down on it. An eased transition here
     lags the cursor and the card feels like it is on elastic. */
  transition:transform .1s linear,box-shadow .4s ease,border-color .4s ease;
  background-image:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),
    var(--pp-glow,rgba(255,255,255,.06)),var(--pp-glow2,transparent) 70%);
  box-shadow:var(--pp-shadow,0 22px 50px -26px rgba(0,0,0,.5));
  border-color:var(--pp-line2);
  position:relative;z-index:2}
@media(prefers-reduced-motion:reduce){
  .pp-tilt,.pp-tilt.lit{transform:none !important;transition:box-shadow .3s ease}
}

/* ---------- section scaffolding ---------- */
/* One gutter, named, so the phone bleed below can undo exactly what this set. */
:root{--pp-gut:clamp(20px,4vw,32px)}
.pp-sec{padding:clamp(56px,8vw,104px) 0;position:relative}
.pp-sec.tint{background:var(--pp-bg2)}
.pp-sec.rule{border-top:1px solid var(--pp-line)}
.pp-w{max-width:1140px;margin:0 auto;padding:0 var(--pp-gut)}
.pp-w.narrow{max-width:880px}

.pp-eye{display:inline-flex;align-items:center;gap:9px;margin:0 0 16px;
  font:700 11px/1 var(--pp-body);letter-spacing:.17em;text-transform:uppercase;color:var(--pp-acc-text)}
.pp-eye::before{content:"";width:22px;height:1px;background:currentColor;opacity:.7}
/* Statements are Fraunces, sentence case, at the brand book's line heights.
   The old condensed-caps treatment shouted; Steinforts does not (02, 05). */
.pp-h2{font-family:var(--pp-cond);line-height:1.1;letter-spacing:-.01em;font-variation-settings:"SOFT" 0,"WONK" 0,"opsz" 100;
  font-size:clamp(28px,4.2vw,50px);font-weight:650;margin:0 0 16px;color:var(--pp-ink);text-wrap:balance}
.pp-h3{font-family:var(--pp-cond);line-height:1.16;letter-spacing:-.005em;font-variation-settings:"SOFT" 0,"WONK" 0,"opsz" 100;
  font-size:clamp(20px,2.4vw,27px);font-weight:600;margin:0 0 10px;color:var(--pp-ink)}
.pp-dek{color:var(--pp-ink2);font-size:clamp(16px,1.5vw,17.5px);line-height:1.62;max-width:62ch;margin:0 0 clamp(28px,4vw,46px)}
.pp-dek.tight{margin-bottom:24px}
.pp-src{font:400 12px/1.55 var(--pp-body);color:var(--pp-ink3);margin:14px 0 0}
.pp-src a{color:var(--pp-ink3)}
.pp-src b{font-weight:600;color:var(--pp-ink2)}

/* =========================================================================
   CREDIBILITY. The Watkins Spine model, adapted.
   ========================================================================= */
.pp-cred{border-top:1px solid var(--pp-line2);overflow:hidden}
/* Four short domain receipts. The old version set every organisation's mark in
   a static grid here and then repeated them all in a name wall below, which
   cost four to five viewports per page. The marks now live in the scrolling
   bands underneath, so these cards are back to being what they were for: the
   one sentence of proof per domain that a mark cannot say. */
.pp-statgrid{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line);
  grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.pp-statblock{background:var(--pp-bg);padding:clamp(20px,2.4vw,30px) clamp(18px,2.2vw,28px)}
.pp-statblock>h4{margin:0 0 12px;font:700 10.5px/1 var(--pp-body);letter-spacing:.19em;
  text-transform:uppercase;color:var(--pp-acc-text)}
.pp-statblock>p{margin:0;font:400 clamp(13px,1.3vw,14.5px)/1.62 var(--pp-body);color:var(--pp-ink2)}

/* =========================================================================
   THE ORGANISATION SCROLLS

   Two tracks moving in opposite directions at different speeds. Opposed motion
   is what makes a logo wall read as a wall rather than as a conveyor belt: the
   eye cannot lock onto a single direction, so it reads the field instead of
   chasing one mark, and the band keeps working no matter where the reader
   happens to arrive on it.

   Every mark is a typographic lockup in the page's own two families and a
   single ink colour, so the band inherits the palette, weighs nothing, and is
   sharp at any pixel density. Swapping in real vector files later is a per
   entry change that does not move the layout.
   ========================================================================= */
.pp-marqs{margin-top:clamp(8px,1.4vw,16px);
  /* The fade is what stops a mark from appearing to be chopped in half at the
     edge of the screen. Without it the band looks broken rather than infinite. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.pp-marq{overflow:hidden;padding:clamp(15px,1.9vw,22px) 0;border-top:1px solid var(--pp-line)}
.pp-marq.alt{border-bottom:1px solid var(--pp-line)}
.pp-marqt{display:flex;width:max-content;
  /* Half the track is a duplicate, so walking back exactly 50% lands the copy
     precisely where the original started. Any other number shows a seam. */
  animation:pp-marq var(--dur,70s) linear infinite}
.pp-marq.alt .pp-marqt{animation-direction:reverse}
.pp-marqr{display:flex;align-items:center;flex:0 0 auto}
/* The band never pauses. A stall under the cursor reads as a broken animation,
   not as a feature, and the names are repeated often enough to be read anyway. */
.pp-marqt{pointer-events:none}
@keyframes pp-marq{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}

.pp-lg{display:flex;align-items:center;gap:9px;flex:0 0 auto;
  padding:0 clamp(22px,3vw,40px);color:var(--pp-ink);
  /* Monochrome and slightly held back, so the band supports the headline
     instead of competing with it. No hover: the wall is not a control
     (John's 2026-09-02 review). */
  opacity:.62}
/* The glyph sits beside the lockup, and the lockup itself stacks. Two elements
   rather than three siblings, so a second line never lands next to the name. */
.pp-lgt{display:block}
.pp-lg b{display:block;white-space:nowrap;font-weight:700}
.pp-lg s{display:block;text-decoration:none;white-space:nowrap;
  font:600 10.5px/1.25 var(--pp-body);letter-spacing:.14em;text-transform:uppercase;
  color:var(--pp-ink3);margin-top:4px}

/* The four type recipes. Real marks differ mostly in weight, width, case and
   whether they are cut from a serif, so four recipes cover the whole set and
   the band still reads as many different brands rather than one list. */
.r-block b{font:700 clamp(24px,2.9vw,34px)/1 var(--pp-cond);text-transform:uppercase;letter-spacing:-.005em}
.r-italic b{font:700 clamp(24px,2.9vw,34px)/1 var(--pp-cond);text-transform:uppercase;
  font-style:italic;letter-spacing:-.02em}
.r-caps b{font:700 clamp(15px,1.65vw,19px)/1.05 var(--pp-body);text-transform:uppercase;letter-spacing:.13em}
.r-sans b{font:500 clamp(21px,2.5vw,29px)/1 var(--pp-body);letter-spacing:-.03em;text-transform:none}
.r-serif b{font:400 clamp(21px,2.5vw,29px)/1 Georgia,"Times New Roman",serif;letter-spacing:.005em}
.r-serif s{letter-spacing:.19em}

/* Glyphs. Enough of a silhouette to read as a mark at a glance, drawn rather
   than fetched, and inheriting the ink colour like everything else here. */
/* Real marks, greyed to one voice. Grayscale plus a slight hold-back makes
   fourteen different brand palettes read as one quiet band. Height, not
   width, is fixed, so a round seal and a wide wordmark both sit on the same
   optical line. */
.pp-lg.img img{height:clamp(36px,4.2vw,54px);width:auto;display:block;
  filter:grayscale(1) opacity(.58) contrast(.92)}

.pp-lgl{display:flex;align-items:center;justify-content:center;flex:0 0 auto;font-style:normal}
.pp-lgl.slash{width:26px;height:22px;background:
  repeating-linear-gradient(70deg,currentColor 0 3px,transparent 3px 7px)}
.pp-lgl.sq{display:grid;grid-template-columns:1fr 1fr;gap:2px;width:24px;height:24px}
.pp-lgl.sq s{width:11px;height:11px;background:currentColor;margin:0;opacity:.85}
.pp-lgl.ring{width:34px;height:34px;border:2px solid currentColor;border-radius:50%;
  font:700 13px/1 var(--pp-cond);letter-spacing:.01em}
.pp-lgl.mono{width:34px;height:34px;border:2px solid currentColor;
  font:700 14px/1 var(--pp-cond);letter-spacing:.02em}
.pp-lgl.shield{width:24px;height:26px}
.pp-lgl.shield svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.6}

/* Paddy's 2026-09-03 review: the full organisation list as one quiet line of
   plain text under the wall, in the same voice as the press line in the hero,
   for those who do not want to wait for the logos to scroll. */
.pp-orgroll{margin:clamp(16px,2vw,24px) auto 0;text-align:center;max-width:1080px;
  font:600 10.5px/2 var(--pp-body);letter-spacing:.13em;text-transform:uppercase;
  color:var(--pp-ink3)}
.pp-orgroll b{font-weight:700;color:var(--pp-ink2);white-space:nowrap}

/* Reduced motion stops the tracks and lets the band wrap into a static grid,
   which is the same content with the movement taken out. */
@media(prefers-reduced-motion:reduce){
  .pp-marqt{animation:none;width:auto;flex-wrap:wrap;justify-content:center}
  .pp-marqr{flex-wrap:wrap;justify-content:center}
  .pp-marqr[aria-hidden="true"]{display:none}
  .pp-marqs{-webkit-mask-image:none;mask-image:none}
  .pp-lg{padding:12px clamp(16px,2.4vw,30px)}
}

/* =========================================================================
   PRESS
   ========================================================================= */
.pp-pressbar{display:flex;flex-wrap:wrap;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line)}
.pp-pressbar a{flex:1 1 190px;background:var(--pp-bg);padding:18px 20px;text-decoration:none;
  display:block;transition:background .18s;text-align:center}
.pp-pressbar a:hover{background:var(--pp-bg2)}
.pp-pressbar b{display:block;font:700 15px/1.2 var(--pp-cond);text-transform:uppercase;letter-spacing:.03em;
  font-size:17px;color:var(--pp-ink)}
.pp-pressbar span{display:block;margin-top:5px;font:500 10.5px/1 var(--pp-body);letter-spacing:.14em;
  text-transform:uppercase;color:var(--pp-ink3)}
/* Jon's call, mobile only: with an odd outlet count the wall wraps into two
   columns and the last one dangles alone at the foot. So small screens get a
   strict two column grid and an odd last item is dropped rather than left
   hanging. Desktop keeps the full set. */
@media(max-width:640px){
  .pp-pressbar{display:grid;grid-template-columns:1fr 1fr}
  .pp-pressbar a:last-child:nth-child(odd){display:none}}

.pp-cover{display:grid;grid-template-columns:minmax(0,300px) 1fr;gap:clamp(26px,4vw,52px);align-items:center}
.pp-cover figure{margin:0;position:relative}
.pp-cover img{display:block;width:100%;height:auto;border:1px solid var(--pp-line);
  box-shadow:0 26px 60px -24px rgba(0,0,0,.55)}
.pp-cover .pp-kick{font:700 11px/1.7 var(--pp-body);letter-spacing:.11em;text-transform:uppercase;
  color:var(--pp-acc-text);margin:0 0 14px;max-width:52ch}
.pp-cover .pp-covertitle{font-family:var(--pp-cond);font-weight:600;font-variation-settings:"SOFT" 0,"WONK" 0,"opsz" 100;
  font-size:clamp(34px,5.2vw,62px);line-height:1.02;letter-spacing:-.01em;margin:0 0 18px;color:var(--pp-ink)}

/* =========================================================================
   THE CLIPPING. Press citation, not endorsement.
   ========================================================================= */
.pp-clip{border:1px solid #D3CEBF;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='0.055'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(130% 55% at 8% 2%,rgba(112,100,76,.06),transparent 55%),
    radial-gradient(120% 50% at 96% 100%,rgba(112,100,76,.05),transparent 55%),
    linear-gradient(180deg,#F8F6EF 0%,#F2EFE5 55%,#ECE8DB 100%);
  box-shadow:inset 0 0 70px rgba(112,100,76,.09),0 18px 40px -22px rgba(46,26,47,.35);
  padding:clamp(26px,3.6vw,46px) clamp(22px,3.4vw,46px)}
.pp-clip .pp-masthead{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 16px;
  padding-bottom:16px;border-bottom:2px solid var(--pp-ink);margin-bottom:22px}
.pp-clip .pp-masthead b{font-family:var(--pp-cond);text-transform:uppercase;font-weight:700;
  font-size:clamp(19px,2.2vw,25px);letter-spacing:.02em;color:var(--pp-ink);line-height:1}
.pp-clip .pp-masthead span{font:500 11px/1 var(--pp-body);letter-spacing:.13em;text-transform:uppercase;
  color:var(--pp-ink3);margin-left:auto}
.pp-clip .pp-hed{font-family:var(--pp-cond);font-weight:600;font-variation-settings:"SOFT" 0,"WONK" 0,"opsz" 100;
  font-size:clamp(22px,3vw,36px);line-height:1.08;letter-spacing:-.01em;margin:0 0 10px;color:var(--pp-ink);max-width:26ch}
.pp-clip .pp-byline{font:500 11.5px/1 var(--pp-body);letter-spacing:.13em;text-transform:uppercase;
  color:var(--pp-ink3);margin:0 0 26px}
.pp-clipbody{column-gap:40px;column-rule:1px solid var(--pp-line)}
@media(min-width:900px){.pp-clipbody{column-count:2}}
/* The pull quote spans both columns. Left inside the flow it is too tall to
   move, so the balancer gives up and one column ends short. */
.pp-clipbody>.pp-hl{column-span:all;margin-bottom:26px}
.pp-clipbody p{margin:0 0 16px;color:var(--pp-ink2);font-size:15.5px;line-height:1.66;break-inside:avoid}
.pp-clipbody p.pp-attrib{color:var(--pp-ink3);font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:600}

/* the highlighted sentence */
.pp-hl{display:block;margin:0 0 18px;padding:20px 22px;background:var(--pp-acc-dim);
  border-left:4px solid var(--pp-acc);break-inside:avoid}
.pp-hl q{font:600 clamp(19px,2.3vw,26px)/1.34 var(--pp-body);color:var(--pp-ink);quotes:'\201C' '\201D'}
.pp-hl cite{display:block;font-style:normal;margin-top:12px;font:700 11px/1.4 var(--pp-body);
  letter-spacing:.14em;text-transform:uppercase;color:var(--pp-ink2)}

/* =========================================================================
   ICP
   ========================================================================= */
.pp-icp{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line);
  grid-template-columns:repeat(auto-fit,minmax(290px,1fr))}
.pp-icpcard{background:var(--pp-bg);padding:clamp(24px,2.8vw,32px);display:flex;flex-direction:column}
.pp-icpcard svg{width:30px;height:30px;margin:0 0 18px;stroke:var(--pp-acc);fill:none;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.pp-icpcard .pp-k{font:700 10.5px/1 var(--pp-body);letter-spacing:.19em;text-transform:uppercase;
  color:var(--pp-acc-text);margin:0 0 10px}
.pp-icpcard h4{font-family:var(--pp-body);font-weight:700;font-size:18.5px;letter-spacing:-.01em;
  line-height:1.02;margin:0 0 12px;color:var(--pp-ink)}
.pp-icpcard p{margin:0 0 18px;color:var(--pp-ink2);font-size:14.8px;line-height:1.6}
.pp-icpcard .pp-ev{margin:auto 0 0;padding-top:16px;border-top:1px solid var(--pp-line);
  font:500 12.5px/1.55 var(--pp-body);color:var(--pp-ink3)}

/* =========================================================================
   THE SURVIVAL SPIRAL

   One SVG on a fixed viewBox, so it scales to any column without a media query
   and without a raster asset anyone has to license. Three things are animated
   and each one is carrying an argument the still picture cannot make:

     the ring draws    the four stages are a sequence, and a sequence has a start
     the nodes land    each one is a location, not a moment
     the pulse orbits  it does not finish. It comes round again.

   Every one of them is written so the finished state is the default and the
   stylesheet only winds it back when `.js` is on the page. A reader with no
   script gets a whole diagram rather than an empty box.
   ========================================================================= */
.pp-spiral{max-width:520px;margin:0 auto clamp(32px,4vw,48px)}
.pp-spiralsvg{display:block;width:100%;height:auto;overflow:visible}
.pp-spiralsvg .pp-track{fill:none;stroke:var(--pp-line);stroke-width:1}
.pp-spiralsvg .pp-ringline{fill:none;stroke:var(--pp-acc);stroke-width:2.4;stroke-linecap:round;
  transform:rotate(-90deg);transform-box:view-box;transform-origin:50% 50%}
.pp-spiralsvg .pp-return{fill:none;stroke:var(--pp-ink3);stroke-width:1.3;stroke-dasharray:4 5}
.pp-spiralsvg marker path{fill:var(--pp-ink3)}
.pp-spiralsvg .pp-node circle{fill:var(--pp-bg);stroke:var(--pp-acc);stroke-width:2.4}
.pp-spiralsvg .pp-nodename{font:600 21px/1 var(--pp-cond);fill:var(--pp-ink)}
.pp-spiralsvg .pp-nodesys{font:600 9px/1 var(--pp-body);fill:var(--pp-ink3);
  letter-spacing:.17em;text-transform:uppercase}
.pp-spiralsvg .pp-ringmid{font:600 23px/1 var(--pp-cond);fill:var(--pp-ink)}
.pp-spiralsvg .pp-ringsub{font:500 9px/1 var(--pp-body);fill:var(--pp-ink3);
  letter-spacing:.15em;text-transform:uppercase}
.pp-spiralsvg .pp-orbit circle{fill:var(--pp-acc)}
.pp-spiralsvg .pp-orbit{transform-box:view-box;transform-origin:50% 50%}

/* The wound-back states. `--len` is the circumference, handed over from the
   builder so the radius stays defined in exactly one place. */
.js .pp-spiral .pp-ringline{stroke-dashoffset:var(--len,830)}
.js .pp-spiral .pp-node circle,.js .pp-spiral .pp-orbit circle{transform:scale(0);
  transform-box:fill-box;transform-origin:50% 50%}
.js .pp-spiral .pp-node text,.js .pp-spiral .pp-return{opacity:0}
.js .pp-spiral.in .pp-ringline{stroke-dashoffset:0;
  transition:stroke-dashoffset 1.5s cubic-bezier(.3,.9,.3,1) .1s}
.js .pp-spiral.in .pp-node circle,.js .pp-spiral.in .pp-orbit circle{transform:scale(1);
  transition:transform .5s cubic-bezier(.2,1.4,.4,1)}
.js .pp-spiral.in .pp-node text{opacity:1;transition:opacity .5s ease}
.js .pp-spiral.in .pp-return{opacity:1;transition:opacity .6s ease 1.5s}
/* Staggered to the quarter points of the ring draw, so a node lands as the line
   reaches it rather than all four arriving at once. */
.js .pp-spiral.in .pp-node-1 circle,.js .pp-spiral.in .pp-node-1 text{transition-delay:.15s}
.js .pp-spiral.in .pp-node-2 circle,.js .pp-spiral.in .pp-node-2 text{transition-delay:.5s}
.js .pp-spiral.in .pp-node-3 circle,.js .pp-spiral.in .pp-node-3 text{transition-delay:.85s}
.js .pp-spiral.in .pp-node-4 circle,.js .pp-spiral.in .pp-node-4 text{transition-delay:1.2s}
.js .pp-spiral.in .pp-orbit circle{transition-delay:1.6s}
@media(prefers-reduced-motion:no-preference){
  .js .pp-spiral.in .pp-orbit{animation:pp-orbit 15s linear 1.6s infinite}
}
@keyframes pp-orbit{to{transform:rotate(360deg)}}

.pp-stages{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line);
  grid-template-columns:repeat(auto-fit,minmax(232px,1fr))}
.pp-stage{background:var(--pp-bg);padding:clamp(22px,2.6vw,30px)}
.pp-stage .pp-k{font:700 10.5px/1 var(--pp-body);letter-spacing:.19em;text-transform:uppercase;
  color:var(--pp-ink3);margin:0 0 14px}
.pp-stage .pp-k b{color:var(--pp-acc-text);font-weight:700;margin-right:9px}
.pp-stage h4{font:600 clamp(27px,2.7vw,33px)/1 var(--pp-cond);margin:0 0 12px;color:var(--pp-ink)}
.pp-stage p{margin:0 0 14px;color:var(--pp-ink2);font-size:14.6px;line-height:1.6}
.pp-stage .pp-kick{margin:0;padding-top:13px;border-top:1px solid var(--pp-line);
  color:var(--pp-ink3);font-size:13px;line-height:1.55}

/* =========================================================================
   FACE

   Rows rather than cards. The client's note on the book diagram is the reason:
   each letter addresses one particular point in the Spiral, which is where the
   title comes from. Four separate cards say four tools. Four rows that start at
   a stage and end at a result say one system, and the rail that grows across
   the row on reveal is the join being drawn rather than claimed.
   ========================================================================= */
.pp-facetable{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line)}
.pp-rowhead{display:grid;grid-template-columns:186px 1fr 200px;background:var(--pp-bg2)}
.pp-rowhead span{padding:13px clamp(18px,2vw,26px);font:700 10px/1 var(--pp-body);
  letter-spacing:.19em;text-transform:uppercase;color:var(--pp-ink3)}
.pp-rowhead span+span{border-left:1px solid var(--pp-line)}
.pp-row{display:grid;grid-template-columns:186px 1fr 200px;background:var(--pp-bg)}
.pp-cell{padding:clamp(22px,2.4vw,28px) clamp(18px,2vw,26px)}
.pp-stagecell{position:relative;display:flex;align-items:center}
.pp-chip{position:relative;z-index:1;background:var(--pp-acc);color:var(--pp-acc-ink);
  font:700 10.5px/1 var(--pp-body);letter-spacing:.17em;text-transform:uppercase;padding:9px 13px}
/* Runs out from under the chip to the edge of the cell and stops at the letter
   it feeds. Anchored left so it grows in the direction the row is read. */
.pp-stagecell::after{content:"";position:absolute;left:clamp(18px,2vw,26px);right:0;top:50%;
  height:1px;background:var(--pp-acc);transform:scaleX(1);transform-origin:left center}
.js .pp-stagecell::after{transform:scaleX(0)}
.js .pp-row.in .pp-stagecell::after{transform:scaleX(1);
  transition:transform .85s cubic-bezier(.22,1,.36,1) .16s}
.pp-movecell{display:flex;gap:clamp(15px,1.8vw,21px);border-left:1px solid var(--pp-line)}
.pp-movecell .pp-letter{font:600 clamp(40px,4.4vw,54px)/.82 var(--pp-cond);color:var(--pp-acc);
  flex:none}
.pp-movecell h4{font-family:var(--pp-body);font-weight:700;font-size:17px;letter-spacing:.04em;
  margin:0 0 9px;color:var(--pp-ink)}
.pp-movecell p{margin:0 0 12px;color:var(--pp-ink2);font-size:14.6px;line-height:1.6}
.pp-movecell .pp-sci{margin:0;font:500 12.3px/1.55 var(--pp-body);color:var(--pp-ink3)}
.pp-resultcell{border-left:1px solid var(--pp-line);display:flex;flex-direction:column;
  justify-content:center}
.pp-resultcell b{font:600 clamp(23px,2.3vw,27px)/1 var(--pp-cond);color:var(--pp-ink);
  margin:0 0 9px}
.pp-resultcell span{color:var(--pp-ink3);font-size:13.4px;line-height:1.5}
@media(max-width:860px){
  .pp-rowhead{display:none}
  .pp-row{grid-template-columns:1fr}
  .pp-movecell,.pp-resultcell{border-left:0;border-top:1px solid var(--pp-line)}
  .pp-stagecell::after{display:none}
}

/* =========================================================================
   3D THINKING

   Two halves, because the idea has two. The lenses say what it is, the quadrant
   says where you are. The lenses start apart and close on reveal, which is the
   one thing the printed diagram cannot do and the exact thing the reader has to
   understand: the depth is in the overlap, and neither lens makes it alone.
   ========================================================================= */
.pp-3d{display:grid;gap:clamp(26px,3.2vw,44px);grid-template-columns:minmax(276px,.92fr) 1.08fr;
  align-items:start}
@media(max-width:900px){.pp-3d{grid-template-columns:1fr}}
.pp-lenssvg{display:block;width:100%;height:auto;margin:0 0 24px}
.pp-lensg circle{stroke-width:1.5}
.pp-lensg text{font:600 12px/1 var(--pp-body);letter-spacing:.03em}
.pp-lensg-a circle{fill:var(--pp-ink);fill-opacity:.07;stroke:var(--pp-ink3)}
.pp-lensg-a text{fill:var(--pp-ink2)}
.pp-lensg-b circle{fill:var(--pp-acc);fill-opacity:.13;stroke:var(--pp-acc)}
.pp-lensg-b text{fill:var(--pp-acc-text)}
.pp-lensdepth{font:600 16px/1 var(--pp-body);letter-spacing:.22em;fill:var(--pp-ink)}
.pp-lensdepth2{font:500 10.5px/1 var(--pp-body);letter-spacing:.14em;text-transform:uppercase;
  fill:var(--pp-ink3)}
.js .pp-lenses .pp-lensg-a{transform:translateX(-40px)}
.js .pp-lenses .pp-lensg-b{transform:translateX(40px)}
.js .pp-lenses .pp-lensdepth,.js .pp-lenses .pp-lensdepth2{opacity:0}
.js .pp-lenses.in .pp-lensg-a,.js .pp-lenses.in .pp-lensg-b{transform:none;
  transition:transform 1.1s cubic-bezier(.22,1,.36,1) .1s}
.js .pp-lenses.in .pp-lensdepth,.js .pp-lenses.in .pp-lensdepth2{opacity:1;
  transition:opacity .6s ease .95s}
.pp-lensrow{padding:16px 0;border-top:1px solid var(--pp-line)}
.pp-lensrow b{font:600 19px/1 var(--pp-cond);color:var(--pp-ink);margin-right:10px}
.pp-lensrow span{font:700 10px/1 var(--pp-body);letter-spacing:.18em;text-transform:uppercase;
  color:var(--pp-ink3)}
.pp-lensrow p{margin:9px 0 0;color:var(--pp-ink2);font-size:14.2px;line-height:1.6}

.pp-grid2{margin:0;display:grid;grid-template-columns:20px 1fr;gap:10px}
.pp-axisy{grid-column:1;grid-row:1;margin:0;place-self:center;writing-mode:vertical-rl;
  transform:rotate(180deg);font:700 10px/1 var(--pp-body);letter-spacing:.18em;
  text-transform:uppercase;color:var(--pp-ink3)}
.pp-quads{grid-column:2;grid-row:1;display:grid;grid-template-columns:1fr 1fr;gap:1px;
  background:var(--pp-line);border:1px solid var(--pp-line)}
.pp-axisx{grid-column:2;grid-row:2;margin:0;text-align:right;font:700 10px/1 var(--pp-body);
  letter-spacing:.18em;text-transform:uppercase;color:var(--pp-ink3)}
.pp-grid2 figcaption{grid-column:2;grid-row:3;margin:6px 0 0;color:var(--pp-ink3);
  font-size:13px;line-height:1.6}
.pp-quad{background:var(--pp-bg);padding:clamp(18px,2.1vw,25px)}
.pp-quad h4{font:600 clamp(21px,2.2vw,26px)/1 var(--pp-cond);margin:0 0 9px;color:var(--pp-ink)}
.pp-quad p{margin:0 0 10px;color:var(--pp-ink2);font-size:13.8px;line-height:1.55}
.pp-quad .pp-who{margin:0;color:var(--pp-ink3);font-size:12.6px;line-height:1.5}
/* The two by two stays two by two on a phone, because the shape is the
   argument. Two axes say both at full strength, and one column would say a
   list, which is the exact misreading the section exists to prevent. It pays
   for that with tighter type rather than with a dropped line. */
@media(max-width:560px){
  .pp-quad{padding:15px 13px}
  .pp-quad h4{font-size:19px;margin-bottom:7px}
  .pp-quad p{font-size:12.8px;line-height:1.5;margin-bottom:8px}
  .pp-quad .pp-who{font-size:11.8px}
}
.pp-quad-framers{position:relative;background:var(--pp-bg2)}
.pp-quad-framers h4{color:var(--pp-acc-text)}
.pp-quad-framers::after{content:"";position:absolute;inset:0;pointer-events:none;
  border:1px solid var(--pp-acc)}
@media(prefers-reduced-motion:no-preference){
  .js .pp-quad-framers.in::after{animation:pp-framer 3.4s ease-out 1s 2}
}
@keyframes pp-framer{0%,100%{box-shadow:0 0 0 0 transparent}
  35%{box-shadow:inset 0 0 26px -6px var(--pp-acc)}}

/* Reduced motion, declared after the three diagrams rather than up with the
   other reduced motion rules, because these have to outrank the wound-back
   states above them and same weight declared later is how that is won without
   an important. Nothing is hidden and nothing waits for a class: the reader who
   asks for stillness gets all three diagrams finished. */
@media(prefers-reduced-motion:reduce){
  .js .pp-spiral .pp-ringline{stroke-dashoffset:0}
  .js .pp-spiral .pp-node circle,.js .pp-spiral .pp-orbit circle{transform:none}
  .js .pp-spiral .pp-node text,.js .pp-spiral .pp-return{opacity:1}
  .js .pp-stagecell::after{transform:scaleX(1)}
  .js .pp-lenses .pp-lensg-a,.js .pp-lenses .pp-lensg-b{transform:none}
  .js .pp-lenses .pp-lensdepth,.js .pp-lenses .pp-lensdepth2{opacity:1}
  .pp-spiralsvg *,.pp-facetable *,.pp-stagecell::after,.pp-lenssvg *,.pp-quad-framers::after{
    transition:none !important;animation:none !important}
}

/* =========================================================================
   CHARTS
   ========================================================================= */
.pp-figs{display:grid;gap:clamp(22px,2.6vw,30px);grid-template-columns:repeat(auto-fit,minmax(360px,1fr))}
.pp-figs.one{grid-template-columns:1fr}
.pp-fig{background:var(--pp-bg);border:1px solid var(--pp-line2);
  padding:clamp(24px,2.8vw,34px);display:flex;flex-direction:column}
.pp-fig .pp-eye{margin-bottom:12px}
.pp-fig h3{font-family:var(--pp-body);font-weight:700;letter-spacing:-.01em;
  font-size:clamp(18px,2vw,22px);line-height:1.3;margin:0 0 12px;color:var(--pp-ink)}
.pp-fig .pp-figdek{margin:0 0 26px;color:var(--pp-ink2);font-size:14.6px;line-height:1.6}
.pp-fig .pp-axis{font:600 10.5px/1 var(--pp-body);letter-spacing:.14em;text-transform:uppercase;
  color:var(--pp-ink3);margin:0 0 18px}
/* Pinned to the bottom of the card so the provenance blocks line up across a
   row. The hairline makes that alignment read as an editorial footer rather
   than as a hole under the shorter chart. */
.pp-fig figcaption{margin:auto 0 0;padding-top:22px;border-top:1px solid var(--pp-line)}
.pp-cap{margin:0 0 12px;color:var(--pp-ink);font-size:14.6px;line-height:1.6;font-weight:500}
.pp-take{margin:0 0 14px;padding:14px 16px;background:var(--pp-acc-dim);border-left:3px solid var(--pp-acc);
  color:var(--pp-ink);font-size:14px;line-height:1.55}
.pp-n{margin:0 0 8px;font:400 12px/1.6 var(--pp-body);color:var(--pp-ink3)}
.pp-n b{color:var(--pp-ink2);font-weight:600}
.pp-cite{margin:0;font:400 11.5px/1.6 var(--pp-body);color:var(--pp-ink3)}
.pp-cite a{color:var(--pp-ink3);word-break:break-word}
.pp-callout{margin:20px 0 0;font:600 13px/1.55 var(--pp-body);color:var(--pp-ink)}
.pp-callout::before{content:"";display:inline-block;width:8px;height:8px;background:var(--pp-acc);
  margin-right:9px;vertical-align:1px}

/* bars */
.pp-bars{display:grid;gap:16px}
.pp-bar{display:grid;grid-template-columns:1fr;gap:7px}
.pp-bar .pp-barlab{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px}
.pp-bar .pp-barlab b{font:600 14px/1.3 var(--pp-body);color:var(--pp-ink)}
.pp-bar .pp-barlab i{font-style:normal;font:400 13px/1.3 var(--pp-body);color:var(--pp-ink3)}
.pp-bar .pp-barlab em{font-style:normal;margin-left:auto;font:600 16px/1 var(--pp-body);letter-spacing:-.01em;
  font-size:21px;color:var(--pp-ink);font-variant-numeric:tabular-nums}
.pp-bar .pp-track{height:13px;background:var(--pp-bg3);border:1px solid var(--pp-line);position:relative;overflow:hidden}
.pp-bar i.pp-fill{position:absolute;inset:0 auto 0 0;width:0;background:var(--pp-ink3);
  transition:width 1.05s cubic-bezier(.2,.75,.25,1)}
.pp-bar.hl i.pp-fill{background:var(--pp-acc)}
.pp-bar.approx i.pp-fill{background-image:repeating-linear-gradient(115deg,rgba(0,0,0,.22) 0 5px,transparent 5px 11px)}
.pp-bar .pp-barnote{font:400 12px/1.4 var(--pp-body);color:var(--pp-ink3)}

/* range band */
.pp-rangewrap{padding:8px 0 0}
.pp-range{position:relative;height:58px;background:var(--pp-bg3);border:1px solid var(--pp-line)}
.pp-range i.pp-bandfill{position:absolute;top:0;bottom:0;background:var(--pp-acc-dim);
  border-left:2px solid var(--pp-acc);border-right:2px solid var(--pp-acc);
  transform:scaleX(0);transform-origin:left;transition:transform 1s cubic-bezier(.2,.75,.25,1)}
.pp-range i.pp-mid{position:absolute;top:0;bottom:0;width:3px;background:var(--pp-acc);opacity:0;
  transition:opacity .5s .7s}
.pp-range i.pp-mark{position:absolute;top:0;bottom:0;width:1px;background:var(--pp-ink3);
  border-left:1px dashed var(--pp-ink3);opacity:.7}
.pp-range .pp-midlab{position:absolute;top:8px;transform:translateX(-50%);white-space:nowrap;
  font:700 12px/1 var(--pp-body);letter-spacing:.06em;text-transform:uppercase;color:var(--pp-ink);
  background:var(--pp-bg);padding:4px 8px;border:1px solid var(--pp-acc)}
.pp-range .pp-marklab{position:absolute;bottom:7px;transform:translateX(-50%);white-space:nowrap;
  font:500 11px/1 var(--pp-body);color:var(--pp-ink3)}
.pp-rangeends{display:flex;justify-content:space-between;margin-top:9px;
  font:600 11.5px/1 var(--pp-body);color:var(--pp-ink2);font-variant-numeric:tabular-nums}

/* donut */
.pp-ringwrap{display:flex;flex-wrap:wrap;gap:clamp(20px,3vw,38px);align-items:center}
.pp-ring{width:clamp(150px,20vw,208px);height:clamp(150px,20vw,208px);flex:none;transform:rotate(-90deg)}
.pp-ring circle{fill:none;stroke-width:18;transition:stroke-dasharray 1.1s cubic-bezier(.2,.75,.25,1)}
.pp-ringkey{display:grid;gap:14px;min-width:180px;flex:1}
.pp-ringkey div{display:grid;grid-template-columns:14px 1fr auto;gap:12px;align-items:center}
.pp-ringkey i{width:14px;height:14px;display:block}
.pp-ringkey b{font:600 14px/1.3 var(--pp-body);color:var(--pp-ink)}
.pp-ringkey em{font-style:normal;font:300 26px/1 var(--pp-body);letter-spacing:-.02em;color:var(--pp-ink);font-variant-numeric:tabular-nums}

/* hero number */
.pp-heronum{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin:0 0 24px;
  padding:0 0 24px;border-bottom:1px solid var(--pp-line)}
.pp-heronum b{font:300 clamp(68px,11vw,128px)/.86 var(--pp-body);color:var(--pp-acc);
  font-variant-numeric:tabular-nums;letter-spacing:-.035em}
.pp-heronum span{font:700 clamp(14px,1.6vw,18px)/1.2 var(--pp-body);
  letter-spacing:.06em;color:var(--pp-ink2);max-width:9ch}
.pp-rows{margin:0;display:grid;gap:0}
.pp-rows div{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:baseline;
  padding:13px 0;border-bottom:1px solid var(--pp-line)}
.pp-rows dt{font:500 14px/1.5 var(--pp-body);color:var(--pp-ink2);margin:0}
.pp-rows dd{margin:0;font:600 14px/1.5 var(--pp-body);color:var(--pp-ink);text-align:right}

/* the small paired table under a chart */
.pp-extra{margin:24px 0 0;padding:20px;background:var(--pp-bg3);border:1px solid var(--pp-line)}
.pp-extra,.pp-branch,.pp-range,.pp-rangewrap{--pp-ink3:var(--pp-ink2);--pp-acc-text:var(--pp-ink)}
.pp-extra h5{margin:0 0 14px;font:700 10.5px/1 var(--pp-body);letter-spacing:.18em;
  text-transform:uppercase;color:var(--pp-acc-text)}
.pp-extra dl{margin:0;display:grid;gap:0}
.pp-extra div{display:grid;grid-template-columns:1fr auto;gap:14px;padding:9px 0;border-bottom:1px solid var(--pp-line)}
.pp-extra div:last-child{border-bottom:0}
.pp-extra dt{margin:0;font-size:13px;line-height:1.5;color:var(--pp-ink2)}
.pp-extra dd{margin:0;font:600 15px/1.4 var(--pp-body);font-size:16px;color:var(--pp-ink);
  font-variant-numeric:tabular-nums}
.pp-extra .pp-extranote{margin:12px 0 0;font:400 12px/1.55 var(--pp-body);color:var(--pp-ink3)}

/* =========================================================================
   THE CASCADE
   ========================================================================= */
.pp-chain{display:grid;gap:0;counter-reset:pp-link}
.pp-link{display:grid;grid-template-columns:64px 1fr;gap:clamp(16px,2.4vw,28px);position:relative;
  padding:0 0 clamp(18px,2.4vw,26px)}
.pp-link .pp-node{position:relative;display:flex;flex-direction:column;align-items:center}
.pp-link .pp-num{width:44px;height:44px;flex:none;border:1px solid var(--pp-line2);border-radius:50%;
  display:grid;place-items:center;background:var(--pp-bg);z-index:2;
  font:600 15px/1 var(--pp-body);font-size:16px;color:var(--pp-ink2);transition:border-color .4s,color .4s,background .4s}
.pp-link.in .pp-num{border-color:var(--pp-acc-text);color:var(--pp-acc-text)}
.pp-link .pp-chain-line{flex:1;width:1px;background:var(--pp-line);position:relative;margin-top:-2px}
.pp-link .pp-chain-line i{position:absolute;inset:0 0 auto 0;width:1px;height:0;background:var(--pp-acc);
  transition:height .5s linear}
.pp-link.in .pp-chain-line i{height:100%}
.pp-link:last-child .pp-chain-line{display:none}
.pp-link .pp-body{padding-bottom:6px}
.pp-link .pp-k{font:700 10.5px/1 var(--pp-body);letter-spacing:.19em;text-transform:uppercase;
  color:var(--pp-acc-text);margin:0 0 8px;display:block;padding-top:13px}
.pp-link .pp-t{font:600 clamp(16px,1.9vw,20px)/1.4 var(--pp-body);color:var(--pp-ink);margin:0 0 8px}
.pp-link .pp-c{font:400 12.8px/1.6 var(--pp-body);color:var(--pp-ink3);margin:0;max-width:64ch}

.pp-branch{margin:0 0 clamp(18px,2.4vw,26px) 84px;padding:16px 20px;border:1px dashed var(--pp-line2);
  background:var(--pp-bg3);position:relative}
.pp-branch::before{content:"";position:absolute;left:-20px;top:26px;width:20px;height:1px;background:var(--pp-line2)}
.pp-branch .pp-k{color:var(--pp-ink2);padding-top:0}
.pp-lever{margin:clamp(22px,3vw,34px) 0 0;padding:clamp(20px,2.6vw,28px);
  border:1px solid var(--pp-acc);background:var(--pp-acc-dim)}
.pp-lever .pp-k{color:var(--pp-acc-text);padding-top:0}
.pp-lever .pp-note{margin:14px 0 0;font-size:13.6px;line-height:1.65;color:var(--pp-ink2)}
.pp-chainfoot{margin:clamp(24px,3vw,34px) 0 0;padding-top:20px;border-top:1px solid var(--pp-line);
  font:500 14px/1.65 var(--pp-body);color:var(--pp-ink2);max-width:70ch}

/* breathing dial */
.pp-breath{display:grid;gap:clamp(24px,3vw,40px);grid-template-columns:repeat(auto-fit,minmax(320px,1fr));align-items:start}
.pp-beats{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 26px}
.pp-beats div{flex:1 1 90px;border:1px solid var(--pp-line2);padding:16px 14px;text-align:center;background:var(--pp-bg)}
.pp-beats b{display:block;font:300 36px/1 var(--pp-body);letter-spacing:-.02em;color:var(--pp-acc);margin-bottom:7px}
.pp-beats span{font:600 10.5px/1.4 var(--pp-body);letter-spacing:.12em;text-transform:uppercase;
  color:var(--pp-ink2)}
/* Only one label is allowed to float over this axis, and it is the marker. The
   band caption used to be positioned too, at a hardcoded 50% that had nothing to
   do with where the band actually was, so it ran straight through the rectangle
   it was describing and collided with the marker. It is a block level key now,
   under the axis, where it cannot hit anything. */
.pp-scaleline{position:relative;height:56px;border-bottom:1px solid var(--pp-line2);margin:40px 0 0}
.pp-scaleline i.pp-resband{position:absolute;bottom:0;top:14px;background:var(--pp-acc-dim);
  border:1px solid var(--pp-acc);transform:scaleX(0);transform-origin:left;
  transition:transform .9s cubic-bezier(.2,.75,.25,1)}
.pp-scaleline i.pp-at{position:absolute;bottom:-5px;width:11px;height:11px;border-radius:50%;
  background:var(--pp-acc);transform:translateX(-50%) scale(0);transition:transform .5s .7s cubic-bezier(.2,.8,.3,1.4)}
.pp-scaleline .pp-atlab{position:absolute;top:-14px;transform:translateX(-50%);white-space:nowrap;
  font:700 11.5px/1 var(--pp-body);letter-spacing:.08em;text-transform:uppercase;color:var(--pp-ink);
  background:var(--pp-bg);padding:5px 9px;border:1px solid var(--pp-acc)}
.pp-scaleends{display:flex;justify-content:space-between;margin-top:9px;
  font:600 10.5px/1 var(--pp-body);letter-spacing:.11em;text-transform:uppercase;color:var(--pp-ink3)}
.pp-bandkey{display:flex;gap:11px;align-items:flex-start;margin:20px 0 0;
  font:400 13px/1.55 var(--pp-body);color:var(--pp-ink2)}
.pp-bandkey i{flex:0 0 auto;width:22px;height:13px;margin-top:3px;background:var(--pp-acc-dim);
  border:1px solid var(--pp-acc)}

/* stacked evidence rows: a term, then a sentence under it */
.pp-evhead{margin:0 0 4px;font:700 10.5px/1 var(--pp-body);letter-spacing:.18em;
  text-transform:uppercase;color:var(--pp-acc-text)}
.pp-evrows{margin:0;display:grid}
.pp-evrows div{padding:15px 0;border-bottom:1px solid var(--pp-line)}
.pp-evrows dt{margin:0 0 5px;font:600 14px/1.45 var(--pp-body);color:var(--pp-ink)}
.pp-evrows dd{margin:0;font:400 13.5px/1.6 var(--pp-body);color:var(--pp-ink2)}

/* the naming circuit */
.pp-circuit{display:grid;gap:0;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  border:1px solid var(--pp-line);background:var(--pp-line);gap:1px}
.pp-circuit div{background:var(--pp-bg);padding:clamp(20px,2.4vw,26px);position:relative}
.pp-circuit b{display:block;font:700 10.5px/1 var(--pp-body);letter-spacing:.19em;text-transform:uppercase;
  color:var(--pp-acc-text);margin:0 0 12px}
.pp-circuit p{margin:0;font:600 15.5px/1.45 var(--pp-body);color:var(--pp-ink)}

/* =========================================================================
   ON THE RECORD
   ========================================================================= */
.pp-chips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 clamp(24px,3vw,34px)}
.pp-chips button{appearance:none;cursor:pointer;background:transparent;border:1px solid var(--pp-line2);
  color:var(--pp-ink2);padding:14px 18px;min-height:44px;font:600 11.5px/1 var(--pp-body);letter-spacing:.12em;
  text-transform:uppercase;transition:background .16s,color .16s,border-color .16s}
.pp-chips button:hover{border-color:var(--pp-ink3);color:var(--pp-ink)}
.pp-chips button.on{background:var(--pp-acc);border-color:var(--pp-acc);color:var(--pp-acc-ink)}
.pp-chips button i{font-style:normal;opacity:.55;margin-left:2px;font-variant-numeric:tabular-nums}
/* Dense packing. The five feature quotes each span two columns, and without
   dense they run consecutively and leave a column of holes down the right.
   Dense pulls a standard quote up beside each feature instead. */
.pp-quotes{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line);
  grid-auto-flow:row dense;grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.pp-q{background:var(--pp-bg);padding:clamp(24px,2.8vw,32px);display:flex;flex-direction:column;
  transition:opacity .25s,transform .25s}
.pp-q[hidden]{display:none}
.pp-q.wide{grid-column:span 2}
@media(max-width:760px){.pp-q.wide{grid-column:span 1}}
.pp-q blockquote{margin:0 0 20px;flex:1}
.pp-q q{quotes:'\201C' '\201D';color:var(--pp-ink);font-size:15.4px;line-height:1.62}
.pp-q.wide q{font-size:17.6px;line-height:1.56;font-weight:500}
.pp-q cite{font-style:normal;display:block;padding-top:16px;border-top:1px solid var(--pp-line)}
.pp-q cite b{display:block;font:700 13px/1.3 var(--pp-body);letter-spacing:.06em;text-transform:uppercase;
  color:var(--pp-ink)}
.pp-q cite span{display:block;margin-top:6px;font:400 12.6px/1.5 var(--pp-body);color:var(--pp-ink3)}
.pp-q .pp-dtag{font:700 10.5px/1 var(--pp-body);letter-spacing:.16em;text-transform:uppercase;
  color:var(--pp-acc-text);margin:0 0 16px}

/* =========================================================================
   TIMELINE
   ========================================================================= */
.pp-time{display:grid;gap:0;border-top:1px solid var(--pp-line)}
.pp-time>div{display:grid;grid-template-columns:76px 116px 1fr;gap:clamp(14px,2vw,26px);
  padding:16px 0;border-bottom:1px solid var(--pp-line);align-items:baseline}
.pp-time .pp-yr{font:600 19px/1 var(--pp-body);letter-spacing:-.01em;color:var(--pp-acc-text);font-variant-numeric:tabular-nums}
.pp-time .pp-kk{font:700 10.5px/1.3 var(--pp-body);letter-spacing:.15em;text-transform:uppercase;color:var(--pp-ink3)}
.pp-time .pp-tt{color:var(--pp-ink2);font-size:14.6px;line-height:1.55}
.pp-time .pp-tt b{color:var(--pp-ink);font-weight:600;display:block;margin-bottom:3px;
  font-family:var(--pp-body);font-size:16px;letter-spacing:0}
@media(max-width:700px){
  .pp-time>div{grid-template-columns:60px 1fr;gap:14px}
  .pp-time .pp-kk{grid-column:2;margin-bottom:-8px}
}

/* =========================================================================
   BIO
   ========================================================================= */
.pp-bio{display:grid;grid-template-columns:minmax(0,300px) 1fr;gap:clamp(26px,4vw,54px);align-items:start}
.pp-bio img{display:block;width:100%;height:auto;border:1px solid var(--pp-line)}
.pp-bio .pp-biobody p{color:var(--pp-ink2);font-size:16.2px;line-height:1.7;margin:0 0 16px;max-width:60ch}
.pp-bio .pp-biobody p b{color:var(--pp-ink);font-weight:600}
/* Grid so the numbers hold a column when the row wraps. Wrapped flex items
   size to their own content and the second row lands ragged. */
.pp-biostats{display:grid;gap:18px 26px;grid-template-columns:repeat(auto-fit,minmax(108px,1fr));
  margin:26px 0 0;padding-top:22px;border-top:1px solid var(--pp-line)}
.pp-biostats div{font:600 10.5px/1.35 var(--pp-body);letter-spacing:.14em;text-transform:uppercase;color:var(--pp-ink3)}
.pp-biostats div b{display:block;font:300 30px/1 var(--pp-body);letter-spacing:-.02em;color:var(--pp-ink);margin-bottom:4px}

/* =========================================================================
   NOTES AND DISCLOSURE
   ========================================================================= */
.pp-disc{display:grid;gap:14px}
.pp-disc p{margin:0 auto;font:400 12.4px/1.65 var(--pp-body);color:var(--pp-ink3);max-width:78ch}
.pp-drop{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line)}
.pp-drop div{background:var(--pp-bg);padding:20px 22px}
.pp-drop b{display:block;font:700 13px/1.3 var(--pp-body);letter-spacing:.04em;color:var(--pp-ink);margin:0 0 8px}
.pp-drop p{margin:0;font:400 13.4px/1.6 var(--pp-body);color:var(--pp-ink3)}

/* =========================================================================
   CLAIM PATH. Step 3 of the funnel: three steps, the presale checkout, and
   the two buttons. Free plus shipping fulfilled direct, so the form has to
   carry a shipping address and the decline has to go somewhere.
   ========================================================================= */
/* The final 3D hardcover render (PRH, 3 Sep 2026) above the checkout steps. */
.pp-bookshot{display:block;width:clamp(300px,34vw,440px);margin:clamp(18px,2.4vw,28px) auto 0}
.pp-bookshot img{display:block;width:100%;height:auto}
.pp-steps{margin:clamp(26px,3.4vw,40px) 0;padding:0;list-style:none;display:grid;
  grid-template-columns:repeat(3,1fr);gap:1px;background:var(--pp-line);border:1px solid var(--pp-line);
  counter-reset:step}
.pp-steps li{background:var(--pp-bg);padding:clamp(20px,2.6vw,30px);counter-increment:step}
.pp-steps li::before{content:counter(step);display:grid;place-items:center;width:40px;height:40px;
  border-radius:50%;border:1px solid var(--pp-em,var(--pp-acc));color:var(--pp-em,var(--pp-acc));
  font:300 19px/1 var(--pp-body);margin-bottom:14px}
.pp-steps b{display:block;font:700 14.5px/1.3 var(--pp-body);color:var(--pp-ink);margin:0 0 8px}
.pp-steps p{margin:0;font:400 13.8px/1.6 var(--pp-body);color:var(--pp-ink2)}
.pp-redeem{display:grid;grid-template-columns:1fr 1fr;gap:14px;max-width:720px}
.pp-redeem label{display:grid;gap:7px;font:600 11px/1 var(--pp-body);letter-spacing:.12em;
  text-transform:uppercase;color:var(--pp-ink3)}
.pp-redeem input{background:var(--pp-bg);border:1px solid var(--pp-line2);color:var(--pp-ink);
  font:500 15.5px/1 var(--pp-body);padding:15px 14px;border-radius:8px;width:100%;min-width:0}
.pp-redeem input:focus{outline:2px solid var(--pp-acc);outline-offset:1px}
.pp-redeem .full{grid-column:1/-1}
.pp-redeem .pp-consent{grid-column:1/-1;display:grid;grid-template-columns:18px 1fr;gap:11px;
  align-items:start;font:400 13px/1.55 var(--pp-body);letter-spacing:0;text-transform:none;
  color:var(--pp-ink2)}
.pp-redeem .pp-consent input{width:16px;height:16px;padding:0;margin-top:2px;accent-color:var(--pp-acc)}
.pp-redeem .btn{grid-column:1/-1;justify-self:start}

/* The optional bump. Boxed rather than bare, because it is the only checkbox
   on the form that costs money and it must not read like the consent line. */
.pp-redeem .pp-bump{grid-column:1/-1;display:grid;grid-template-columns:18px 1fr;gap:11px;
  align-items:start;font:400 13.6px/1.55 var(--pp-body);letter-spacing:0;text-transform:none;
  color:var(--pp-ink2);border:1px solid var(--pp-line2);border-radius:8px;
  background:var(--pp-bg2);padding:14px 16px}
.pp-redeem .pp-bump input{width:16px;height:16px;padding:0;margin-top:2px;accent-color:var(--pp-acc)}
.pp-redeem .pp-bump b{color:var(--pp-ink)}

/* The two-button choice. Green buys, red declines and routes to the six week
   intensive presentation rather than dead-ending. Both are visibly buttons,
   because a decline styled as a link is a decline that leaks off the page. */
.choice{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin:8px 0 0}
.pp-redeem .choice{grid-column:1/-1}
.choice .btn.yes{background:#0f7a48;border-color:#0f7a48;color:#fff}
.choice .btn.yes:hover{background:#0b5f37;border-color:#0b5f37;color:#fff}
.choice .btn.no{background:transparent;color:var(--pp-ink3);border:1px solid var(--pp-line2);
  font-weight:600}
.choice .btn.no:hover{color:var(--pp-ink);border-color:var(--pp-ink3);background:transparent}

/* =========================================================================
   FAQ. Native details/summary, no script.
   ========================================================================= */
.pp-faqs{display:grid;gap:1px;background:var(--pp-line);border:1px solid var(--pp-line)}
.pp-faq{background:var(--pp-bg)}
.pp-faq summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:18px;
  align-items:center;padding:clamp(18px,2.2vw,24px) clamp(18px,2.4vw,26px);
  font:700 15.5px/1.4 var(--pp-body);color:var(--pp-ink)}
.pp-faq summary::-webkit-details-marker{display:none}
.pp-faq summary::after{content:"+";flex:0 0 auto;width:28px;height:28px;display:grid;place-items:center;
  border:1px solid var(--pp-line2);border-radius:50%;color:var(--pp-em,var(--pp-acc));
  font:300 19px/1 var(--pp-body);transition:transform .18s}
.pp-faq[open] summary::after{transform:rotate(45deg)}
.pp-faq p{margin:0;padding:0 clamp(18px,2.4vw,26px) clamp(18px,2.2vw,24px);
  font:400 14.6px/1.7 var(--pp-body);color:var(--pp-ink2);max-width:62ch}

/* =========================================================================
   WHAT YOU GET. The named artifacts under the opt-in form.
   ========================================================================= */
.pp-get{margin:18px 0 0;padding:0;list-style:none;display:grid;gap:9px;max-width:52ch}
.pp-get li{display:grid;grid-template-columns:15px 1fr;gap:10px;
  font:400 14.2px/1.55 var(--pp-body);color:var(--pp-ink2)}
.pp-get li::before{content:"";width:7px;height:7px;border-radius:50%;
  background:var(--pp-em,var(--pp-acc));margin-top:6px}
.pp-get li b{color:var(--pp-ink);font-weight:600}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media(max-width:880px){
  .pp-cover{grid-template-columns:1fr}
  .pp-cover figure{max-width:280px}
  .pp-bio{grid-template-columns:1fr}
  .pp-bio figure{max-width:260px;margin:0}
  .pp-link{grid-template-columns:48px 1fr}
  .pp-link .pp-num{width:38px;height:38px;font-size:15px}
  .pp-branch{margin-left:62px}
}
@media(max-width:560px){
  .pp-steps{grid-template-columns:1fr}
  .pp-redeem{grid-template-columns:1fr}
  .pp-heronum{gap:10px}
  .pp-rows div{grid-template-columns:1fr;gap:2px}
  .pp-rows dd{text-align:left}
  .pp-extra div{grid-template-columns:1fr;gap:2px}
}
/* =========================================================================
   PHONE BLEED. The tiled modules are boxes drawn in hairlines: on a phone a
   box inside a 20px gutter reads as a box inside a box, and every hairline
   costs content width the cells then pay for in padding. So the tiled modules
   run to the screen edges, their own cell padding becomes the gutter, and the
   side hairlines go, since a line on the physical edge of a screen is not
   drawing anything. The 2x2 mindframe grid is the exception: its axis labels
   need the margin they sit in, so it keeps the gutter. Section rhythm also
   tightens, since 56px of air on an 812px screen is a fifteenth of the
   viewport spent twice between every pair of sections.
   ========================================================================= */
@media(max-width:640px){
  .pp-sec{padding:48px 0}
  .pp-statgrid,.pp-facetable,.pp-quotes,.pp-faqs,.pp-steps,.pp-stages{
    margin-left:calc(-1*var(--pp-gut));margin-right:calc(-1*var(--pp-gut));
    border-left:0;border-right:0}
  .pp-spiral{max-width:none;
    margin-left:calc(-1*var(--pp-gut));margin-right:calc(-1*var(--pp-gut))}
}
@media print{
  .js .pp-r{opacity:1;transform:none}
  .pp-fig{break-inside:avoid}
}
