/* ============================================================
   CULTURILY — PROFILE PAGE
   Extends global.css + components.css.
   Covers: loading, page shell, header, stats, culture card,
   achievement grid, edit mode, friendship buttons.
   ============================================================ */

/* ── Loading splash ─────────────────────────────────────────── */

.pf-loading {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
  background: var(--c-bg);
  z-index: 100;
}
/* Skeleton loading layout — mirrors the avatar, rank card and stats grid. */
.pf-skeleton { width: 100%; max-width: var(--app-width); padding: 0 var(--sp-5); }
.pf-skeleton-avatar { width: 80px; height: 80px; margin: 0 auto var(--sp-4); }
.pf-skeleton-name { width: 160px; height: 24px; border-radius: 6px; margin: 0 auto var(--sp-5); }
.pf-skeleton-rank { height: 96px; border-radius: 16px; margin-bottom: var(--sp-5); }
.pf-skeleton-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.pf-skeleton-stat { height: 72px; border-radius: 14px; }

/* ── Error state ────────────────────────────────────────────── */

.pf-error-screen {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-6);
  text-align: center;
}

/* ── Page shell ─────────────────────────────────────────────── */

.pf-page {
  position: relative;
  min-height: 100dvh;
  padding-bottom: calc(var(--nav-bottom-h) + var(--sp-6));
  max-width: var(--app-width);
  margin-inline: auto;
}

/* ── Settings gear (top right) ──────────────────────────────── */

.pf-settings-btn {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-4);
  z-index: 20;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-primary);
  font-size: 1.3rem;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.pf-settings-btn:hover {
  background: var(--surface-3);
  color: var(--accent-ink);
}

/* Dark/light toggle — sits just left of the settings gear */
.pf-theme-btn {
  position: absolute;
  top: var(--sp-3);
  right: calc(var(--sp-4) + 48px);
  z-index: 20;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-primary);
  font-size: 1.15rem;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.pf-theme-btn:hover {
  background: var(--surface-3);
  color: var(--accent-ink);
}

/* ── Back bar (other-user view) ─────────────────────────────── */

.pf-back-bar {
  display: flex;
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
}

.pf-back-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-subtle);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  border: none;
  background: none;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}

.pf-back-btn:hover {
  color: var(--text-primary);
  background: var(--surface-2);
}

/* ── Header ─────────────────────────────────────────────────── */

.pf-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--sp-8) var(--sp-5) var(--sp-5);
  gap: var(--sp-3);
  text-align: center;
}

.pf-avatar-area {
  position: relative;
  display: inline-block;
  margin-bottom: var(--sp-1);
}

/* Avatar is tappable to change its colour (own profile only). */
.avatar.is-editable {
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease);
}
.avatar.is-editable:hover { transform: scale(1.04); }
.avatar.is-editable:focus-visible {
  outline: 3px solid var(--accent-ink);
  outline-offset: 3px;
}

/* Small pencil badge, bottom-right of the avatar — the edit affordance. */
.pf-avatar-edit {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 30px;
  height: 30px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  border: 3px solid var(--c-bg);
  background: var(--accent);
  color: var(--accent-text);
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
  transition: transform var(--t-fast) var(--ease);
}
.pf-avatar-edit:hover { transform: scale(1.08); }
.pf-avatar-edit:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
}
.pf-avatar-edit svg { display: block; }

@media (prefers-reduced-motion: reduce) {
  .avatar.is-editable,
  .pf-avatar-edit { transition: none; }
  .avatar.is-editable:hover,
  .pf-avatar-edit:hover { transform: none; }
}

/* (Avatar SUPER badge removed — SUPER status is canonical on the rank card,
   and also shown on the subscription card.) */

.pf-name {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
  letter-spacing: -0.015em;
}

.pf-country {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--text-sm);
  color: var(--text-subtle);
  min-height: 22px;
}

.pf-bio {
  font-size: var(--text-sm);
  color: var(--text-muted);
  max-width: 300px;
  line-height: var(--leading-relaxed);
  margin: 0;
}

.pf-joined {
  font-size: var(--text-xs);
  color: var(--text-subtle);
  margin: 0;
}

.pf-actions {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
  flex-wrap: wrap;
  justify-content: center;
}

