/* 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 { position: relative; gap: 9px; }
/* The 32 px logo row, a 44 px tap target (test round, 9 Oct 2026). */
.pp-top .brand::after { content: ""; position: absolute; inset: -6px 0; }
.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; }
}

/* 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);
}
/* Owner, 8 Oct 2026 (option C): the strips beside the fitted cover take a blur of the same art, not
   the matte, so nothing is cropped and there are no dark bars. Same URL as the cover: no extra fetch.
   The blur is 7% of the label's width, as in the owner's mock. A blur fades to clear at its own edge,
   which over the dark matte reads as a dark rim, so the copy reaches 20% past the label (almost three
   blur radii): the fade stays outside the window. */
.pp-cover-fill {
  position: absolute;
  inset: -20%;
  width: 140%;
  max-width: none;
  height: 140%;
  object-fit: cover;
  filter: blur(4em) saturate(1.2) brightness(.8);
}
.pp-label.is-missing .pp-cover-fill { display: none; }
/* 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: a clear ──────────────────────────────────────────────── */

/* 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%; }

/* ── 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, up to two lines, centred beside the shell. These rows have no platform
   line under the title, so a long title takes that room rather than being cut (owner, 8 Oct 2026:
   "they'd rather have wrapped, text than no text"). Only a title longer than two lines ends in "…".
   Two lines (33.6) stay shorter than the shell (59.8), so the row's height never changes.
   A wrapped box would keep the whole 160, leaving a wide gap after a short second line; the page's
   inline script (ROTATION_FIT_SCRIPT, api/profile.js) sets it to its widest line, as SwiftUI's Text
   is. Without the script it stays 160. */
.pp-rotation-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  max-width: 160px;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 800;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* ── 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; }
}
