/* A public profile, /@handle (api/profile.js): the app's PublicProfileView for another player, as a
   page. Every size here is the app's own (1.0.6), so the page and the screen look the same:
   - the hero: ProfileHero (ProfileComponents.swift), 152 high, or 228 with a backdrop or banner;
   - the headings and the Favourite Four row: ProfileSectionHeading and PublicProfileView;
   - the cartridges: GameCartridgeArtwork (CoverTile.swift), the flat 62 × 81 shell every profile
     row draws, sized in em so one em is its unit (the shell's width / 62);
   - the Stacks: StackStripCard and StackArtworkStrip; the reviews: ProfilePublicReviewCard and
     RatingStars; the chart: ProfileRatingsView.
   Line boxes are Urbanist's own, 1.2 em. SwiftUI's lineSpacing adds space only between lines, so
   a paragraph with it takes half of it back above and below. */

.pp-page {
  --pp-line: #262A31;
  --pp-raised: #1E2127;
  --pp-shell: #454A54;
  --pp-matte: #111318;
  /* The cartridges' skin, classic until the owner wears another: the ink tints the grips, the groove
     and the foot's bar, the rim is the shell's edge, and the board shows through a see-through shell. */
  --pp-ink: #000;
  --pp-rim: rgba(255, 255, 255, .05);
  --pp-board: none;
}

/* The owner's skin (the body's data-skin), the app's flat palettes (CartridgeKit's CartridgeSkin.flat):
   every cartridge on the page wears it. Translucent Purple, Green and Clear show the board through. */