/* Culture Rank player card removed (arcade-removal stage 2) — its CSS
   (.pf-rank-card and children) removed with it. */

/* Share profile button — secondary action, co-located with Edit in the action row. */
.pf-share-btn i { margin-right: 5px; vertical-align: -1px; }

/* ── Referral card (premium redesign) ───────────────────────── */

.pf-referral-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 16px);
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-align: center;
}

.pf-referral-label {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-subtle);
  margin: 0;
}

.pf-referral-code-block {
  width: 100%;
  background: var(--surface-3);
  border-radius: var(--r-md, 12px);
  padding: var(--sp-4) var(--sp-3);
  display: flex;
  align-items: center;
  justify-content: center;
}

.pf-referral-code {
  font-family: 'Courier New', ui-monospace, monospace;
  font-size: clamp(1.75rem, 9vw, 2.25rem);
  font-weight: 700;
  color: var(--accent-ink);   /* --accent itself is #CCFF00 in both themes — --accent-ink is the tier that actually darkens on light, per §3a */
  letter-spacing: 0.18em;
  /* letter-spacing adds trailing space on the right — nudge to re-centre */
  text-indent: 0.18em;
  line-height: 1.1;
  word-break: break-all;
}

.pf-referral-reward {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-relaxed);
  margin: 2px 0 var(--sp-1);
}

.pf-referral-card .btn { width: 100%; }
.pf-referral-card .btn i { margin-right: 6px; vertical-align: -1px; }

/* ── Stats grid ─────────────────────────────────────────────── */

.pf-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
  padding: 0 var(--sp-4) var(--sp-5);
}

.pf-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: var(--sp-3) var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  text-align: center;
}

.pf-stat-value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
}

.pf-stat-label {
  font-size: 9px;
  font-weight: 600;
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.3;
}

/* ── Stats grid (2×3) ────────────────────────────────────── */
.pf-stats-grid {
  /* Flex-wrap so 5 stat tiles flow 3-then-2 and shrink (never crush 5 across)
     on narrow phones. */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-4) var(--sp-5);
}

.pf-stat-card {
  flex: 1 1 27%;
  min-width: 92px;
  max-width: 150px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-3);
  background: var(--surface-2);   /* theme token — readable card in light mode */
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 14px);
  text-align: center;
}
.pf-stat-card.pf-stat-wide { flex-basis: 100%; max-width: none; }

/* Muted state — e.g. zero streak freezes */
.pf-stat-card.is-muted { opacity: 0.55; }
.pf-stat-card.is-muted .pf-stat-num { color: var(--text-subtle); }

.pf-stat-num {
  font-family: var(--font-numeric);
  font-size: clamp(1.1rem, 5.5vw, 1.6rem);   /* fits 3 tiles across, large totals included */
  font-weight: 800;
  color: var(--accent);
  line-height: 1;
  white-space: nowrap;
}

.pf-stat-cap {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-subtle);
  letter-spacing: 0.02em;
}

/* ── Section wrapper ────────────────────────────────────────── */

.pf-section {
  padding: 0 var(--sp-4) var(--sp-6);
}

.pf-section-title {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  margin: 0 0 var(--sp-3);
}

/* ── Recently unlocked achievements ─────────────────────────── */
.pf-recent-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.pf-recent-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
}
.pf-recent-chip-icon { font-size: 1rem; line-height: 1; }
.pf-recent-seeall {
  display: inline-block;
  margin-top: var(--sp-3);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
}
.pf-recent-seeall:hover { text-decoration: underline; }

/* ── Culture card ───────────────────────────────────────────── */

.pf-culture-card {
  background: var(--surface);
  border: 1px solid var(--border);
  /* WO-VIS Wave B: NO CLEAN MAPPING — decorative one-off blue accent stripe,
     not close enough to var(--info) to swap without a visible hue shift;
     left literal. */
  border-top: 2px solid #4A9EFF;
  border-radius: var(--r-lg);
  padding: var(--sp-4);
}

.pf-culture-top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

.pf-culture-flag {
  font-size: 30px;
  line-height: 1;
  flex-shrink: 0;
}

.pf-culture-meta {
  flex: 1;
  min-width: 0;
}

.pf-culture-name {
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--text-primary);
  margin: 0 0 2px;
}

.pf-culture-level-title {
  font-size: var(--text-sm);
  color: var(--text-subtle);
  margin: 0;
}

.pf-culture-level-badge {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  flex-shrink: 0;
}

.pf-culture-level-num {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1;
}

.pf-culture-level-label {
  font-size: 10px; /* a11y low-pass (2026-07-11): was 9px; kept conservative — a caption under a 24px hero number in a tight right-aligned column, --text-xs (12px) risked crowding */
  font-weight: 700;
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.pf-culture-xp-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--text-xs);
  color: var(--text-subtle);
  margin-bottom: var(--sp-1);
}

.pf-culture-xp-curr {
  color: var(--text-primary); /* dark-theme small text is never lime — Wave D follow-up; light stays --accent-ink below */
  font-weight: 700;
}
html.theme-light .pf-culture-xp-curr { color: var(--accent-ink); }

.pf-culture-streak {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--streak);
  margin-top: var(--sp-3);
}
/* The streak flame orange is 1.94:1 on the light-theme surface — no
   --streak-ink token exists yet (unlike accent/error/info), so this falls
   back to the standard ink color rather than inventing a new hex. The flame
   icon beside this text (js/profile.js) is aria-hidden and keeps its own
   orange — only the readable count text needs to pass. */
html.theme-light .pf-culture-streak { color: var(--text-primary); }

/* ── Cultures explored ───────────────────────────────────── */
.pf-explored-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 12px);
  margin-bottom: var(--sp-2);
}
.pf-explored-row:last-child { margin-bottom: 0; }

.pf-explored-flag { font-size: 1.6rem; line-height: 1; flex-shrink: 0; }

.pf-explored-name {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
}

.pf-explored-count {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-primary); /* dark-theme small text is never lime — Wave D follow-up; light stays --accent-ink below. Background (--accent-dim) is a translucent wash, not a solid fill, so the button-fill exemption doesn't apply */
  background: var(--accent-dim);
  padding: 3px 9px;
  border-radius: var(--r-full);
}
html.theme-light .pf-explored-count { color: var(--accent-ink); }

.pf-culture-no-data {
  font-size: var(--text-sm);
  color: var(--text-subtle);
  text-align: center;
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}

/* ── Name days — 114_user_saved_namedays.sql. Same card-row shape as
   .pf-explored-row, but no accent/lime pill: this is a calm personal
   calendar, not a score or an achievement. ── */
.pf-nameday-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 12px);
  margin-bottom: var(--sp-2);
}
.pf-nameday-row:last-child { margin-bottom: 0; }
.pf-nameday-name { flex: 1; min-width: 0; font-size: var(--text-sm); font-weight: 600; color: var(--text-primary); }
.pf-nameday-next { flex-shrink: 0; font-size: var(--text-xs); color: var(--text-subtle); }

/* ── Family timeline (era-anchoring) — calm almanac styling, no arcade:
   plain text prompt, two equally-weighted secondary buttons (neither
   "left"/"still there" reads as the default), one decade select, one
   understated Edit link once answered. ── */
.pf-era-prompt { font-size: var(--text-sm); color: var(--text-primary); margin: 0 0 var(--sp-3); }
.pf-era-choices { display: flex; gap: var(--sp-3); }
.pf-era-choices .btn { flex: 1; }
/* §ED465: .btn's base white-space:nowrap + overflow:hidden (css/components.css)
   is sized for short CTA labels — "Leaving, and what came after" clipped
   mid-word ("ving, and what came a") at 375px instead of wrapping. These two
   choices carry full-sentence copy, so let them wrap and grow instead. */
.pf-era-choices .btn.pf-era-choice {
  white-space: normal;
  overflow: visible;
  height: auto;
  line-height: 1.3;
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
}
.pf-era-decade-select {
  display: block;
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg, 12px);
}
.pf-era-summary { font-size: var(--text-sm); color: var(--text-primary); margin: 0 0 var(--sp-2); }
.pf-era-edit-link {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-subtle);
  text-decoration: underline;
  cursor: pointer;
}

/* ── Achievements grid ──────────────────────────────────────── */

.pf-achievements-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-2);
}

/* ── Edit mode: inline inputs ───────────────────────────────── */