.pp-page[data-skin="cyan"]   { --pp-shell:#3DB6D4; --pp-ink:#083A47; --pp-rim:rgba(255,255,255,.22); }
.pp-page[data-skin="silver"] { --pp-shell:#B2B8C1; --pp-ink:#2A2F36; --pp-rim:rgba(255,255,255,.40); }
.pp-page[data-skin="gold"]   { --pp-shell:#D2A138; --pp-ink:#4A3006; --pp-rim:rgba(255,241,200,.35); }
.pp-page[data-skin="purple"] { --pp-shell:rgba(169,138,238,.8); --pp-ink:#2C1360; --pp-rim:rgba(255,255,255,.38); --pp-board:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 62 81'%3E%3Crect x='5' y='2.4' width='52' height='77' rx='1.2' fill='%232C7A5A'/%3E%3Crect x='11.6' y='4.4' width='9' height='5.6' rx='.6' fill='%2315171B'/%3E%3Ccircle cx='45' cy='8.2' r='4.6' fill='%23B9C0C8'/%3E%3Cg fill='%23E0B24A'%3E%3Crect x='11.2' y='78.3' width='3' height='2.4'/%3E%3Crect x='15.3' y='78.3' width='3' height='2.4'/%3E%3Crect x='19.4' y='78.3' width='3' height='2.4'/%3E%3Crect x='23.5' y='78.3' width='3' height='2.4'/%3E%3Crect x='27.6' y='78.3' width='3' height='2.4'/%3E%3Crect x='31.7' y='78.3' width='3' height='2.4'/%3E%3Crect x='35.8' y='78.3' width='3' height='2.4'/%3E%3Crect x='39.9' y='78.3' width='3' height='2.4'/%3E%3Crect x='44' y='78.3' width='3' height='2.4'/%3E%3Crect x='48.1' y='78.3' width='3' height='2.4'/%3E%3C/g%3E%3C/svg%3E"); }
.pp-page[data-skin="green"]  { --pp-shell:rgba(123,215,169,.8); --pp-ink:#0B3D25; --pp-rim:rgba(255,255,255,.38); --pp-board:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 62 81'%3E%3Crect x='5' y='2.4' width='52' height='77' rx='1.2' fill='%232C7A5A'/%3E%3Crect x='11.6' y='4.4' width='9' height='5.6' rx='.6' fill='%2315171B'/%3E%3Ccircle cx='45' cy='8.2' r='4.6' fill='%23B9C0C8'/%3E%3Cg fill='%23E0B24A'%3E%3Crect x='11.2' y='78.3' width='3' height='2.4'/%3E%3Crect x='15.3' y='78.3' width='3' height='2.4'/%3E%3Crect x='19.4' y='78.3' width='3' height='2.4'/%3E%3Crect x='23.5' y='78.3' width='3' height='2.4'/%3E%3Crect x='27.6' y='78.3' width='3' height='2.4'/%3E%3Crect x='31.7' y='78.3' width='3' height='2.4'/%3E%3Crect x='35.8' y='78.3' width='3' height='2.4'/%3E%3Crect x='39.9' y='78.3' width='3' height='2.4'/%3E%3Crect x='44' y='78.3' width='3' height='2.4'/%3E%3Crect x='48.1' y='78.3' width='3' height='2.4'/%3E%3C/g%3E%3C/svg%3E"); }
.pp-page[data-skin="clear"]  { --pp-shell:rgba(230,240,255,.12); --pp-ink:#0E0F12; --pp-rim:rgba(255,255,255,.6); --pp-board:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 62 81'%3E%3Crect x='5' y='2.4' width='52' height='77' rx='1.2' fill='%232C7A5A'/%3E%3Crect x='11.6' y='4.4' width='9' height='5.6' rx='.6' fill='%2315171B'/%3E%3Ccircle cx='45' cy='8.2' r='4.6' fill='%23B9C0C8'/%3E%3Cg fill='%23E0B24A'%3E%3Crect x='11.2' y='78.3' width='3' height='2.4'/%3E%3Crect x='15.3' y='78.3' width='3' height='2.4'/%3E%3Crect x='19.4' y='78.3' width='3' height='2.4'/%3E%3Crect x='23.5' y='78.3' width='3' height='2.4'/%3E%3Crect x='27.6' y='78.3' width='3' height='2.4'/%3E%3Crect x='31.7' y='78.3' width='3' height='2.4'/%3E%3Crect x='35.8' y='78.3' width='3' height='2.4'/%3E%3Crect x='39.9' y='78.3' width='3' height='2.4'/%3E%3Crect x='44' y='78.3' width='3' height='2.4'/%3E%3Crect x='48.1' y='78.3' width='3' height='2.4'/%3E%3C/g%3E%3C/svg%3E"); }

/* The app's screen is a phone's width: on a wider window it is a centred column of the same. */
.pp-col {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding-bottom: 38px;
  container-type: inline-size;
}

/* ── The hero ──────────────────────────────────────────────────────────────── */

/* A backdrop game or a banner: the tall hero, 228 high, under a fade to the page. */
.pp-art {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 228px;
  overflow: hidden;
}
/* The game's cover at the column's width, 3:4, filled, lifted by 30% of the width. */
.pp-backdrop {
  position: absolute;
  top: calc(min(100vw, 480px) * -.3);
  top: -30cqw;
  left: 0;
  width: 100%;
  max-width: none;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--surface);
}
/* An uploaded banner: the photo filling the hero, on the raised fill the app shows until it arrives. */
.pp-art.is-banner { background: var(--pp-raised); }
.pp-banner {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  object-fit: cover;
}
.pp-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(14, 15, 18, .3) 0%, rgba(14, 15, 18, .15) 30%, rgba(14, 15, 18, .92) 80%, #0E0F12 100%);
}

/* The hero's top row, 44 high, 8 under its top: the app's Back, here the site's way home. In the
   short hero the app's row sits 2 higher, its 156 of content centred in 152. */
.pp-top {
  position: relative;
  display: flex;
  align-items: center;
  height: 44px;
  margin-top: 6px;
  padding: 0 24px;
}
.has-art .pp-top { margin-top: 8px; }
.pp-top .brand { gap: 9px; }
.pp-top .brand svg { width: 32px; height: 32px; }
.pp-top .brand-word { font-size: 20px; }

.pp { position: relative; }

/* The avatar and, where the app has Follow, the pill: 20 under the top row, or at the foot of the
   tall hero. */
.pp-hero-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
  padding: 0 24px;
}
.has-art .pp-hero-row { margin-top: 92px; }

/* ProfileAvatarView: 84 across, the raised fill, the initial at 40% in the accent, the photo filling
   the circle over it once it arrives, and over both a ring of the page's colour and a 1-point line. */
.pp-avatar {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--pp-raised);
  color: var(--accent);
  font-size: 33.6px;
  line-height: 1.2;
  font-weight: 800;
}
.pp-avatar-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  object-fit: cover;
}
.pp-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--pp-line), inset 0 0 0 3px var(--bg);
}