.pf-edit-field {
  width: 100%;
  max-width: 300px;
}

.pf-edit-input {
  width: 100%;
  background: var(--surface-2);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  text-align: center;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}

.pf-edit-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}

.pf-edit-input.input-error {
  border-color: var(--error);
  box-shadow: 0 0 0 3px var(--error-dim);
}

.pf-edit-error {
  font-size: var(--text-xs);
  color: var(--error);
  text-align: center;
  margin-top: 4px;
}

.pf-edit-textarea {
  width: 100%;
  background: var(--surface-2);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  text-align: center;
  resize: none;
  min-height: 72px;
  line-height: var(--leading-relaxed);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}

.pf-edit-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}

.pf-country-select {
  width: 100%;
  background: var(--surface-2);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  text-align: center;
  appearance: none;
  -webkit-appearance: none;
  /* NOTE: raw data-URI SVG stroke color can't reference var() — flagged
     WO-VIS Wave B, same fix as css/components.css's .form-select. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(248,248,248,0.45)' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-3) center;
  padding-right: var(--sp-8);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
html.theme-light .pf-country-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(22,22,22,0.45)' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

.pf-country-select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}

.pf-country-select option {
  background: var(--surface-3);
  color: var(--text-primary);
}

/* ── Avatar colour picker ───────────────────────────────────── */

.pf-avatar-color-picker {
  display: flex;
  justify-content: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  padding: var(--sp-1) 0;
}

.pf-color-swatch {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  cursor: pointer;
  border: 3px solid transparent;
  transition: border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  flex-shrink: 0;
}

.pf-color-swatch:hover { transform: scale(1.08); }

.pf-color-swatch.is-selected {
  border-color: var(--text-primary);
  transform: scale(1.15);
}

/* ── Fixed save / cancel bar (edit mode) ───────────────────── */

.pf-edit-bar {
  position: fixed;
  bottom: var(--nav-bottom-h);
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: var(--app-width);
  background: var(--surface);
  border-top: 1px solid var(--border-strong);
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  gap: var(--sp-2);
  z-index: calc(var(--z-sticky) + 1);
  animation: slideUp var(--t-base) var(--ease-out) both;
}

@keyframes slideUp {
  from { transform: translateX(-50%) translateY(100%); }
  to   { transform: translateX(-50%) translateY(0); }
}

/* ── Sign out section ───────────────────────────────────────── */

.pf-signout-section {
  padding: 0 var(--sp-4) var(--sp-4);
}

/* ── Toast ──────────────────────────────────────────────────── */

.pf-toast {
  position: fixed;
  top: var(--sp-5);
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
  box-shadow: var(--shadow-lg);
  z-index: var(--z-toast);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}

.pf-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── Responsive ─────────────────────────────────────────────── */

@media (max-width: 380px) {
  .pf-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ── Friend requests section ────────────────────────────────── */

/* a11y medium-pass (2026-07-11): white-on-#FF4444 measured 3.41:1 at 11px
   bold — under 4.5:1, and this text is nowhere near the 18.66px-bold
   large-text threshold so the 3:1 exception doesn't apply. TOKEN GAP,
   reported rather than silently patched: neither existing red token clears
   4.5:1 with white text either (--error #FF5A48 -> 3.08:1, --hearts #ff6b6b
   -> 2.78:1 — both WORSE than the ad-hoc value already here), so swapping to
   an existing token would regress this, not fix it. #FF4444 itself isn't a
   token — checked, this is its only use in the codebase. Darkened the
   existing ad-hoc value by the same minimum-step method used for the
   --text-subtle/--accent-ink token fixes above (4.94:1), rather than
   inventing an unrelated hue. If Jake wants a real badge-red token
   (--danger, say) for reuse, this is the value to seed it with. */
.pf-requests-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: #D42F2F;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  border-radius: var(--r-full);
  margin-left: 6px;
  line-height: 1;
  vertical-align: middle;
}

.pf-friend-req-card {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  margin-bottom: var(--sp-2);
}

.pf-friend-req-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}

.pf-friend-req-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pf-friend-req-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pf-friend-req-sub {
  font-size: var(--text-xs);
  color: var(--text-subtle);
}

.pf-friend-req-actions {
  flex-shrink: 0;
  display: flex;
  gap: var(--sp-2);
}
/* a11y medium-pass (2026-07-11): .btn-sm (8px padding + 14px text, line-height:1
   from base .btn) resolves to ~30px tall — under the 44px floor. Scoped to
   just these two (not a global .btn-sm change, which is used elsewhere for
   deliberately compact contexts this audit didn't examine). */
.pf-req-accept, .pf-req-decline { min-height: 44px; }

.pf-change-culture-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  text-decoration: none;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.pf-change-culture-link:hover {
  background: var(--surface-3);
  border-color: var(--border-strong);
}

/* ============================================================
   SUPER — plan picker + subscription status
   ============================================================ */

.pf-plans {
  display: flex;
  gap: 10px;
  margin-bottom: 12px;
}

.pf-plan {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 14px 14px;
  background: var(--surface-2);
  border: 2px solid var(--border-strong);
  border-radius: var(--r-lg, 14px);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.16s ease, background 0.16s ease, transform 0.1s ease;
  -webkit-tap-highlight-color: transparent;
}
.pf-plan:hover  { border-color: var(--accent); }
.pf-plan:active { transform: scale(0.99); }

.pf-plan--annual {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.pf-plan-badge {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--accent-text);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: var(--r-full, 999px);
  white-space: nowrap;
}

.pf-plan-name {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-subtle);
  margin-top: 2px;
}

.pf-plan-was {
  font-size: 0.8125rem;
  color: var(--text-disabled);
  text-decoration: line-through;
}

.pf-plan-price {
  font-family: var(--font-numeric);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.1;
}
.pf-plan-per {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-subtle);
}

.pf-plan-save {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--accent);
}

.pf-plan-trial {
  font-size: 0.6875rem;
  color: var(--text-subtle);
  margin-top: 2px;
}

.pf-plan-perks {
  font-size: var(--text-xs);
  color: var(--text-subtle);
  text-align: center;
  margin: 0 0 12px;
  line-height: 1.4;
}

/* ── Subscription status (Super users) ───────────────────── */

.pf-sub {
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg, 14px);
  padding: 16px 18px;
  margin-bottom: 12px;
}

.pf-sub-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pf-sub-title {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--text-primary);
}

.pf-sub-status {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-dim);
  padding: 3px 9px;
  border-radius: var(--r-full, 999px);
}

.pf-sub-plan {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-primary);
  margin: 10px 0 0;
}

.pf-sub-renew {
  font-size: var(--text-xs);
  color: var(--text-subtle);
  margin: 2px 0 0;
}

/* Compact earned-only milestones row (replaces the full achievements grid) */
.pf-milestones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.pf-milestone-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-primary);
}
.pf-milestone-chip-icon { font-size: 1rem; line-height: 1; }

/* ============================================================
   REWARD-KIT PROFILE RESKIN
   Brings the existing structure to the design "Culturily Profile"
   (+ Light): sticky top bar, rounded-square avatar with culture-flag
   badge, single Friends count, icon-chip stat cards (reward icons),
   card sections, achievement badges. Token-driven → dark + light.
   ============================================================ */

.pf-page { background: var(--c-bg); }

/* ── Sticky top bar ──────────────────────────────────────── */
.pf-topbar {
  position: sticky;
  top: 0;
  z-index: 200;
  /* Reserve the status-bar inset (sticky → occupies flow, no double-offset below). */
  height: calc(60px + var(--safe-top));
  padding: var(--safe-top) 20px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: color-mix(in srgb, var(--c-bg) 85%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.pf-topbar-title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; color: var(--text-primary); text-wrap: balance; }
.pf-topbar-actions { display: flex; gap: 8px; }
/* icon buttons in the bar (override the old absolute positioning) */
.pf-icon-btn,
.pf-topbar .pf-theme-btn,
.pf-topbar .pf-settings-btn {
  position: relative; /* anchors the hit-slop ::before below; was static */
  inset: auto;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-subtle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-base);
  cursor: pointer;
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.pf-icon-btn:hover { border-color: var(--border-strong); color: var(--text-primary); }
/* Hit-slop only — the visible 36px box is unchanged; -4px on every side (the
   .pf-topbar-actions gap is 8px, so adjacent buttons' slop meets exactly at
   the midpoint with no overlap) brings the actual tappable area to ~44px. */
.pf-icon-btn::before,
.pf-topbar .pf-theme-btn::before,
.pf-topbar .pf-settings-btn::before {
  content: '';
  position: absolute;
  inset: -4px;
}

/* ── Hero ────────────────────────────────────────────────── */
/* Header reads as intentional blocks: identity · status · meta · actions.
   The header gap is the inter-block rhythm; each block keeps a tighter
   internal gap so the hierarchy doesn't flatten into one even column. */
.pf-header { padding: 24px 20px 8px; gap: var(--sp-5); }

.pf-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
}