/* FollowButton's pill: 44 high, 18 to the sides, 14/800, 5 above the avatar's foot. */
.pp-get {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 44px;
  margin-bottom: 5px;
  padding: 0 18px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 800;
  white-space: nowrap;
}
.pp-get svg { flex: none; width: 16px; height: 16px; margin-top: -2px; }
.pp-get:hover,
.pp-get:focus-visible { color: var(--accent-ink); background: #86e5f7; }

/* The name, 14 under the hero (12 under the short hero's avatar, which hangs 2 below it), the
   handle 3 under it, the bio 7 more. */
.pp-id {
  margin-top: 12px;
  padding: 0 24px;
  container-type: inline-size;
}
.has-art .pp-id { margin-top: 14px; }

/* Always one line (owner, 30 Sep 2026): 26 points, shrinking with the name's length so it fits the
   column, down to 40%. It never wraps and is never cut. The page's script measures it exactly. */
.pp-name {
  margin: 0;
  font-size: clamp(10.4px, calc(100cqw / (var(--chars, 1) * .58)), 26px);
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: 0;
  white-space: nowrap;
  color: var(--text);
}
.pp-handle {
  margin: 3px 0 0;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
/* The rank line, 4 under the handle: the small seal, 6 from one run of text, the rank in gold and
   " · 22 clears" in meta (so a word space stands either side of the "·", as in the app's one Text).
   13.5/700, always one line. */
.pp-rank {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  font: 700 13.5px/1.2 Urbanist, system-ui, sans-serif;
  color: var(--muted);
  white-space: nowrap;
}
.pp-rank-name { color: #E9B949; }
/* The small seal, tilted as the app tilts it. */
.pp-seal-s { width: 16px; height: 16px; transform: rotate(-12deg); flex: none; }
.pp-bio {
  margin: 8.5px 0 -1.5px;
  font-size: 14.5px;
  line-height: calc(1.2em + 3px);
  font-weight: 600;
  color: rgba(242, 243, 245, .82);
  overflow-wrap: anywhere;
}
/* iOS sets a 14.5-point font on a 3x screen's pixel grid, at 14⅔ (measured: the bio's lines are that
   much wider in the app, every whole-point size matches exactly), so its lines break where the
   app's do. */
@media (min-resolution: 3dppx) {
  .pp-bio { font-size: 14.6667px; margin-top: 8.4px; }
}

/* The head's cartridge (/skin-cart.js): the latest clear on the real Ridgeback, sealed, in the
   owner's skin. The element fills this host and draws the cartridge 236 high, centred across it and
   150 down, so the host holds it whole as it floats: never cropped. Under the name on a phone, beside
   it on a wider window (below). Without scripts, the sealed flat tile (below); the
   host is a flow root so the tile's top margin stays inside it rather than collapsing through it. */
.pp-head-cart {
  display: flow-root;
  width: 100%;
  height: 300px;
  margin-top: 8px;
}

/* ProfileConnectionsCounts: 8 under the hero, 18 apart, each 44 high. */
.pp-connections {
  display: flex;
  gap: 18px;
  margin: 8px 0 0;
  padding: 0 24px;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
.pp-connections span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  white-space: nowrap;
}
.pp-connections b { font-weight: 800; color: var(--text); }

/* ── The sections, 32 apart ─────────────────────────────────────────────────── */

.pp-sections {
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: 32px 24px 0;
}
.pp-section { min-width: 0; }

/* ProfileSectionHeading: 19/700, 12 over its content. */
.pp-heading {
  margin: 0 0 12px;
  font-size: 19px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: 0;
  white-space: nowrap;
  color: var(--text);
}

.pp-rotation,
.pp-stacks,
.pp-reviews {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ── The flat cartridge ────────────────────────────────────────────────────── */

/* GameCartridgeArtwork, one em to its unit: the shell in the page's skin (classic #454A54, radius
   5.5) over the board a see-through skin shows, the skin's rim, the groove under the grips, five
   grips, the label (92% × 77.3%, centred at 56.35% down) on its #111318 matte with the whole cover
   fitted in it, and the foot's bar. */
.pp-cart {
  position: relative;
  display: block;
  width: 62em;
  height: 81em;
  border-radius: max(3px, 5.5em);
  /* Two layers, the shell over the board, so a translucent shell tints what it covers. */
  background-image: linear-gradient(var(--pp-shell), var(--pp-shell)), var(--pp-board);
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
.pp-cart::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(11.8em - max(.5px, .55em) / 2);
  height: max(.5px, .55em);
  background: rgba(0, 0, 0, .22);
}
.pp-cart::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 max(.5px, .4em) var(--pp-rim);
  pointer-events: none;
}
.pp-grips {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 3.844em;
  padding-top: 3.1625em;
}
.pp-grips i {
  flex: none;
  width: 5.394em;
  height: 6.075em;
  border-radius: max(1px, 1.35em);
  background: rgba(0, 0, 0, .52);
}
.pp-grips::after {
  content: "";
  position: absolute;
  left: 18.6em;
  width: 24.8em;
  top: calc(78.3em - max(1px, 1.5em) / 2);
  height: max(1px, 1.5em);
  border-radius: 999px;
  background: rgba(0, 0, 0, .3);
}
/* The groove, grips and bar in the skin's ink, at the same strengths. A browser without color-mix()
   (Safari before 16.2) keeps them black, as above, rather than losing them. */
@supports (color: color-mix(in srgb, #000 22%, transparent)) {
  .pp-cart::before { background: color-mix(in srgb, var(--pp-ink) 22%, transparent); }
  .pp-grips i { background: color-mix(in srgb, var(--pp-ink) 52%, transparent); }
  .pp-grips::after { background: color-mix(in srgb, var(--pp-ink) 30%, transparent); }
}
.pp-label {
  position: absolute;
  left: 2.48em;
  top: 14.3372em;
  width: 57.04em;
  height: 62.613em;
  overflow: hidden;
  border-radius: max(2px, 3.2em);
  background: var(--pp-matte);
}
.pp-label::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 max(.5px, .45em) rgba(0, 0, 0, .28);
}
.pp-cover {
  position: absolute;
  top: max(.5px, .8em);
  left: max(.5px, .8em);
  width: calc(100% - 2 * max(.5px, .8em));
  max-width: none;
  height: calc(100% - 2 * max(.5px, .8em));
  object-fit: contain;
  border-radius: max(1px, 1.5em);
}
/* No cover: the app's placeholder, the controller on the surface. */
.pp-label.is-missing .pp-cover { display: none; }
.pp-label.is-missing::before {
  content: "";
  position: absolute;
  inset: max(.5px, .8em);
  border-radius: max(1px, 1.5em);
  background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -2 128 84'%3E%3Cpath fill='none' stroke='%238A8F99' stroke-width='6' stroke-linejoin='round' d='M30 6h60c14 0 22 8 25 22l4 28c2 14-6 22-15 20-7-1.5-11-7-15-14l-4-7c-2-3-4-4-8-4H43c-4 0-6 1-8 4l-4 7c-4 7-8 12.5-15 14-9 2-17-6-15-20l4-28C8 14 16 6 30 6Zm-2 14v6h-6v8h6v6h8v-6h6v-8h-6v-6h-8Zm60-3a4 4 0 1 0 0 8 4 4 0 1 0 0-8Zm9 9a4 4 0 1 0 0 8 4 4 0 1 0 0-8Zm-18 0a4 4 0 1 0 0 8 4 4 0 1 0 0-8Zm9 9a4 4 0 1 0 0 8 4 4 0 1 0 0-8Z'/%3E%3C/svg%3E") center / 24px 16px no-repeat;
}
/* A Stack's strip draws a missing cover as a dashed outline instead. */
.pp-cart.is-strip .pp-label.is-missing::before {
  background: var(--surface);
  outline: 1px dashed var(--pp-line);
  outline-offset: -4px;
}

/* ── The Favourite Four: four across, 10 apart, the whole row one link ────────── */

.pp-four {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: inherit;
}
.pp-four-slot {
  flex: 1 1 0;
  min-width: 0;
  container-type: inline-size;
}
.pp-four-slot .pp-cart {
  /* Before container units (Safari 15): the slot from the window's width. */
  font-size: calc((min(100vw, 480px) - 78px) / 4 / 62);
  font-size: calc(100cqw / 62);
}
/* An empty place: a clear 3:4 tile, as the app pads its row. */
.pp-four-slot.is-empty { aspect-ratio: 3 / 4; }
/* Four games and no clear tile: SwiftUI's row is the shells' height (the slot's width × 81/62), and
   each 3:4 tile fitted into that is 243/248 of its slot, the four packed from the left, 10 apart. */
.pp-four.is-full { height: calc((100cqw - 78px) / 4 * 81 / 62); }
.pp-four.is-full .pp-four-slot { flex: 0 0 calc((100% - 30px) / 4 * 243 / 248); }
.pp-four:active .pp-four-slot { transform: scale(.97); }

/* ── A sealed cartridge: the head's latest clear, without scripts ─────────────── */

/* The small seal stamped on the label's top right. */
.pp-cart.is-sealed .pp-seal-s { position: absolute; width: 35%; height: auto; aspect-ratio: 1; left: 64%; top: 12%; }
/* The head's latest clear without scripts: the sealed tile where the 3D one stands, 236 high, centred
   across its host and 150 down. */
.pp-head-cart .pp-cart { font-size: calc(236px / 81); margin: 32px auto 0; }

/* ── In rotation: scrolls sideways inside the column, 24 between games ──────── */

.pp-rotation {
  display: flex;
  gap: 24px;
  overflow-x: auto;
  scrollbar-width: none;
}
.pp-rotation::-webkit-scrollbar { display: none; }
.pp-rotation-item {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
}
/* ProfileGameArtwork: 46 × 59.8, the shell fitted in it. */
.pp-rotation-item .pp-cart { font-size: calc(59.8px / 81); margin: 0 .115px; }
/* 14/800, at most 160 wide, one line, cut at its end as the app cuts it. */
.pp-rotation-title {
  max-width: 160px;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Stacks: 26 apart ──────────────────────────────────────────────────────── */

.pp-stacks {
  display: flex;
  flex-direction: column;
  gap: 26px;
}
/* "Pinned": pin.fill and the word, 12/700 in the accent, 8 over the card. The symbol's frame (14.3
   × 17.1 at 12 points) makes the row taller than the word. */
.pp-pinned {
  display: flex;
  align-items: center;
  gap: 7.9px;
  height: 17.1px;
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 700;
  color: var(--accent);
}
.pp-pinned .pp-icon { width: 14.33px; height: 17.1px; }
.pp-stack-link {
  display: flex;
  flex-direction: column;
  min-height: 44px;
  color: inherit;
}
.pp-stack-link:hover .pp-stack-title,
.pp-stack-link:focus-visible .pp-stack-title { color: var(--accent); }
/* StackArtworkStrip: up to five shells 120 high, from the left, 10 apart, overlapping (the first
   on top) only when the row is too narrow for them. */
.pp-strip {
  position: relative;
  display: block;
  height: 120px;
  container-type: inline-size;
  --pp-card: 92.3077px;
  --pp-step: min(calc(var(--pp-card) + 10px), max(0px, (min(100vw, 480px) - 48px - var(--pp-card)) / var(--d)));
}
@supports (width: 1cqw) {
  .pp-strip { --pp-step: min(calc(var(--pp-card) + 10px), max(0px, (100cqw - var(--pp-card)) / var(--d))); }
}
.pp-strip-item {
  position: absolute;
  top: 0;
  left: calc(var(--i) * var(--pp-step));
  z-index: calc(10 - var(--i));
  display: grid;
  place-items: center;
  width: var(--pp-card);
  height: 120px;
}
.pp-strip-item .pp-cart { font-size: calc(120px / 81); }
.pp-strip-empty {
  display: grid;
  place-items: center;
  min-height: 120px;
  font-size: 13px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
.pp-stack-title {
  margin-top: 11px;
  font-size: 17px;
  line-height: 1.2;
  font-weight: 800;
  color: var(--text);
  overflow-wrap: anywhere;
}
.pp-stack-note {
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* StackSummaryCounts: 12/600, 10 apart, in a 44-high row 4 under the card. */
.pp-stack-counts {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
/* Each count is a Label: the symbol's frame (heart.fill 14.7 wide, bubble.left 15.5), then 7.8. */
.pp-stack-counts span {
  display: inline-flex;
  align-items: center;
  gap: 7.8px;
  white-space: nowrap;
}
.pp-icon { flex: none; display: block; }
.pp-icon-heart { width: 14.74px; height: 14px; }
.pp-icon-bubble { width: 15.47px; height: 14px; }

/* ── Recent reviews: 20 apart ──────────────────────────────────────────────── */

.pp-reviews {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* The shell 58 wide, 14 to the text, and the app's 44-point "…" (report, in the app) kept as room
   so the text wraps where the app's does. */
.pp-review {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.pp-review::after {
  content: "";
  flex: none;
  width: 44px;
}
.pp-review > .pp-cart { flex: none; font-size: calc(75.4px / 81); margin: 0 .144px; }
.pp-review-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
.pp-review-title {
  margin: 0;
  font-size: 15px;
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: 0;
  text-wrap: wrap;
  color: var(--text);
}
.pp-review-text {
  margin: -1.5px 0;
  font-size: 14px;
  line-height: calc(1.2em + 3px);
  font-weight: 600;
  color: var(--text);
  overflow-wrap: anywhere;
}
.pp-review-meta {
  margin: 0;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}

/* RatingStars(size: 12, style: .inline): five 13.2 boxes 0.96 apart, every star in the accent. */
.pp-stars {
  display: flex;
  gap: .96px;
  color: var(--accent);
}
.pp-star { flex: none; display: block; width: 13.2px; height: 13.2px; }

/* ── "Nothing public yet." ─────────────────────────────────────────────────── */

.pp-nothing {
  margin: 0;
  padding: 24px 0;
  font-size: 15px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
}

/* ── The counts: a rule, 18 over three columns, or four with Cleared ───────── */

.pp-stats {
  display: flex;
  padding-top: 18px;
  border-top: 1px solid var(--pp-line);
}
.pp-stat {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 0;
}
.pp-stat-n {
  font-size: 20px;
  line-height: 1.2;
  font-weight: 800;
  color: var(--text);
}
.pp-stat-l {
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
/* The small seal by Cleared, in the label's line (the site draws every svg as a block). */
.pp-seal-xs { display: inline-block; width: 12px; height: 12px; margin-right: 4px; vertical-align: -2px; transform: rotate(-12deg); }

/* ── Public ratings: 12 apart ──────────────────────────────────────────────── */

.pp-ratings {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pp-ratings-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.pp-ratings-head .pp-heading { margin: 0; }
.pp-average {
  font-size: 14px;
  line-height: 1.2;
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}
/* Ten bars, 4 apart, 72 high at the tallest, rounded 2 at the top, darker to the left. */
.pp-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 72px;
}
.pp-bars i {
  flex: 1 1 0;
  height: var(--h);
  border-radius: 2px 2px 0 0;
  background: var(--accent);
  opacity: .35;
}
.pp-bars i:nth-child(2) { opacity: .415; }
.pp-bars i:nth-child(3) { opacity: .48; }
.pp-bars i:nth-child(4) { opacity: .545; }
.pp-bars i:nth-child(5) { opacity: .61; }
.pp-bars i:nth-child(6) { opacity: .675; }
.pp-bars i:nth-child(7) { opacity: .74; }
.pp-bars i:nth-child(8) { opacity: .805; }
.pp-bars i:nth-child(9) { opacity: .87; }
.pp-bars i:nth-child(10) { opacity: .935; }
.pp-axis {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 600;
  color: var(--muted);
}
.pp-rated,
.pp-rated-none {
  margin: 0;
  font-weight: 600;
  line-height: 1.2;
  color: var(--muted);
}
.pp-rated { font-size: 13px; }
.pp-rated-none { font-size: 15px; }

/* ── Wider windows ─────────────────────────────────────────────────────────── */

@media (min-width: 560px) {
  .pp-col { margin-top: 24px; }
  .pp-art { border-radius: 28px 28px 0 0; }
}

/* The head's cartridge beside the name on a wider window. The name keeps the column's whole width
   (it shrinks to fit only as on a phone); the handle, the rank line and the bio run beside the
   cartridge, in 192, which holds the longest rank line (172); a handle wider than that (20 wide
   letters) wraps rather than running under the cartridge. The cartridge's host is 240 by 320: the
   cartridge, at most 200 across as it floats, stays whole inside it. */
@media (min-width: 720px) {
  .pp-hero.has-cart .pp-id {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 240px;
    grid-template-rows: auto auto auto auto 1fr;
    grid-template-areas: "name name" "handle cart" "rank cart" "bio cart" ". cart";
  }
  .pp-hero.has-cart .pp-name { grid-area: name; }
  .pp-hero.has-cart .pp-handle { grid-area: handle; overflow-wrap: anywhere; }
  .pp-hero.has-cart .pp-rank { grid-area: rank; }
  .pp-hero.has-cart .pp-bio { grid-area: bio; }
  .pp-head-cart { grid-area: cart; height: 320px; }
}