.pf-meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
}
/* Empty country/bio collapse so they leave no dead gap (no flex item = no gap). */
.pf-country:empty,
.pf-bio:empty { display: none; }

.pf-avatar-area { margin-bottom: 0; }
#pf-avatar.avatar.avatar--2xl {
  width: 92px;
  height: 92px;
  border-radius: 26px;            /* rounded square per export */
}
/* Neutral placeholder — initials/glyph readable on the surface tone (the base
   .avatar::after uses near-black text, invisible on a dark surface). */
#pf-avatar.avatar::after { color: var(--text-primary); }
.pf-avatar-glyph {
  position: relative;
  z-index: 1;
  color: var(--text-subtle);
  font-size: 46px;
  line-height: 1;
}
.pf-avatar-flag {
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: var(--c-bg);
  border: 2px solid var(--c-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--border-strong);
}
.pf-avatar-flag:empty { display: none; }
.pf-avatar-flag .flag-chip,
.pf-avatar-flag img { width: 26px; height: 18px; border-radius: 4px; display: block; box-shadow: none; }

.pf-name { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 600; letter-spacing: -0.01em; text-wrap: balance; overflow-wrap: break-word; }
.pf-joined { font-size: 13.5px; color: var(--text-subtle); }

.pf-actions { margin-top: 0; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ── Friends count (single, mutual-friends) ──────────────── */
.pf-friends-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin: 0 20px 22px;
  padding: 13px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.pf-friends-count { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; color: var(--text-primary); }
.pf-friends-label { font-size: var(--text-xs); color: var(--text-subtle); }

/* ── Stats grid — icon-chip cards ────────────────────────── */
.pf-stats-grid {
  grid-template-columns: 1fr 1fr;
  gap: 11px;
  padding: 0 20px;
  margin-bottom: 22px;
}
.pf-stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px;
  min-height: 0;
}
.pf-stat-ico {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border-radius: 11px;
  background: var(--accent-dim);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-ink);
  font-size: 19px;
}
.pf-stat-ico .reward-ico svg { display: block; }
.pf-stat-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; align-items: flex-start; }
.pf-stat-num { font-size: 19px; font-weight: 600; color: var(--text-primary); }
/* font-family intentionally NOT re-set here — the base .pf-stat-num rule above
   (var(--font-numeric)) used to be silently overridden by this later rule
   setting var(--font-display); removing the override, not re-adding on top,
   so numeric wins for real (rule: numbers always use --font-numeric). */
.pf-stat-cap { font-size: 11.5px; color: var(--text-subtle); text-transform: none; letter-spacing: 0; }

/* ── Sections + cards ────────────────────────────────────── */
.pf-section { padding: 0 20px; margin-bottom: 22px; }
.pf-section-title {
  font-size: var(--text-xs); /* a11y low-pass (2026-07-11): was a raw 10.5px, doesn't scale like the (dead, shadowed) earlier block's own var(--text-xs) — aligned to it */
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-subtle);
  padding-left: 2px;
  margin-bottom: 12px;
  text-wrap: balance;
}

/* ── Achievements — export badge grid ────────────────────── */
.pf-milestones {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 11px;
}
.pf-milestone-chip {
  flex-direction: column;
  align-items: center;
  gap: 9px;
  padding: 15px 8px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-radius: 16px;
  text-align: center;
}
.pf-milestone-chip > span:last-child {
  font-family: var(--font-display);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-primary);
}
.pf-milestone-chip-icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-dim);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  color: var(--accent-ink);
  font-size: 22px;
}

/* ════════ Premium profile upgrade ════════════════════════════════
   Token-based throughout → dark + light follow automatically. */

/* Avatar sizing/positioning box — the rank-progress ring SVG that used to live
   here (Home HUD ring geometry) was removed in arcade-removal stage 2; this
   still centers the avatar and positions the flag badge. */
.pf-avatar-ring {
  position: relative;
  width: 148px;
  height: 148px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pf-avatar-ring .pf-avatar-in { position: relative; z-index: 1; }
.pf-avatar-ring .pf-avatar-flag {
  position: absolute;
  bottom: 10px;
  right: 10px;
  z-index: 2;
  box-shadow: 0 0 0 3px var(--c-bg);
  border-radius: 5px;
}

/* Friends/Requests dual-stat card removed — Requests now reuses
   .pf-change-culture-link (see profile.html), so its old flex:1 tile styling
   (sized for a 2-up pair) is gone with it. */

/* Achievements — earned + locked showcase grid, collapsed behind a tap toggle. */
.pf-achv-toggle {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 6px;
  background: none;
  border: none;
  padding: 12px 2px;
  margin: -12px 0;
  cursor: pointer;
  font-family: inherit;
}
.pf-achv-count { font-size: 0.8125rem; font-weight: 600; color: var(--text-subtle); }
.pf-achv-chevron { margin-left: auto; font-size: 0.7rem; color: var(--text-subtle); }
.pf-achv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 12px 10px;
}
.pf-achv { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.pf-achv-icon {
  width: 54px;
  height: 54px;
  border-radius: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 25px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-disabled);
}
.pf-achv.is-earned .pf-achv-icon {
  background: var(--accent-dim);
  border-color: var(--border-accent);
  color: var(--accent-ink);
}
.pf-achv-title { font-size: var(--text-xs); line-height: 1.25; color: var(--text-subtle); } /* a11y medium-pass (2026-07-11): was 0.6875rem (11px) */
.pf-achv.is-locked .pf-achv-icon { opacity: 0.5; }
.pf-achv.is-locked .pf-achv-title { color: var(--text-disabled); }

/* ── Desktop — clear the fixed .app-topnav (css/global.css), which replaces
   the bottom-nav pill ≥900px (world-sweep components pass, 2026-07-21).
   .pf-topbar drops its own sticky pin at this width — the top nav is now the
   page's persistent chrome, so .pf-topbar just scrolls with the content
   underneath it, same as briefing.html's in-flow (never sticky) header. */
@media (min-width: 900px) {
  .pf-page { padding-top: 64px; }
  .pf-topbar { position: static; }
}

/* ══════════════════════════════════════════════════════════════════════
   §ED132 — LEGAL FOOTER · DELETE BUTTON · DELETE MODAL
   Extracted verbatim from profile.html's inline style="" attributes.
   §ED115's rule holds: extraction changes nothing's rendered appearance.
   Every declaration below is the value the attribute carried; where a
   literal was an exact landing-scale step it now names the token and says
   so, and where it is off-scale it stays literal and says WHY.
   The two colour literals travel WITH the WO-VIS Wave B comments that
   justify them — §ED115's defect class is a cited comment beside an
   un-cited value, so the value and its citation must not be separated.
   ══════════════════════════════════════════════════════════════════════ */

.pf-legal {
  text-align: center;
  padding: 24px 0 4px;
  font-size: var(--text-xs);   /* was 0.75rem — identical (12px), now named */
}
/* Was two onmouseover/onmouseout handlers writing this.style.color. Same two
   colours, same trigger, expressed as :hover. Specificity 0,1,1 clears
   global.css:482's bare `a` (0,0,1) — nothing else in the three loaded
   sheets targets an anchor at higher weight. */
.pf-legal a { color: var(--text-disabled); text-decoration: none; }
.pf-legal a:hover { color: var(--text-subtle); }
.pf-legal-sep { color: var(--text-disabled); margin: 0 6px; }

.pf-delete-wrap { text-align: center; padding: 4px 0 32px; }
.pf-delete-btn {
  background: none;
  border: none;
  cursor: pointer;
  /* 15px — OFF the landing scale, between --text-sm (14) and --text-base (16).
     Inherited from the a11y medium-pass (2026-07-11), not introduced here.
     Listed in §ED132's open ruling; not resolved unilaterally. */
  font-size: 0.9375rem;
  color: var(--text-muted);
  font-family: var(--font-body);
  padding: 11px 16px;
}

/* display is deliberately NOT set here: js/profile.js:385/389 writes
   style.display = 'flex' / 'none' on this element, and the markup keeps its
   inline display:none as the initial state. Putting display in the class
   would be shadowed by that write and read as dead. */
.pf-delete-modal {
  position: fixed;
  inset: 0;
  /* WO-VIS Wave B: backdrop kept at a literal rgba(0,0,0,0.8) rather than
     var(--scrim) (0.62 dark / 0.35 light) — this is the last-chance
     destructive-action confirmation and is meant to read as more blocking
     than a normal modal scrim, same reasoning as auth.css's
     .auth-loading-overlay. */
  background: rgba(0, 0, 0, 0.8);
  z-index: 9000;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.pf-delete-card {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 20px;
  padding: 32px 24px;
  max-width: 340px;
  width: 100%;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.pf-delete-icon { font-size: 40px; color: var(--error); }   /* glyph box, not text */
.pf-delete-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);   /* was 1.25rem — identical (20px), now named */
  font-weight: 700;
  color: var(--text-primary);
  margin: 0;
}
.pf-delete-copy {
  /* a11y medium-pass (2026-07-11): was 0.875rem (14px) */
  font-size: var(--text-base);  /* was 1rem — identical (16px), now named */
  color: var(--text-subtle);
  line-height: 1.55;
  margin: 0;
}
.pf-delete-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.pf-delete-confirm {
  /* WO-VIS Wave B: NO CLEAN MAPPING — this muted brick-red is deliberately
     more subdued than var(--error) (#FF7A6E dark / #B3261E light), a distinct
     "point of no return" tone; left literal rather than force-matched. */
  background: #c0392b;
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 14px;
  font-size: 0.9375rem;   /* 15px — off-scale, same ruling as .pf-delete-btn */
  font-weight: 700;
  font-family: var(--font-body);
  cursor: pointer;
}
.pf-delete-status {
  font-size: 0.8125rem;   /* 13px — off-scale; matches .pf-achv-count, §ED132 ruling */
  color: var(--text-subtle);
  margin: 0;
  min-height: 20px;
}


/* ══════════════════════════════════════════════════════════════════════
   §ED140 — THE TOP, THE BANDS, THE DANGER ZONE (layout only)
   §ED132 extracted this page's type and then wrote a layout brief it
   deliberately did not act on. This block is that brief, acted on.
   NOT ONE TYPE RULE LIVES HERE. The eyebrow and the headline are
   .lv2-eyebrow and .lv2-h1 out of css/landing-v2.css, applied in the
   markup — a local font-size here would contradict the landing scale and
   fail the pinned build, which is the correct outcome. Spacing is --sp-*,
   the rule colour is --border. No literal.
   ══════════════════════════════════════════════════════════════════════ */

/* The page had no top: a 24px h1 six pixels under a sticky bar repeating the
   same words, where the landing hero is 40-64px. .pf-hero neutralises the
   flex gap and alignment .pf-header carries for its (now removed) identity
   block, so the landing's own margins own the rhythm. */
.pf-hero {
  display: block;
  text-align: left;
  gap: 0;
  padding: var(--sp-8) var(--sp-5) var(--sp-3);
}

/* A band groups sections that answer the same question. It carries NO
   heading — a heading would be new copy — so the grouping device is the
   hairline and the air: within a band, the inherited 22px section rhythm;
   between bands, a rule and 24px on both sides of it. */
.pf-band { margin: 0; }
.pf-band > .pf-section:last-child { margin-bottom: var(--sp-6); }
.pf-band + .pf-band {
  border-top: 1px solid var(--border);
  padding-top: var(--sp-6);
}

/* The one irreversible control on the page, in a container of its own.
   Sign out and the legal links stay outside it: sign out is reversible and
   a legal link is not an action on your data. */
.pf-danger-zone {
  margin: var(--sp-6) var(--sp-5) 0;
  padding-top: var(--sp-5);
  border-top: 1px solid var(--border);
}
