* { box-sizing: border-box; margin: 0; padding: 0; }

/* Self-hosted fonts. We used to pull Lora + DM Sans from Google Fonts,
   which meant a DNS lookup, TLS handshake, a CSS round-trip, and a
   separate woff2 fetch per weight — by the time fonts arrived, first
   paint had already happened in a fallback, and the swap caused visible
   layout shift. Serving the files from the same origin and preloading
   them in the head (see index.html) lets them arrive before first
   paint, so the page lands in the branded fonts with no swap. The
   Latin subsets are variable fonts that cover all the weights we use
   (DM Sans 300/400/500, Lora regular 400/600); italic is a separate
   WOFF for the few <em> usages. Fallback to Arial / Georgia with
   metric overrides covers the edge case where the font fails to load. */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url('/fonts/dmsans-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Lora';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/lora-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Lora';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/lora-italic-latin.woff') format('woff');
}
@font-face {
  font-family: 'DM Sans Fallback';
  src: local('Arial');
  size-adjust: 100.06%;
  ascent-override: 92.5%;
  descent-override: 24.1%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Lora Fallback';
  src: local('Georgia');
  size-adjust: 107.4%;
  ascent-override: 93.5%;
  descent-override: 25.65%;
  line-gap-override: 0%;
}

:root {
  --cream: #FBF8F3;
  --coral: #D85A30;
  --coral-light: #FAECE7;
  --blue: #4A90BF;
  --blue-light: #F1F7FB;
  --pink: #C2547A;
  --pink-light: #FDF3F8;
  --teal: #0F6E56;
  --teal-light: #E1F5EE;
  --amber: #C8931A;
  --amber-light: #FCF5E5;
  --ink: #2C2C2A;
  --muted: #888780;
  --border: rgba(44,44,42,0.12);
}

body { font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; background: var(--cream); color: var(--ink); min-height: 100vh; display: flex; flex-direction: column; }
/* Disable browser scroll anchoring globally. The site renders large
   panels (perception, playground, harmony) lazily on every search —
   when those panels grow above the user's current scroll position,
   anchoring jumps the page down by the inserted height, fighting the
   smooth scroll-into-view we already issue ourselves. We always know
   where we want the user to land; let our scrollTo win. */
body, html { overflow-anchor: none; }
.app { max-width: 1100px; width: 100%; margin: 0 auto; padding: 2.5rem 2rem 2rem; display: flex; flex-direction: column; min-height: 100vh; }

.header { text-align: left; margin-bottom: 1.5rem; }
.app-top { flex: 0; padding-top: 1.25rem; }
.app-bottom { flex: 0; }
.logo {
  font-family: 'Lora', 'Lora Fallback', serif; font-size: 48px; color: var(--ink);
  letter-spacing: -0.5px; line-height: 1.15;
  white-space: nowrap;
}
.logo-static { color: var(--ink); }
.logo-name {
  color: #C2547A; font-style: italic;
  display: inline-block;
  vertical-align: baseline;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.logo-name.fade-out {
  opacity: 0;
  transform: translateY(-10px);
  display: inline-block;
}
.logo-name.fade-in-prep {
  opacity: 0;
  transform: translateY(10px);
  display: inline-block;
  transition: none;
}
.logo-name.fade-in {
  opacity: 1;
  transform: translateY(0);
  display: inline-block;
}
.tagline { font-size: 16px; color: var(--muted); margin-top: 6px; margin-left: 4px; letter-spacing: 0.02em; }

/* Trending strip */
.trending-strip { margin-bottom: 1.5rem; }
.strip-label { font-size: 12px; color: var(--muted); letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 10px; }
.gender-toggle { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.gtab { padding: 6px 14px; border-radius: 50px; font-size: 14px; border: 1.5px solid var(--border); background: white; cursor: pointer; transition: all 0.18s; color: var(--muted); }
.gtab.active-g { background: var(--pink); color: white; border-color: var(--pink); }
.gtab.active-b { background: var(--blue); color: white; border-color: var(--blue); }
.gtab.active-u { background: var(--ink); color: white; border-color: var(--ink); }
.gtab.active-x { background: var(--amber); color: white; border-color: var(--amber); }
@keyframes toastIn { from { opacity: 0; transform: translateX(-50%) translateY(20px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
@keyframes toastInMobile { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
@keyframes cleverSnow { 0% { transform: translateY(-10px) rotate(0deg); opacity: 0; } 8% { opacity: 0.7; } 85% { opacity: 0.5; } 100% { transform: translateY(70px) rotate(180deg); opacity: 0; } }
@keyframes cleverPetal { 0% { transform: translate(0, -10px) rotate(0deg); opacity: 0; } 8% { opacity: 0.7; } 85% { opacity: 0.4; } 100% { transform: translate(15px, 70px) rotate(120deg); opacity: 0; } }
@keyframes cleverSun { 0% { transform: scale(0.9); opacity: 0; } 8% { opacity: 0.6; } 50% { transform: scale(1.15); opacity: 0.5; } 92% { opacity: 0.6; } 100% { transform: scale(0.9); opacity: 0; } }
@keyframes cleverLeaf { 0% { transform: translate(0, -10px) rotate(0deg); opacity: 0; } 8% { opacity: 0.7; } 50% { transform: translate(-10px, 30px) rotate(90deg); opacity: 0.6; } 85% { opacity: 0.4; } 100% { transform: translate(5px, 70px) rotate(200deg); opacity: 0; } }
@keyframes busDrive { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
@keyframes busBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } }
@keyframes wheelSpin { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }
/* Bus row sky + clouds */
.bus-card { position: relative; overflow: hidden; container-type: inline-size; }
.bus-card.sky-g { background: linear-gradient(to bottom, #fce4e9 0%, #fdf1f3 60%, #fdf4f5 100%); }
.bus-card.sky-b { background: linear-gradient(to bottom, #d7e6f2 0%, #e8f0f7 60%, #eef4f9 100%); }
.bus-card.sky-u { background: linear-gradient(to bottom, #f9e9c9 0%, #fcf3de 60%, #fdf7e9 100%); }
.bus-card .sky-cloud {
  position: absolute; pointer-events: none; z-index: 0;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.04));
  will-change: transform;
}
.bus-card .sky-cloud-1 { top: 8px;  left: -80px;  animation: cloudDrift1 70s linear infinite; }
.bus-card .sky-cloud-2 { top: 22px; left: -110px; animation: cloudDrift2 95s linear infinite; opacity: 0.75; }
.bus-card .sky-cloud-3 { top: 40px; left: -60px;  animation: cloudDrift3 55s linear infinite; opacity: 0.65; }
/* Animate `transform: translateX` (composited) rather than `left` (layout-
   triggering on every frame). cqw = container-query width unit, so 105cqw
   = 105% of the bus-card's width — same span the old `left: -80px → 105%`
   animation covered, but auto-scales to the card width. */
@keyframes cloudDrift1 { 0% { transform: translateX(0); } 100% { transform: translateX(calc(105cqw + 80px)); } }
@keyframes cloudDrift2 { 0% { transform: translateX(0); } 100% { transform: translateX(calc(108cqw + 110px)); } }
@keyframes cloudDrift3 { 0% { transform: translateX(0); } 100% { transform: translateX(calc(103cqw + 60px)); } }
.bus-card > .bus-line-row,
.bus-card > .bus-info-popover,
.bus-card > .bus-road-area { position: relative; z-index: 1; }
.bus-card .bus-line-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 0 18px 6px;
  flex-wrap: wrap;
}
.bus-card .bus-line-text { flex: 1; min-width: 0; }
/* On narrow viewports the text gets its own full-width row beneath
   the buttons. wrap-reverse makes the wrapped row land ABOVE its
   flow position — so source-order text-then-pill-then-info renders
   as pill (left) + info (right) above text (full width below).
   margin-right:auto on the pill pushes the info icon to the far
   right while the pill stays at the left. */
@media (max-width: 640px) {
  /* Wrap-reverse only kicks in when the spelling toggle is present —
     it gives the pill its own row above the text. Without the toggle
     we keep the desktop layout (text left, info icon top-right inline)
     so the headline stays at the top. */
  .bus-card .bus-line-row:has(.bus-spelling-toggle) {
    flex-wrap: wrap-reverse;
    row-gap: 6px;
  }
  .bus-card .bus-line-row:has(.bus-spelling-toggle) .bus-line-text { flex: 1 0 100%; }
  .bus-card .bus-spelling-toggle { margin-right: auto; }
}
/* Pill button shows different copy on desktop ("+ all spellings",
   short and unobtrusive) vs mobile ("Include all spellings", more
   explicit because the pill stands alone on its own row). */
.bus-card .bus-spelling-toggle .bs-mobile { display: none; }
@media (max-width: 640px) {
  .bus-card .bus-spelling-toggle .bs-desktop { display: none; }
  .bus-card .bus-spelling-toggle .bs-mobile { display: inline; }
}
.bus-card .bus-info-btn {
  flex-shrink: 0; width: 24px; height: 24px; padding: 0;
  border: none; border-radius: 50%;
  background: rgba(255,255,255,0.7); color: var(--muted);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.16s, color 0.16s;
}
.bus-card .bus-info-btn:hover,
.bus-card .bus-info-btn[aria-expanded="true"] { background: white; color: var(--ink); }
.bus-card .bus-info-btn svg { width: 16px; height: 16px; display: block; }
/* Pill that toggles "include all spellings" mode for the bus animation.
   Sits next to the (i) info button so the line/animation can still
   breathe — clicking flips the global state and re-renders the card. */
.bus-card .bus-spelling-toggle {
  flex-shrink: 0; height: 24px; padding: 0 10px;
  border: 1px solid rgba(44,44,42,0.18); border-radius: 50px;
  background: rgba(255,255,255,0.7); color: var(--muted);
  cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 500;
  letter-spacing: 0.01em; user-select: none;
  transition: background 0.16s, color 0.16s, border-color 0.16s;
}
.bus-card .bus-spelling-toggle:hover { background: white; color: var(--ink); border-color: var(--ink); }
.bus-card .bus-spelling-toggle.is-on {
  background: var(--ink); color: white; border-color: var(--ink);
}

/* Class clash card: "Include all N similar spellings" toggle box.
   Uses gender-tinted hover and checked states so the box matches the
   profile's gender accent without competing with the result block
   below. --cp-accent is set inline per-name (pink/blue/amber). */
.cp-include-toggle {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 12px;
  background: rgba(255, 255, 255, 0.55);
  font-size: 14px; color: var(--ink); line-height: 1.5;
  cursor: pointer; user-select: none;
  margin-bottom: 14px;
  transition: background 0.15s, border-color 0.15s;
}
/* Whole box is clickable — keep the pointer cursor across the label,
   variant names, and any inner text so the affordance is consistent
   wherever the user hovers. */
.cp-include-toggle, .cp-include-toggle * { cursor: pointer; }
.cp-include-toggle input[type="checkbox"] {
  margin: 3px 0 0 0; flex-shrink: 0;
  accent-color: var(--cp-accent, var(--ink));
}
.cp-include-toggle.gender-g:hover { background: var(--pink-light); border-color: var(--pink); }
.cp-include-toggle.gender-b:hover { background: var(--blue-light); border-color: var(--blue); }
.cp-include-toggle.gender-u:hover { background: var(--amber-light); border-color: var(--amber); }
.cp-include-toggle.gender-g:has(input:checked) { background: var(--pink-light); border-color: var(--pink); }
.cp-include-toggle.gender-b:has(input:checked) { background: var(--blue-light); border-color: var(--blue); }
.cp-include-toggle.gender-u:has(input:checked) { background: var(--amber-light); border-color: var(--amber); }
.bus-card .bus-info-popover {
  margin: 2px 18px 10px;
  padding: 11px 14px;
  background: rgba(255,255,255,0.88);
  border: 1px solid var(--border); border-radius: 10px;
  animation: busInfoIn 0.18s ease;
}
.bus-card .bus-info-popover[hidden] { display: none; }
.bus-card .bus-info-popover .bi-head {
  font-weight: 600; font-size: 13px; color: var(--ink); margin-bottom: 6px;
}
.bus-card .bus-info-popover ul {
  margin: 0; padding-left: 1.1rem; font-size: 13px; color: var(--muted); line-height: 1.6;
}
.bus-card .bus-info-popover ul li { margin-bottom: 3px; }
.bus-card .bus-info-popover ul li strong { color: var(--ink); }
@keyframes busInfoIn { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .bus-card .sky-cloud { animation: none; }
}
@keyframes babyJump {
  0%   { transform: translateY(0) scale(1); }
  30%  { transform: translateY(-6px) scale(1.15); }
  55%  { transform: translateY(0) scale(0.95); }
  70%  { transform: translateY(-2px) scale(1.02); }
  100% { transform: translateY(0) scale(1); }
}
.convince-emoji img {
  width: 22px;
  height: 22px;
}
.convince-emoji img.jump {
  animation: babyJump 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) forwards;
}
.trending-scroll {
  display: flex;
  gap: 8px;
  padding-bottom: 6px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  scroll-behavior: auto;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  /* Reserve space so the strip doesn't collapse while the 1MB of data
     scripts load and renderTrending() runs — otherwise the cards pop
     the layout down a few lines when they appear. Matches the natural
     height of a .trend-chip (ranks + 20px name + badge + padding). */
  min-height: 92px;
  opacity: 0;
  transition: opacity 0.28s ease;
}
.trending-scroll.ready { opacity: 1; }
.trending-scroll::-webkit-scrollbar { display: none; }
.trending-scroll.is-dragging { cursor: grabbing; }
.trending-track {
  display: flex;
  gap: 8px;
  width: max-content;
  will-change: transform;
}
.trend-chip { flex-shrink: 0; background: white; border: 1px solid var(--border); border-radius: 16px; padding: 12px 16px; cursor: pointer; transition: all 0.18s; min-width: 110px; }
.trend-chip:hover { border-color: var(--hover-color, var(--coral)); }
.tc-rank { font-size: 12px; color: var(--muted); margin-bottom: 2px; }
.tc-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 20px; font-weight: 500; margin: 4px 0; }
.tc-name.girl { color: var(--pink); }
.tc-name.boy  { color: var(--blue); }
.tc-name.unisex { color: var(--amber); }
.tc-badge { font-size: 12px; padding: 2px 8px; border-radius: 50px; margin-top: 4px; display: inline-block; }
.up { background: var(--teal-light); color: var(--teal); }
.down { background: #FEE; color: #A32D2D; }
.flat { background: var(--amber-light); color: #7A4A0E; }

.ad-unit {
  display: none;
  margin: 1.5rem 0 0.5rem;
  text-align: center;
  min-height: 90px;
  position: relative;
}
.ad-unit.visible { display: block; }
.ad-unit ins { min-height: 90px; }
/* Mock placeholder — shown until real ad loads */
.ad-unit.visible:not(:has(ins[data-ad-status="filled"]))::before {
  content: 'Ad will appear here once approved by Google';
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  inset: 0;
  background: #F5F5F3;
  border: 1.5px dashed var(--border);
  border-radius: 10px;
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.02em;
  pointer-events: none;
  min-height: 90px;
}

@keyframes babyBounce {
  0%   { transform: translateY(0) rotate(0deg); }
  45%  { transform: translateY(-8px) rotate(12deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
.convince-emoji img.bounce {
  animation: babyBounce 0.55s cubic-bezier(0.33, 0, 0.66, 1) forwards;
}
.gift-emoji {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  overflow: visible;
}
.gift-emoji img {
  width: 44px;
  height: auto;
  object-fit: contain;
  margin-left: -8px;
  mix-blend-mode: multiply;
}

.convince-bar {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 16px;
  font-size: 15px;
  width: 100%;
  flex-wrap: wrap;
  margin-top: 0;
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 0.2s;
  position: relative;
}
.convince-bar.visible { display: flex; }
.convince-bar:hover { border-color: var(--ink); }
.convince-bar-text { color: #7A7973; flex: 1; min-width: 0; }
/* Pair-mode tints — applied when the convince + veto bars sit side by
   side as the primary CTA row. Subtle coloured backgrounds so the row
   reads as a clear positive/negative pair without shouting. */
.convince-bar.cta-pair {
  background: color-mix(in srgb, var(--teal) 6%, white);
  border-color: color-mix(in srgb, var(--teal) 22%, var(--border));
}
.convince-bar.cta-pair:hover {
  border-color: var(--teal);
  background: color-mix(in srgb, var(--teal) 10%, white);
}
.convince-bar.cta-pair .convince-bar-text strong { color: var(--teal); font-weight: 700; }
/* When the new copy is showing — "Make the case for X to your partner"
   on desktop, "Make the case to your partner" on mobile — the WHOLE
   line gets the teal colour at a single semibold weight. Flattens
   the bold/non-bold contrast that the <strong> created so the line
   reads as one phrase, not two. */
.convince-bar.cta-pair .cta-text-desktop,
.convince-bar.cta-pair .cta-text-desktop strong,
.convince-bar.cta-pair .cta-text-mobile,
.convince-bar.cta-pair .cta-text-mobile strong { color: var(--teal); font-weight: 500; }
.convince-bar.cta-pair .convince-emoji svg { width: 22px; height: 22px; display: block; color: var(--teal); }
.convince-bar.cta-pair .convince-bar-cta::after { color: var(--teal); }
.convince-bar-cta {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
  margin-left: auto;
  font-size: 0;
  line-height: 1;
}
.convince-bar-cta span { display: none; }
.convince-bar-cta::before { content: ''; position: absolute; inset: 0; z-index: 1; }
.convince-bar-cta::after { content: '→'; font-size: 18px; color: var(--ink); position: relative; top: 1px; }
.convince-emoji {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  font-size: 20px;
}

.gift-inline {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 16px;
  font-size: 15px;
  width: 100%;
  flex-wrap: wrap;
  cursor: pointer;
  transition: border-color 0.2s;
  text-decoration: none;
  position: relative;
}

/* Veto-inline mirrors .convince-bar so the two paid CTAs sit as a
   matched pair in the .card-cta-row grid. The only visual difference
   is the red-tinted "no" icon (matches the veto-btn elsewhere on the
   page) — same shape, copy congruent ("Make the case FOR / AGAINST"),
   so the row reads as a single "tell your partner" affordance. */
.veto-inline {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 16px;
  font-size: 15px;
  width: 100%;
  flex-wrap: wrap;
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color 0.2s;
  position: relative;
  font-family: inherit;
  color: inherit;
}
.veto-inline.visible { display: flex; }
.veto-inline:hover { border-color: var(--ink); }
.veto-inline:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.veto-inline-text { color: #7A7973; flex: 1; min-width: 0; }
.veto-inline-text strong { color: #A8543C; font-weight: 700; }
/* Pair-mode tint — matches the convince-bar.cta-pair so the row reads
   as a positive/negative pair. */
.veto-inline.cta-pair {
  background: color-mix(in srgb, #A8543C 6%, white);
  border-color: color-mix(in srgb, #A8543C 22%, var(--border));
}
.veto-inline.cta-pair:hover {
  border-color: #A8543C;
  background: color-mix(in srgb, #A8543C 10%, white);
}
.veto-inline.cta-pair .veto-inline-cta::after { color: #A8543C; }
.veto-inline.cta-pair .cta-text-desktop,
.veto-inline.cta-pair .cta-text-desktop strong,
.veto-inline.cta-pair .cta-text-mobile,
.veto-inline.cta-pair .cta-text-mobile strong { color: #A8543C; font-weight: 500; }
.veto-bar-emoji {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex-shrink: 0;
  color: #A8543C;
}
.veto-bar-emoji svg { width: 22px; height: 22px; display: block; }
.veto-inline-cta {
  white-space: nowrap; flex-shrink: 0; margin-left: auto;
  font-size: 0; line-height: 1; position: relative;
}
.veto-inline-cta::after {
  content: '→'; font-size: 18px; color: var(--ink);
  position: relative; top: 1px;
}
@media (max-width: 640px) {
  .veto-inline {
    display: none;
    grid-template-columns: 26px 1fr auto;
    grid-template-rows: auto;
    gap: 0; column-gap: 8px;
    padding: 9px 12px 9px 10px;
    align-items: center;
  }
  .veto-inline.visible { display: grid; }
  .veto-bar-emoji { grid-column: 1; grid-row: 1; }
  .veto-inline-text { grid-column: 2; grid-row: 1; font-size: 14px; line-height: 1.25; }
  .veto-inline-cta { grid-column: 3; grid-row: 1; margin: 0; }
  .veto-inline-cta::after { font-size: 16px; }
  .veto-inline.cta-pair .veto-bar-emoji svg { width: 20px; height: 20px; }
}
.gift-inline.visible { display: flex; }
.gift-inline:hover { border-color: var(--ink); }
.gift-inline a {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
  margin-left: auto;
  font-size: 0;
  line-height: 1;
}
.gift-inline a span { display: none; }
.gift-inline a::before { content: ''; position: absolute; inset: 0; z-index: 1; }
.gift-inline a::after { content: '→'; font-size: 18px; color: var(--ink); position: relative; top: 1px; }
.gift-inline-text { color: #7A7973; flex: 1; min-width: 0; }
@media (max-width: 640px) {
  .convince-bar {
    display: none;
    grid-template-columns: 26px 1fr auto;
    grid-template-rows: auto;
    gap: 0;
    column-gap: 8px;
    padding: 9px 12px 9px 10px;
    align-items: center;
  }
  .convince-bar.visible {
    display: grid;
  }
  .convince-emoji { grid-column: 1; grid-row: 1; }
  .convince-bar-text { grid-column: 2; grid-row: 1; font-size: 14px; line-height: 1.25; }
  .convince-bar-cta { grid-column: 3; grid-row: 1; margin: 0; }
  .convince-bar-cta::after { font-size: 16px; }
  .convince-bar.cta-pair .convince-emoji svg { width: 20px; height: 20px; }
}

/* ── Gift band — affiliate placement at the bottom of each panel ──
   Sits flush against the card's bottom edge (negative horizontal +
   bottom margins cancel the 1.75rem parent padding) so it reads as a
   footer band rather than another rounded card competing with the UI
   above. Background is gender-tinted inline; mix-blend-mode: multiply
   on the Amazon logo makes its white ground effectively transparent
   over that tint, so the wordmark sits cleanly and the hover state
   reads. */
.gift-band {
  display: none;
  align-items: center;
  gap: 8px;
  margin: 2rem -1.75rem -1.75rem;
  padding: 11px 1.5rem 11px 1.25rem;
  background: var(--cream);
  border-top: 1px solid var(--border);
  border-radius: 0 0 19px 19px;
  text-decoration: none;
  color: var(--ink);
  transition: filter 0.15s;
}
.gift-band.visible { display: flex; }
.gift-band:hover { filter: brightness(0.97); }
.gift-band-emoji {
  flex-shrink: 0; width: 44px; height: 32px;
  display: flex; align-items: center; justify-content: flex-start;
  overflow: visible;
}
.gift-band-emoji img {
  width: 52px; height: auto; max-height: 32px;
  display: block; object-fit: contain;
  mix-blend-mode: multiply;
}
.gift-band-text { flex: 1; min-width: 0; font-size: 15px; color: var(--ink); }
.gift-band-arrow { color: var(--muted); font-size: 18px; flex-shrink: 0; line-height: 1; }
@media (max-width: 640px) {
  /* Negative margin matches the .harmony-tool / .class-tool 1.75rem
     mobile padding so the band bleeds flush to the rounded card edge
     instead of leaving a 0.5rem gap on each side. */
  .gift-band { margin: 1.5rem -1.75rem -1.75rem; padding: 10px 1rem 10px 0.75rem; border-radius: 0 0 19px 19px; }
  .gift-band-emoji { width: 40px; height: 28px; }
  .gift-band-emoji img { width: 46px; max-height: 28px; }
  /* "Find " is hidden on mobile — capitalise the next visible letter
     ("personalised" → "Personalised") so the band reads as a proper
     sentence start. */
  .gift-band-text:first-letter { text-transform: uppercase; }
}

.au-xref-hint {
  margin-top: 1rem;
  padding: 18px 20px;
  background: white;
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 16px;
  cursor: pointer;
  transition: box-shadow 0.2s;
  text-align: left;
}
.au-xref-hint:hover {
  box-shadow: 0 2px 10px rgba(0,0,0,0.08);
}
.au-xref-hint-flag { font-size: 40px; line-height: 1; flex-shrink: 0; }
.au-xref-hint-text { flex: 1; min-width: 0; }
.au-xref-hint-title { font-size: 15px; font-weight: 500; color: var(--ink); }
.au-xref-hint-sub { font-size: 13px; color: var(--muted); margin-top: 4px; }
.au-xref-hint-arrow { margin-left: auto; color: var(--muted); font-size: 16px; flex-shrink: 0; }

.gift-find { display: inline; }
@media (max-width: 640px) {
  .gift-find { display: none; }
  .gift-inline-text:first-letter { text-transform: uppercase; }
  .gift-inline {
    display: none;
    grid-template-columns: 28px 1fr auto;
    grid-template-rows: auto;
    gap: 0;
    column-gap: 10px;
    padding: 9px 14px 9px 12px;
    align-items: center;
  }
  .gift-inline.visible {
    display: grid;
  }
  .gift-emoji { grid-column: 1; grid-row: 1; align-self: center; }
  .gift-inline-text { grid-column: 2; grid-row: 1; font-size: 14px; line-height: 1.25; }
  .gift-inline a { grid-column: 3; grid-row: 1; margin: 0; }
}
/* Two text variants per CTA bar — the desktop copy keeps the name
   ("Send your partner the case for Name") while the mobile copy
   reframes for the narrow column ("Make the case to your partner").
   Verb-led mobile copy reads punchier and always fits one line. */
.cta-text-mobile { display: none; }
@media (max-width: 640px) {
  .cta-text-desktop { display: none; }
  .cta-text-mobile { display: inline; }
}
/* Wrap convince-bar + gift-inline so they sit side-by-side on desktop. */
.card-cta-row { display: contents; }
.card-cta-row > .gift-inline { margin-bottom: 1.25rem; }
/* On mobile the bars stack one above the other (display: contents).
   The last bar in the row needs the same breathing room before the
   following content (page title, section header) that the desktop
   grid gets via its own margin-bottom — the inherited 8px wasn't
   enough. */
@media (max-width: 640px) {
  .card-cta-row > .veto-inline.cta-pair { margin-bottom: 1.25rem; }
}
@media (min-width: 641px) {
  .card-cta-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 1.25rem; }
  .card-cta-row > .convince-bar, .card-cta-row > .gift-inline, .card-cta-row > .veto-inline { margin-bottom: 0 !important; }
}
.section-divider { border: none; border-top: 1px solid var(--border); margin: 0 0 2rem; }
.story-input::placeholder { color: #AFADA3; opacity: 1; }
.story-input::-webkit-input-placeholder { color: #AFADA3; }
.story-input:focus { border-color: var(--ink); }
.story-heart-btn {
  flex-shrink: 0; align-self: center;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px; border-radius: 50px;
  border: 1px solid var(--border); background: white;
  color: var(--muted); font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 12px; font-weight: 500; cursor: pointer;
  transition: all 0.15s;
}
.story-heart-btn:hover { border-color: #B8943E; color: #B8943E; }
.story-heart-btn.loved { border-color: #B8943E; color: #B8943E; }
.story-heart-btn.loved svg { animation: heartPop 0.3s ease; }

/* Search bar */
.search-wrap { position: relative; margin-bottom: 1.5rem; }
.search-row { display: flex; gap: 8px; align-items: center; }

.country-btn-inline {
  display: flex; align-items: center; gap: 6px;
  padding: 13px 14px; border-radius: 50px;
  border: 1.5px solid rgba(44,44,42,0.15); background: var(--cream);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 15px; font-weight: 500; color: var(--ink);
  cursor: pointer; transition: background 0.2s; white-space: nowrap;
  user-select: none; flex-shrink: 0;
}
.country-btn-inline:hover { background: #EDE9E0; }
.country-btn-inline.open { background: #EDE9E0; }

.country-dropdown { position: relative; flex-shrink: 0; }
.country-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 15px 16px; border-radius: 50px;
  border: 1.5px solid var(--border); background: white;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 15px; color: var(--ink);
  cursor: pointer; transition: border-color 0.2s; white-space: nowrap;
  user-select: none;
}
.country-btn:hover { border-color: var(--ink); }
.country-btn.open { border-color: var(--coral); }
.country-btn .chevron, .country-btn-inline .chevron {
  width: 10px; height: 6px; margin-left: 2px; transition: transform 0.2s;
  flex-shrink: 0;
}
.country-btn.open .chevron, .country-btn-inline.open .chevron { transform: rotate(180deg); }
/* Country-button chevron — the V-shape's ink mass sits in the upper
   half of the viewBox (wings at y=1, apex at y=5), so a geometric
   center-align reads visually high next to the flag/text. Nudging
   down 1px in transform realigns it with the optical centre of
   "UK" / "US" / "AU" in the button. flex-shrink keeps it from
   collapsing on tight widths. */
.country-chevron {
  width: 8px; height: 5px; margin-left: 3px; flex-shrink: 0;
  transform: translateY(1px); transition: transform 0.2s;
}
.country-btn.open .country-chevron, .country-btn-inline.open .country-chevron {
  transform: translateY(1px) rotate(180deg);
}
/* The flag emoji + country text span sit a fraction below the
   button's optical centre on iOS — emoji glyphs render with extra
   space below the baseline, so the visible mass lands low. Pulling
   the label up 1px aligns it with the chevron's adjusted centre so
   all three (flag, text, chevron) read centered. Scoped to the
   mobile row only — on desktop the larger button padding makes
   the same offset read as too-high. */
.mobile-country-row .country-btn-inline > span,
.country-btn > span {
  transform: translateY(-1px);
}
.country-menu {
  display: none; position: absolute; top: calc(100% + 6px); left: 0;
  background: white; border: 1.5px solid var(--border); border-radius: 16px;
  overflow: hidden; z-index: 9999; min-width: 130px;
  box-shadow: 0 8px 24px rgba(44,44,42,0.1);
  padding: 6px 0;
}
.country-menu.open { display: block; }
.country-option {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 20px; font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 14px; color: var(--ink); cursor: pointer;
  transition: background 0.12s;
}
.country-option .flag {
  font-style: normal; display: inline-block;
  width: 20px; text-align: center; flex-shrink: 0;
}
.country-option:hover { background: var(--cream); }
.country-option.selected { color: var(--coral); font-weight: 500; }

.name-input-wrap { position: relative; flex: 1; }
.name-input-wrap input {
  width: 100%; padding: 18px 190px 18px 24px; border-radius: 50px;
  border: 1.5px solid var(--border); background: white;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 16px; color: var(--ink);
  outline: none; transition: border-color 0.2s;
}
.name-input-wrap input:focus { border-color: var(--border); outline: none; }
.name-input-wrap input::placeholder { color: var(--muted); }
.search-actions { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 8px; }
.clear-btn {
  width: 28px; height: 28px; border-radius: 50%; border: none; background: #E8E4DC;
  color: var(--muted); font-size: 18px; line-height: 28px; cursor: pointer; display: none;
  align-items: center; justify-content: center; transition: background 0.15s; flex-shrink: 0;
  margin-right: 4px;
  font-family: Arial, sans-serif;
  padding: 0;
}
.clear-btn:hover { background: #CCC9C0; color: var(--ink); }
.search-btn {
  padding: 13px 24px; border-radius: 50px; border: none;
  background: var(--ink); color: white;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 15px; font-weight: 500;
  cursor: pointer; transition: opacity 0.2s, background 0.2s; white-space: nowrap;
}
.search-btn:hover:not(:disabled) { opacity: 0.78; }
.search-btn:disabled { background: #E8E4DC; color: #BBB8B0; cursor: not-allowed; opacity: 1; }

@media (max-width: 640px) {
  .app { padding: 1.5rem 1rem 3rem; }
  .logo { font-size: 32px; }
  .tagline { font-size: 13px; }
  .search-section { padding: 1.25rem; text-align: left; margin-top: 2rem; }
  .search-section-title { font-size: 20px; margin-bottom: 1rem; }
  .mobile-country-row { display: flex !important; margin-bottom: 8px; }
  .mobile-country-row .country-btn-inline { padding: 7px 12px; font-size: 13px; border-radius: 50px; }
  .desktop-country { display: none !important; }
  .name-input-wrap input { font-size: 16px !important; padding: 12px 100px 12px 14px !important; }
  .search-btn { padding: 8px 16px !important; font-size: 14px !important; }
  .sub-tabs { gap: 6px; margin-top: 1.5rem; }
  .sub-tabs.visible { padding: 12px 0; margin-top: calc(1.5rem - 12px); margin-bottom: calc(1.5rem - 12px); }
  /* .stab padding/font defined later in the second mobile @media block
     so the global .stab rule (line 846) doesn't override on source order. */
  .name-title { font-size: 32px; }
  .name-result-card { padding: 1.25rem; }
  .harmony-inputs { flex-direction: column; }
  .score-ring-wrap { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .trend-chip { min-width: 90px; padding: 8px 10px; }
  .tc-name { font-size: 16px; }
  .trending-strip { margin-top: 3rem !important; }
}

@media (min-width: 641px) {
  .mobile-country-row { display: none; }
  .desktop-country { display: flex; }
}

.mobile-country-row { display: none; }

/* Search section */
.search-section { margin-top: 2.875rem; padding: 2.5rem; background: white; border-radius: 20px; border: 1px solid var(--border); text-align: center; overflow: visible; }
.search-section-title { font-family: 'Lora', 'Lora Fallback', serif; font-size: 24px; font-weight: 600; color: var(--ink); margin-bottom: 1.25rem; }

.sub-tabs { display: none; gap: 8px; margin-top: 2rem; margin-bottom: 1.5rem; }
.sub-tabs.visible {
  display: block;
  position: sticky;
  top: var(--topnav-h, 56px);
  z-index: 50;
  padding: 22px 0 15px;
  margin-top: calc(2rem - 22px);
  margin-bottom: calc(1.5rem - 15px);
}
.stab-scroll { display: flex; flex-wrap: wrap; gap: 8px; }
/* Full-viewport cream background via a pseudo so the pinned bar visually
   spans edge-to-edge. top:-1px bleeds 1px upward to hide subpixel gap
   without offsetting the element itself (which would cause a 1px jump). */
.sub-tabs.visible::before {
  content: '';
  position: absolute;
  top: -1px; bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  background: var(--cream);
  z-index: -1;
  pointer-events: none;
  transition: box-shadow 0.22s ease;
}
.sub-tabs.visible.stuck-scrolled::before {
  box-shadow: 0 6px 12px -4px rgba(20, 20, 20, 0.12);
}
.stab { flex: 1; text-align: center; padding: 8px 14px; border-radius: 50px; font-size: 13px; font-weight: 500; border: 1.5px solid var(--active-tab-color, var(--border)); background: white; cursor: pointer; transition: all 0.18s; color: var(--active-tab-color, var(--muted)); white-space: nowrap; }
.stab.active { background: var(--active-tab-color, var(--ink)); color: white; border-color: var(--active-tab-color, var(--ink)); position: relative; }
/* ── Tab hint: Mexican wave ──────────────────────────────── */
@keyframes tabWave {
  0% { transform: translateY(0); }
  35% { transform: translateY(-5px); border-color: var(--active-tab-color, var(--ink)); }
  70% { transform: translateY(0); }
  100% { transform: translateY(0); }
}
.stab-scroll.anim-a .stab:not(.active) { animation: tabWave 0.5s ease; }
.stab-scroll.anim-a .stab:not(.active):nth-child(2) { animation-delay: 0s; }
.stab-scroll.anim-a .stab:not(.active):nth-child(3) { animation-delay: 0.1s; }
.stab-scroll.anim-a .stab:not(.active):nth-child(4) { animation-delay: 0.2s; }
.stab-scroll.anim-a .stab:not(.active):nth-child(5) { animation-delay: 0.3s; }
.stab-scroll.anim-a .stab:not(.active):nth-child(6) { animation-delay: 0.4s; }
.stab.active::after { content: ''; position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 7px solid var(--active-tab-color, var(--ink)); }
@media (hover: hover) {
  .stab:hover:not(.active) { border-color: var(--active-tab-color, var(--ink)); color: var(--active-tab-color, var(--ink)); background: color-mix(in srgb, var(--active-tab-color, var(--ink)) 8%, white); }
}
@media (max-width: 640px) {
  .stab.active::after { display: none; }
  .stab-scroll.anim-a .stab:not(.active) { animation: none; }
  /* Horizontal-scroll tab strip on mobile */
  .stab-scroll {
    flex-wrap: nowrap;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .stab-scroll::-webkit-scrollbar { display: none; }
  .stab-scroll.fade-right {
    mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
  }
  .stab-scroll.fade-both {
    mask-image: linear-gradient(to right, transparent 0%, black 32px, black calc(100% - 32px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 32px, black calc(100% - 32px), transparent 100%);
  }
  .stab-scroll.fade-left {
    mask-image: linear-gradient(to right, transparent 0%, black 32px);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 32px);
  }
  /* Bigger horizontal padding on mobile so the third tab clearly
     cuts off mid-word inside the fade mask, making the horizontal
     scroll affordance unmistakable. Defined here (not in the
     earlier mobile @media block at line 783) because the global
     .stab rule below it has the same specificity and would
     otherwise win on source order. */
  .stab { flex: none; font-size: 13px; padding: 7px 18px; }
}

/* Single-page scroll layout: all panels visible and stacked. The .active
   class is still toggled, but now only drives the sticky feature-nav tab
   highlighting (scrollspy) — not panel visibility. */
.panel { display: block; }
.panel + .panel { margin-top: 2.5rem; }
/* Pre-search home state: only the #explore panel (hero + empty state) is
   visible. The other four tool panels stack into view after a name search
   alongside the sticky sub-tabs bar. SSR name pages strip this class. */
body.pre-search .panel:not(#explore):not(#shortlist) { display: none; }

/* SSR fallback: server-rendered name card is in the HTML for SEO/crawlers
   but hidden visually so users never see the unstyled FOUC before JS
   hydrates and replaces it with the live name card. Search engines render
   display:none content fine. */
.ssr-name-card { display: none; }

/* Name card */
.name-result-card { background: white; border-radius: 20px; border: 1px solid var(--border); padding: 1.75rem; margin-bottom: 1.25rem; }
.name-title { font-family: 'Lora', 'Lora Fallback', serif; font-size: 40px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.name-meta { font-size: 14px; color: var(--muted); margin-bottom: 1.25rem; }
.name-origin-crumb { margin-bottom: 10px; }
.name-origin-crumb-link { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px 5px 9px; border-radius: 50px; background: var(--cream); border: 1px solid var(--border); font-size: 13px; font-weight: 500; text-decoration: none; color: var(--muted); transition: border-color 0.15s, background 0.15s; cursor: pointer; }
.name-origin-crumb-link:hover { background: white; }
.name-origin-crumb-link.girl:hover   { border-color: var(--pink); }
.name-origin-crumb-link.boy:hover    { border-color: var(--blue); }
.name-origin-crumb-link.unisex:hover { border-color: var(--amber); }
.name-origin-crumb-arrow { width: 13px; height: 13px; flex-shrink: 0; display: block; }
.name-origin-crumb-label { color: var(--muted); }
.name-origin-crumb-link.girl   .name-origin-crumb-name { color: var(--pink); }
.name-origin-crumb-link.boy    .name-origin-crumb-name { color: var(--blue); }
.name-origin-crumb-link.unisex .name-origin-crumb-name { color: var(--amber); }
.name-origin-crumb-name { font-weight: 500; }
.name-variants { font-size: 14px; color: var(--muted); margin: -0.75rem 0 1.25rem; line-height: 1.5; }
.name-variant-link { font-weight: 500; text-decoration: none; cursor: pointer; transition: opacity 0.15s, text-decoration-color 0.15s; }
.name-variant-link.girl   { color: var(--pink); }
.name-variant-link.boy    { color: var(--blue); }
.name-variant-link.unisex { color: var(--amber); }
.name-variant-link:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }

/* "Show combined popularity" inline expander next to the See also chips.
   Colour matches the share-name button (#676766) so it sits at the same
   visual weight as other secondary actions on the profile. */
.cp-expand {
  background: transparent; border: 0; padding: 0;
  font-family: inherit; font-size: 14px; color: #676766;
  font-weight: 500; cursor: pointer; text-decoration: underline;
  text-decoration-color: rgba(103, 103, 102, 0.4); text-underline-offset: 3px;
}
.cp-expand:hover { color: var(--ink); text-decoration-color: var(--ink); }
.cp-expand .cp-expand-hide { display: none; }
.cp-expand[aria-expanded="true"] .cp-expand-show { display: none; }
.cp-expand[aria-expanded="true"] .cp-expand-hide { display: inline; }

/* The collapsible interactive box. Sits inline under the See also line.
   Full-width inside its parent so the header, explanation, and rows
   have room to breathe — was max-width 380px which felt cramped. */
.combined-pop {
  margin: 0.75rem 0 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border); border-radius: 12px;
  background: rgba(255, 255, 255, 0.55);
  overflow: hidden;
}
.combined-pop[hidden] { display: none; }
.combined-pop .cp-header {
  font-family: 'Lora', 'Lora Fallback', serif;
  font-size: 18px; font-weight: 600; color: var(--ink);
  margin-bottom: 6px;
}
.combined-pop .cp-hint {
  font-size: 15px; color: var(--muted); margin-bottom: 14px; line-height: 1.5;
}
.combined-pop .cp-hint strong { color: var(--ink); font-weight: 500; }
.cp-rows { display: flex; flex-direction: column; gap: 2px; }
.cp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 8px;
  cursor: pointer; user-select: none;
  transition: background 0.12s, opacity 0.12s;
}
.cp-row:hover { background: rgba(44, 44, 42, 0.05); }
.cp-row .cp-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 4px;
  background: var(--ink); color: white; font-size: 10px; line-height: 1;
  flex-shrink: 0;
}
.cp-row .cp-name-wrap {
  flex: 1; display: flex; align-items: baseline; gap: 7px; min-width: 0;
}
/* `.cp-name` uses a pseudo-element strike-through (instead of
   text-decoration: line-through) so the line sits at the visual centre
   of the glyph across fonts — DM Sans rendered the default line a few
   px above centre. The pseudo doesn't extend to the THIS NAME tag,
   which sits as a sibling and stays readable when the row is excluded. */
.cp-row .cp-name {
  display: inline-block; position: relative;
  color: var(--ink); font-size: 14px; font-weight: 500;
}
.cp-row .cp-tag {
  font-size: 11px; font-weight: 400; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.cp-row .cp-births { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.cp-row.cp-excluded { opacity: 0.42; }
.cp-row.cp-excluded .cp-check { background: transparent; color: var(--muted); border: 1px solid var(--border); }
.cp-row.cp-excluded .cp-name::after {
  content: ''; position: absolute;
  left: 0; right: 0; top: 50%;
  border-top: 1.5px solid currentColor;
  transform: translateY(-50%);
}
.combined-pop .cp-summary {
  /* Negative horizontal margin punches through the parent's 1.1rem
     padding so the separator and tinted background span edge-to-edge.
     The bottom margin/padding rebalances so the tint ends flush with
     the box's bottom border. Neutral warm-grey tint — gender-light
     palettes were tried but collided with the pink/blue meaning card
     that often sits directly below this box. */
  margin: 12px -1.1rem -1rem;
  padding: 12px calc(1.1rem + 10px) 14px;
  border-top: 1px solid var(--border);
  background: rgba(44, 44, 42, 0.045);
}
.combined-pop .cp-summary-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-weight: 600; font-size: 15px; color: var(--ink);
}
.combined-pop .cp-summary-row > span:last-child { font-size: 18px; font-variant-numeric: tabular-nums; }
.combined-pop .cp-rank-line { font-size: 13px; color: var(--muted); margin-top: 4px; }
.dym-suggest { font-size: 14px; color: var(--muted); margin: -0.25rem 0 1rem; line-height: 1.5; }
.dym-suggest .dym-link { color: var(--ink); font-weight: 600; text-decoration: underline; }
.dym-suggest .dym-dismiss { color: var(--muted); font-size: 12px; margin-left: 6px; text-decoration: underline; cursor: pointer; }
.dym-suggest .dym-dismiss:hover { color: var(--ink); }
.dym-suggest .dym-kept { color: var(--ink); font-weight: 500; }
.stat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 1.25rem; }
.stat-box { background: var(--cream); border: 1px solid var(--border); border-radius: 14px; padding: 14px; text-align: center; }
.stat-box .stat-num { font-size: 22px; font-weight: 500; }
.stat-box .stat-lbl { font-size: 12px; color: var(--muted); margin-top: 3px; letter-spacing: 0.03em; text-transform: uppercase; }
/* Stats unified to ink — the page already carries the gender accent on
   the name title and the new green/red pair on the CTA bars; tinting
   the three stat numbers in three more colours added noise. Ink lets
   the values do the work. */
.stat-box.coral .stat-num,
.stat-box.teal .stat-num,
.stat-box.amber .stat-num { color: var(--ink); }
/* Vintage variant — used for historic-only names where the stat boxes
   carry years and peak counts rather than current rank/births. Parchment
   tint + dashed border + serif numbers + a tilted "VINTAGE" stamp on the
   peak-births box (the standout stat) so the whole row reads instantly
   as "this is from the archive" rather than current data.
   Layout reorders so users see the timeline left-to-right:
   last registered → peak births (the headline) → classroom clash. */
.stat-row.vintage-row {
  margin-top: 1.5rem;
}
.stat-row.vintage-row > :nth-child(1) { order: 2; position: relative; overflow: visible; }
.stat-row.vintage-row > :nth-child(2) { order: 1; }
.stat-row.vintage-row > :nth-child(3) { order: 3; }
.stat-row.vintage-row > :nth-child(1)::before {
  content: "VINTAGE";
  position: absolute;
  top: -14px; right: -10px;
  font-family: 'Lora', serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: #9C7A2E;
  background: #FBF8F3;
  border: 1.5px solid #C8931A;
  border-radius: 4px;
  padding: 3px 9px 2px;
  transform: rotate(-6deg);
  box-shadow: 0 1px 0 rgba(200, 147, 26, 0.15);
  pointer-events: none;
  z-index: 2;
  animation: vintageStampIn 0.5s cubic-bezier(.18,.85,.36,1.15) both;
}
.stat-box.vintage {
  background: #F5EEDE;
  border: 1px dashed rgba(156, 122, 46, 0.45);
}
.stat-box.vintage .stat-num {
  color: #5A4A1F;
  font-family: 'Lora', 'Lora Fallback', serif;
  font-weight: 500;
  letter-spacing: 0.005em;
}
.stat-box.vintage .stat-lbl {
  color: rgba(90, 74, 31, 0.7);
}
@keyframes vintageStampIn {
  0%   { opacity: 0; transform: rotate(-14deg) scale(1.6); }
  60%  { opacity: 1; transform: rotate(-3deg) scale(0.94); }
  100% { opacity: 1; transform: rotate(-6deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .stat-row.vintage-row > :nth-child(1)::before { animation: none; }
}

/* Rare variant — used for names that didn't make the modern top-rank
   dataset but have had at least one registration in the last
   VINTAGE_GAP_YEARS years. Layout stays identical to the regular row
   so the rank/registered/clash hierarchy is preserved; only the
   tilted "RARE" stamp on the registered box flags it as a niche
   pick — pairs naturally with the "0" registration count. The stamp
   uses a calmer teal-on-cream palette to read as "uncommon" rather
   than "from the archive" (which is what VINTAGE conveys). */
.stat-row.rare-row > :nth-child(2) { position: relative; overflow: visible; }
.stat-row.rare-row > :nth-child(2)::before {
  content: "RARE";
  position: absolute;
  top: -14px; right: -10px;
  font-family: 'Lora', serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  /* Default (unisex): brand teal, matching the site's "uncommon"
     accent. Gender-leaning rare names override the colour set below
     so the stamp visually echoes the rest of the profile (pink for
     girls, blue for boys). */
  color: var(--rare-stamp-color, var(--teal));
  background: var(--rare-stamp-bg, var(--teal-light));
  border: 1.5px solid var(--rare-stamp-border, var(--teal));
  border-radius: 4px;
  padding: 3px 9px 2px;
  transform: rotate(-6deg);
  box-shadow: 0 1px 0 var(--rare-stamp-shadow, rgba(31, 139, 112, 0.15));
  pointer-events: none;
  z-index: 2;
  animation: vintageStampIn 0.5s cubic-bezier(.18,.85,.36,1.15) both;
}
.stat-row.rare-row-girl {
  --rare-stamp-color: var(--pink);
  --rare-stamp-bg: var(--pink-light);
  --rare-stamp-border: var(--pink);
  --rare-stamp-shadow: rgba(194, 84, 122, 0.18);
}
.stat-row.rare-row-boy {
  --rare-stamp-color: var(--blue);
  --rare-stamp-bg: var(--blue-light);
  --rare-stamp-border: var(--blue);
  --rare-stamp-shadow: rgba(74, 144, 191, 0.18);
}
@media (prefers-reduced-motion: reduce) {
  .stat-row.rare-row > :nth-child(2)::before { animation: none; }
}
.prob-bar-wrap { margin-bottom: 1rem; }
.prob-label { font-size: 14px; color: var(--muted); margin-bottom: 6px; display: flex; justify-content: space-between; }
.prob-bar { height: 8px; border-radius: 99px; background: #EEE; overflow: hidden; }
.prob-fill { height: 100%; border-radius: 99px; transition: width 0.6s cubic-bezier(.4,0,.2,1); }
.insight-pill { display: inline-block; padding: 6px 14px; border-radius: 50px; font-size: 13px; font-weight: 500; margin: 4px 4px 0 0; }
.pill-coral { background: var(--coral-light); color: #993C1D; }
.pill-teal { background: var(--teal-light); color: #0F6E56; }
.pill-amber { background: var(--amber-light); color: #7A4A0E; }
.perception-summary { font-size: 18px; line-height: 1.45; color: var(--ink); margin-bottom: 8px; }
.perception-summary strong { font-weight: 500; }
.perception-rate-cta {
  flex-shrink: 0; padding: 7px 14px; font: inherit; font-size: 13px; font-weight: 500;
  border: 1px solid var(--perception-accent, var(--ink));
  border-radius: 50px; background: var(--perception-accent, var(--ink)); color: white;
  cursor: pointer; transition: filter 0.15s, transform 0.1s; white-space: nowrap;
}
/* Desktop-only nudge: pull the button up a few px so it optically aligns
   with the cap-height of the 'Based on X ratings' text. Mobile keeps its
   natural baseline. */
@media (hover: hover) and (min-width: 521px) {
  .perception-rate-cta { transform: translateY(-3px); }
  .perception-rate-cta:active { transform: translateY(-3px) scale(0.97); }
}
.perception-rate-cta:hover { filter: brightness(0.92); }
.perception-rate-cta:active { transform: scale(0.97); }

/* Rating modal — BTN-style 3-option picker for all 13 traits at once. */
.perception-rate-modal {
  position: fixed; inset: 0; z-index: 1050; display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transition: opacity 0.18s ease;
}
.perception-rate-modal.open { opacity: 1; pointer-events: auto; }
.perception-rate-modal.girl   { --perception-accent: var(--pink); }
.perception-rate-modal.boy    { --perception-accent: var(--blue); }
.perception-rate-modal.unisex { --perception-accent: var(--amber); }
.perception-rate-backdrop { position: absolute; inset: 0; background: rgba(20, 20, 20, 0.5); }
.perception-rate-content {
  position: relative; background: white; border-radius: 18px;
  padding: 1.75rem 1.5rem 1.5rem; width: calc(100% - 2rem); max-width: 520px;
  max-height: calc(100vh - 2rem); overflow-y: auto;
  box-shadow: 0 18px 50px rgba(0,0,0,0.2);
  transform: translateY(8px) scale(0.98); transition: transform 0.22s ease;
}
.perception-rate-modal.open .perception-rate-content { transform: translateY(0) scale(1); }
.perception-rate-close {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px; border-radius: 50%;
  border: none; background: var(--cream); color: var(--muted);
  cursor: pointer; font-size: 20px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.perception-rate-close:hover { background: var(--border); color: var(--ink); }
.perception-rate-title { font-family: 'Lora', 'Lora Fallback', serif; font-size: 24px; font-weight: 600; color: var(--ink); margin: 0 40px 6px 0; }
.perception-rate-title span { color: var(--perception-accent, var(--ink)); }
.perception-rate-sub { font-size: 14px; color: var(--muted); line-height: 1.45; margin: 0 0 1.25rem; }
.perception-rate-rows { display: flex; flex-direction: column; gap: 8px; margin-bottom: 1.25rem; }
.perception-rate-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: stretch; }
.perception-rate-opt {
  padding: 9px 12px; font-size: 13px; font-weight: 500; font-family: inherit;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--cream); color: var(--ink); cursor: pointer;
  transition: border-color 0.12s, background 0.12s, color 0.12s, transform 0.08s;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
@media (hover: hover) {
  .perception-rate-opt:hover { border-color: var(--ink); background: white; }
}
.perception-rate-opt:active { transform: scale(0.97); }
.perception-rate-opt.chosen,
.perception-rate-opt.chosen:hover { background: var(--perception-accent, var(--ink)); color: white; border-color: var(--perception-accent, var(--ink)); }
.perception-rate-opt-neutral { color: #7a7873; font-size: 12px; min-width: 92px; }
.perception-rate-opt-neutral.chosen,
.perception-rate-opt-neutral.chosen:hover { background: var(--perception-accent, var(--ink)); color: white; border-color: var(--perception-accent, var(--ink)); }
.perception-rate-done {
  display: block; width: 100%; padding: 10px 16px;
  font: inherit; font-size: 14px; font-weight: 500;
  border: none; border-radius: 10px; background: var(--ink); color: white;
  cursor: pointer; transition: opacity 0.15s;
}
.perception-rate-done:hover { opacity: 0.92; }
@media (max-width: 480px) {
  .perception-rate-row { grid-template-columns: 1fr 1fr 1fr; }
  .perception-rate-opt { font-size: 12px; padding: 8px 8px; }
  .perception-rate-opt-neutral { min-width: 0; }
  .perception-rate-title { font-size: 20px; }
}
.perception-intro { margin-bottom: 12px; color: var(--muted); font-size: 14px; display: flex; align-items: center; gap: 10px; }
.perception-intro-text { flex: 1 1 auto; min-width: 0; }
.perception-intro strong { color: var(--ink); font-weight: 500; }
.perception-info { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: rgba(44,44,42,0.12); color: var(--muted); cursor: help; user-select: none; vertical-align: middle; transform: translateY(-1px); }
.perception-info svg { width: 10px; height: 10px; display: block; }
.perception-info:hover, .perception-info.open { background: rgba(44,44,42,0.2); color: var(--ink); }
.perception-info-tip { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: var(--ink); color: white; font-size: 11px; line-height: 1.4; padding: 8px 12px; border-radius: 8px; width: 240px; text-align: left; pointer-events: none; opacity: 0; transition: opacity 0.15s; font-weight: 400; z-index: 50; }
.perception-info:hover .perception-info-tip, .perception-info.open .perception-info-tip { opacity: 1; }
.perception-box { background: var(--cream); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; }
.perception-footer { font-size: 11px; color: var(--muted); margin: 10px 0 0; line-height: 1.45; }
.perception-footer a { color: var(--muted); text-decoration: underline; }
.perception-footer a:hover { color: var(--ink); }
.perception-box.girl,
.perception-result-wrap.girl   { --perception-accent: var(--pink); }
.perception-box.boy,
.perception-result-wrap.boy    { --perception-accent: var(--blue); }
.perception-box.unisex,
.perception-result-wrap.unisex { --perception-accent: var(--amber); }
.perception-list { display: flex; flex-direction: column; gap: 10px; }
/* Desktop: fixed-width label columns so every bar starts and ends at the
   same x-position regardless of label length, sized to fit "Upper-class
   100%" with breathing room. Mobile keeps the original max-content
   layout — the screens are too narrow for fixed columns to feel right,
   and the production look tested better. */
.perception-row { display: grid; grid-template-columns: 22px 125px 1fr 125px 22px; align-items: center; gap: 8px; font-size: 13px; }
@media (max-width: 520px) {
  .perception-row { gap: 6px; font-size: 12px; grid-template-columns: 20px max-content 1fr max-content 20px; }
  .perception-label .pct { font-size: 11px; }
}
@media (max-width: 380px) {
  .perception-row { grid-template-columns: 18px max-content 1fr max-content 18px; gap: 4px; font-size: 11px; }
}
.perception-row > .perception-vote-l { justify-self: end; }
.perception-row > .perception-vote-r { justify-self: start; }
.perception-vote { width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--border); background: white; color: var(--muted); font-size: 14px; font-weight: 500; line-height: 1; padding: 0; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.15s; position: relative; }
@media (hover: hover) {
  .perception-vote:hover:not(:disabled):not(.chosen) { border-color: var(--perception-accent, var(--ink)); color: var(--perception-accent, var(--ink)); transform: scale(1.08); }
  .perception-vote.chosen:hover:not(:disabled) { transform: scale(1.08); color: white; background: var(--perception-accent, var(--ink)); border-color: var(--perception-accent, var(--ink)); }
}
.perception-vote:active:not(:disabled) { transform: scale(0.95); }
.perception-vote:disabled { cursor: default; opacity: 0.35; }
.perception-vote.chosen { background: var(--perception-accent, var(--ink)); color: white; border-color: var(--perception-accent, var(--ink)); opacity: 1; }
.perception-row.voting .perception-vote { pointer-events: none; }
/* Vote-confirmation optics: quick scale pulse on the clicked button plus
   a bump on the intro rating count when a new distinct voter is recorded.
   Purely visual — no effect on stored votes or the blended score. */
.perception-vote.just-voted { animation: perceptionVoteBump 360ms ease-out; }
@keyframes perceptionVoteBump {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.35); }
  100% { transform: scale(1); }
}
.perception-intro-text strong.just-incremented {
  display: inline-block;
  animation: perceptionCountBump 560ms ease-out;
}
@keyframes perceptionCountBump {
  0%   { transform: scale(1); color: var(--ink); }
  35%  { transform: scale(1.22); color: var(--perception-accent, var(--ink)); }
  100% { transform: scale(1); color: var(--ink); }
}
@media (prefers-reduced-motion: reduce) {
  .perception-vote.just-voted,
  .perception-intro-text strong.just-incremented { animation: none; }
}
.perception-vote::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  padding: 4px 8px; background: var(--ink); color: white; border-radius: 6px;
  font-size: 11px; font-weight: 500; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.15s; z-index: 20;
}
@media (hover: hover) {
  .perception-vote:hover::after,
  .perception-vote:focus-visible::after { opacity: 1; }
}
.perception-label { color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color 0.25s, font-weight 0.25s; display: flex; align-items: baseline; gap: 6px; }
.perception-label-l { text-align: right; justify-content: flex-end; }
.perception-label-r { text-align: left; justify-content: flex-start; }
.perception-label .pct { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 500; }
.perception-row .perception-label-l { color: var(--perception-accent, var(--ink)); font-weight: 500; }
.perception-row .perception-label-l .pct { color: var(--perception-accent, var(--ink)); }
.perception-track { position: relative; height: 10px; background: white; border-radius: 99px; border: 1px solid var(--border); overflow: hidden; display: flex; }
.perception-bar-l, .perception-bar-r { height: 100%; transition: width 0.9s cubic-bezier(0.2, 0.6, 0.25, 1); }
.perception-bar-l { background: var(--perception-accent, var(--ink)); }
/* The losing bar previously read as an empty track — visitors thought the
   row's percentage was for the right-hand pole. Tint it with a faint wash
   of the accent so both halves look filled and clearly belong to the same
   scale. Fixed-grey fallback first; color-mix is the upgrade where
   supported (Chrome 111+ / Safari 16.2+ / Firefox 113+). */
.perception-bar-r { background: #D4D0C7; margin-left: auto; }
.perception-bar-r { background: color-mix(in srgb, var(--perception-accent, #B8B3A8) 22%, white); margin-left: auto; }

/* Empty state: this trait has no community/BTN ratings yet, so the 50/50
   split is just our fallback default — not a measured result. Hide the
   percentages entirely (otherwise visitors read them as real data) and
   paint both halves of the bar in the same neutral grey so the row reads
   "no data" rather than "evenly split". Equalise label weight (no
   bold/accent on the left) so neither pole is emphasised when neither is
   winning. Per-row, not per-box — when a visitor rates one trait, the
   other unrated rows stay greyed; only the rated one lights up. */
.perception-row.empty .perception-label .pct { display: none; }
.perception-row.empty .perception-bar-l,
.perception-row.empty .perception-bar-r { background: #DCD8CF; }
.perception-row.empty .perception-label-l { color: var(--ink); font-weight: 500; }
.perception-row.empty .perception-label-r { color: var(--ink); font-weight: 500; }
/* Mobile: revert the new visual treatments back to production for RATED
   rows only — production's right-bar grey, no right-pct chip. Empty
   rows still use the universal greyed-out treatment above so a no-data
   name doesn't lie with a 50/50-looking split. */
@media (max-width: 520px) {
  .perception-row:not(.empty) .perception-label-r .pct { display: none; }
  .perception-row:not(.empty) .perception-bar-r { background: #E7E4DC; }
}
/* All rows the same height — a taller top-row track caused the "some
   bars look thicker" impression. Emphasis comes from the label styling
   instead. */
.perception-box .perception-bar-l, .perception-box .perception-bar-r { width: 0; }
.perception-box.animate .perception-bar-l { width: var(--wl, 50%); transition-delay: var(--d, 0ms); }
.perception-box.animate .perception-bar-r { width: var(--wr, 50%); transition-delay: var(--d, 0ms); }
@media (prefers-reduced-motion: reduce) {
  .perception-bar-l, .perception-bar-r { transition: none; }
  .perception-box .perception-bar-l { width: var(--wl, 50%); }
  .perception-box .perception-bar-r { width: var(--wr, 50%); }
}
.name-origin-block { font-size: 15px; color: var(--muted); line-height: 1.6; padding: 12px 14px; border-left: 3px solid var(--pink); background: #fdf1f3; border-radius: 0 10px 10px 0; margin-bottom: 1rem; font-style: italic; }
.name-origin-block.origin-g { border-left-color: var(--pink); background: #fdf1f3; }
.name-origin-block.origin-b { border-left-color: var(--blue); background: #eef4f9; }
.name-origin-block.origin-u { border-left-color: var(--amber); background: #fdf7e9; }

/* Classroom */
.class-tool { background: white; border-radius: 20px; border: 1px solid var(--border); padding: 1.75rem; }
.class-header { font-family: 'Lora', 'Lora Fallback', serif; font-size: 24px; margin-bottom: 6px; }
.class-sub { font-size: 16px; color: var(--muted); margin-bottom: 1.5rem; }
.slider-row { margin-bottom: 1.25rem; }
.slider-row label { font-size: 14px; color: var(--muted); display: flex; justify-content: space-between; margin-bottom: 7px; }
.slider-row label span { font-weight: 500; color: var(--ink); }
.slider-row input[type=range] { width: 100%; accent-color: var(--ink); }
.slider-row .slider-wrap { position: relative; }
.slider-row .slider-val {
  position: absolute; top: -22px; font-size: 14px; font-weight: 500; color: var(--ink);
  transform: translateX(-50%); pointer-events: none;
}
.class-result { background: var(--cream); border: 1px solid var(--border); border-radius: 14px; padding: 1.25rem; text-align: center; margin-top: 1.25rem; }
.class-big { font-size: 48px; font-weight: 300; color: var(--ink); font-family: 'Lora', 'Lora Fallback', serif; }
.class-desc { font-size: 16px; color: var(--muted); margin-top: 6px; line-height: 1.6; }
.class-verdict { display: inline-block; margin-top: 10px; padding: 6px 16px; border-radius: 50px; font-size: 14px; font-weight: 500; border: 1px solid color-mix(in srgb, currentColor 40%, transparent); }

/* Harmony */
.harmony-tool { background: white; border-radius: 20px; border: 1px solid var(--border); padding: 1.75rem; }
.harmony-header { font-family: 'Lora', 'Lora Fallback', serif; font-size: 24px; margin-bottom: 6px; }
.harmony-sub { font-size: 16px; color: var(--muted); margin-bottom: 1.5rem; }
.harmony-inputs { display: flex; gap: 12px; margin-bottom: 1.25rem; flex-wrap: wrap; }
.harmony-inputs .input-wrap { position: relative; flex: 1; min-width: 120px; display: flex; }
.harmony-inputs input { flex: 1; min-width: 120px; padding: 13px 40px 11px 16px; border-radius: 50px; border: 1.5px solid var(--border); background: var(--cream); font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 16px; color: var(--ink); outline: none; transition: border-color 0.2s; }
/* ✕ clear button — visible only when the input has a value, so it
   appears the moment the user starts typing. Sibling combinator on
   :placeholder-shown means no JS state to drive visibility. The
   tabindex="-1" on the button (set in the markup) keeps Tab key
   navigation hopping straight from input to input. */
.harmony-inputs .input-clear {
  position: absolute; top: 50%; right: 10px; transform: translateY(-50%);
  width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(44, 44, 42, 0.08); color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer;
  display: none; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.harmony-inputs .input-wrap input:not(:placeholder-shown) ~ .input-clear { display: inline-flex; }
.harmony-inputs .input-clear:hover { background: rgba(44, 44, 42, 0.18); color: var(--ink); }
/* Keep input border colour unchanged on focus per design preference. */
.score-ring-wrap { display: flex; align-items: center; gap: 1.5rem; }
.score-ring { position: relative; width: 120px; height: 120px; flex-shrink: 0; }
.score-ring svg { transform: rotate(-90deg); }
.score-ring .score-center { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); font-size: 30px; font-weight: 600; color: var(--ink); }
.compat-list { flex: 1; min-width: 200px; }
.compat-item { font-size: 14px; color: var(--muted); padding: 5px 0; border-bottom: 0.5px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
.compat-item:last-child { border-bottom: none; }
.compat-label { display: flex; align-items: center; gap: 5px; }
.info-icon { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: var(--border); color: var(--muted); font-size: 11px; font-weight: 600; cursor: default; position: relative; flex-shrink: 0; font-style: normal; }
.info-icon:hover .tooltip { display: block; }
.tooltip { display: none; position: absolute; left: 20px; top: -4px; background: var(--ink); color: white; font-size: 12px; line-height: 1.4; padding: 6px 10px; border-radius: 8px; width: 200px; z-index: 10; font-weight: 400; pointer-events: none; }
.tooltip::before { content: ''; position: absolute; left: -5px; top: 8px; border: 5px solid transparent; border-right-color: var(--ink); border-left: none; }
.compat-val { font-weight: 500; color: var(--ink); }
.compat-val.warn { color: var(--coral); }
.initials-warning { margin-top: 1rem; padding: 12px 14px; background: var(--coral-light); border-radius: 10px; font-size: 14px; color: #993C1D; border-left: 3px solid var(--coral); line-height: 1.5; }

/* Empty state */
.empty-state { text-align: center; padding: 3rem 1rem 1.25rem; color: var(--muted); }
.empty-state .big-emoji { font-size: 36px; margin-bottom: 0.5rem; }
.empty-state p { font-size: 16px; line-height: 1.6; }

/* Similar names */
.vibe-chip { padding: 7px 14px; border-radius: 50px; font-size: 13px; font-weight: 500; border: 1.5px solid var(--border); background: white; cursor: pointer; transition: all 0.18s; color: var(--muted); user-select: none; }
.vibe-chip.active { background: var(--ink); color: white; border-color: var(--ink); }
.vibe-chip:hover:not(.active) { border-color: var(--ink); color: var(--ink); }
.similar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; margin-top: 0.5rem; }
.similar-card { background: white; border: 1px solid var(--border); border-radius: 14px; padding: 12px 14px; cursor: pointer; transition: all 0.18s; }
.similar-card:hover { transform: translateY(-1px); }
.similar-card:has(.similar-card-name.girl):hover { border-color: var(--pink); }
.similar-card:has(.similar-card-name.boy):hover { border-color: var(--blue); }
.similar-card:has(.similar-card-name.unisex):hover { border-color: var(--amber); }
.similar-card-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 20px; font-weight: 500; margin-bottom: 2px; }
.similar-card-name.girl { color: var(--pink); }
.similar-card-name.boy  { color: var(--blue); }
.similar-card-name.unisex { color: var(--amber); }
.similar-card-meta { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.similar-card-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.similar-card-tag { font-size: 12px; padding: 2px 7px; border-radius: 50px; background: var(--cream); color: var(--muted); }

/* Internal-link sections (Similar names + homepage Popular names) */
.link-block { margin-top: 1.5rem; }
.link-block-title { font-size: 12px; font-weight: 500; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 10px; }
.link-pill-row { display: flex; flex-wrap: wrap; gap: 8px; }
.link-pill { display: inline-block; padding: 7px 14px; border-radius: 50px; font-size: 14px; font-family: 'Lora', 'Lora Fallback', serif; text-decoration: none; background: white; border: 1px solid var(--border); transition: all 0.18s; cursor: pointer; }
.link-pill:hover { border-color: currentColor; transform: translateY(-1px); }
.link-pill.girl { color: var(--pink); }
.link-pill.boy { color: var(--blue); }
.link-pill.unisex { color: var(--amber); }
.link-grid-section { margin-top: 2.5rem; padding: 1.75rem 0 1rem; border-top: 1px solid var(--border); }
.link-grid-section h2 { font-family: 'Lora', 'Lora Fallback', serif; font-size: 24px; font-weight: 600; color: var(--ink); margin-bottom: 0.25rem; }
.link-grid-section .lg-sub { font-size: 16px; color: var(--muted); margin-bottom: 1.5rem; }
.vibe-row { margin-bottom: 1.5rem; }
.vibe-row-label { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink); margin-bottom: 10px; }

/* ── Top nav ──────────────────────────────────────────────── */
.topnav {
  position: sticky; top: 0; z-index: 100;
  background: #ffffff;
  border-bottom: 1px solid var(--border);
  transition: box-shadow 0.22s ease;
}
.topnav.scrolled {
  box-shadow: 0 6px 20px rgba(20, 20, 20, 0.10);
}
.topnav-inner {
  max-width: 1100px; margin: 0 auto; padding: 10px 2rem;
  display: flex; align-items: center; gap: 16px;
  min-height: 58px;
}
.topnav-logo {
  display: flex; align-items: center; gap: 8px;
  text-decoration: none; color: var(--ink);
  flex-shrink: 0;
  min-width: 0;
  position: relative; top: -2px;
}
.topnav-logo:hover, .topnav-logo:hover .topnav-logo-text { color: var(--ink); text-decoration: none; }
.topnav-links { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-left: 16px; }
.topnav-link {
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 14px; font-weight: 500;
  color: var(--ink); text-decoration: none;
  padding: 8px 18px; border-radius: 50px;
  background: var(--cream); border: 1px solid var(--border);
  transition: background 0.18s, color 0.18s, border-color 0.18s;
  white-space: nowrap;
  cursor: pointer;
}
.topnav-link:hover { background: #F5F1EA; color: var(--ink); text-decoration: none; }
.topnav-link.active { background: var(--amber); color: white; border-color: var(--amber); }
.topnav-link.active:hover { background: var(--amber); color: white; }
.topnav-explore-btn.active, .topnav-explore-btn.active:hover { background: var(--amber); color: white; border-color: var(--amber); }
@media (max-width: 1100px) {
  .topnav-link { padding: 7px 14px; font-size: 13px; }
  .topnav-links { gap: 6px; margin-left: 10px; }
}
@media (max-width: 860px) {
  .topnav-link { padding: 7px 13px; font-size: 13px; }
  .topnav-links { margin-left: 8px; gap: 6px; }
}
@media (max-width: 640px) {
  .topnav-links { display: none; }
}
.topnav-logo-icon { width: 30px; height: 30px; display: block; flex-shrink: 0; }
.topnav-logo-text { font-family: 'Lora', 'Lora Fallback', serif; font-size: 16px; font-weight: 600; white-space: nowrap; position: relative; top: 2px; display: inline-block; }

/* ── Noah moment: icon swap + angry scribble under 'Not' ─── */
.topnav-logo-icon-stage {
  position: relative; width: 30px; height: 30px;
  flex-shrink: 0; display: inline-flex;
  align-items: center; justify-content: center;
  overflow: hidden;
}
.topnav-logo-icon-emoji {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px; line-height: 1;
  opacity: 0; transform: translateY(-34px);
  pointer-events: none;
}
.topnav-logo-not { position: relative; display: inline-block; }
.noah-scribble {
  position: absolute; left: -4px; right: -4px; bottom: -9px;
  width: calc(100% + 8px); height: 11px;
  pointer-events: none; overflow: visible;
}
.noah-scribble path {
  fill: none; stroke: #D85A30; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 470; stroke-dashoffset: 470;
  opacity: 0;
}
/* ─── Entry + hold: .noah-moment (Noah, with scribble) and
 *     .name-moment (other themed names — icon swap only). ─── */
.noah-moment .topnav-logo-icon,
.name-moment .topnav-logo-icon {
  animation: noahIconDrop 0.32s cubic-bezier(0.5, 0, 0.75, 0.1) 0s forwards;
}
.noah-moment .topnav-logo-icon-emoji,
.name-moment .topnav-logo-icon-emoji {
  animation: noahEmojiDrop 0.4s cubic-bezier(0.25, 1.5, 0.5, 1) 0.22s forwards;
}
.noah-moment .noah-scribble path {
  animation: noahScribbleCycle 5s linear infinite;
}
/* ─── Exit: .noah-exit / .name-exit. ─── */
.noah-exit .topnav-logo-icon,
.name-exit .topnav-logo-icon {
  animation: noahIconReturn 0.35s cubic-bezier(0.25, 1, 0.5, 1) 0.1s forwards;
}
.noah-exit .topnav-logo-icon-emoji,
.name-exit .topnav-logo-icon-emoji {
  animation: noahEmojiExit 0.3s cubic-bezier(0.5, 0, 0.75, 0.1) 0s forwards;
}
.noah-exit .noah-scribble path {
  animation: noahScribbleFade 0.3s ease-out 0s forwards;
}

/* ─── Side emoji field ───
 * Drifting decorative emojis in the left/right gutters when a themed
 * name is searched (Sunny → suns, Luna → moons & stars, etc.). The
 * spawner JS clamps emojis out of the central .app column; here we
 * just hide it on viewports too narrow to have side gutters, and
 * under prefers-reduced-motion. */
.name-field {
  position: fixed; inset: 0;
  pointer-events: none;
  /* Above .app contents (incl. the sticky sub-tabs at z-index 50)
   * but below the topnav (100) and modals (1050+). The exclusion
   * logic in JS keeps emojis transparent in the central column, so
   * the sub-tabs / result card / FAQ remain readable; in the side
   * gutters the emojis paint in front of those elements (including
   * the sub-tabs' full-viewport cream background). */
  z-index: 60;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.name-field.visible { opacity: 1; }
.name-field span {
  position: absolute; top: 0; left: 0;
  user-select: none; -webkit-user-select: none;
  will-change: transform, opacity;
  transition: opacity 0.6s ease;
  line-height: 1;
}
@media (max-width: 1199px) {
  .name-field { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .name-field { display: none; }
}

@keyframes noahIconDrop {
  0% { transform: translateY(0); opacity: 1; }
  100% { transform: translateY(34px); opacity: 0; }
}
@keyframes noahIconReturn {
  0% { transform: translateY(-34px); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}
@keyframes noahEmojiDrop {
  0% { transform: translateY(-34px); opacity: 0; }
  65% { transform: translateY(5px); opacity: 1; }
  100% { transform: translateY(2px); opacity: 1; }
}
@keyframes noahEmojiExit {
  0% { transform: translateY(2px); opacity: 1; }
  100% { transform: translateY(34px); opacity: 0; }
}
@keyframes noahScribbleCycle {
  /* Wait, draw, hold, fade, reset — loops every 5s to keep drawing
     the eye back to the logo without being obnoxious. */
  0%   { stroke-dashoffset: 470; opacity: 1; }
  16%  { stroke-dashoffset: 470; opacity: 1; }
  34%  { stroke-dashoffset: 0;   opacity: 1; }
  90%  { stroke-dashoffset: 0;   opacity: 1; }
  97%  { stroke-dashoffset: 0;   opacity: 0; }
  98%  { stroke-dashoffset: 470; opacity: 0; }
  100% { stroke-dashoffset: 470; opacity: 1; }
}
@keyframes noahScribbleFade {
  0% { opacity: 1; }
  100% { opacity: 0; }
}
.topnav-search {
  position: relative;
  width: 300px;
  margin-left: auto;          /* push to the right, anchored next to share btn */
  flex-shrink: 0;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.topnav-search.visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
.topnav-search input {
  width: 100%;
  height: 36px;
  line-height: 36px;
  padding: 0 36px 0 18px;
  border: 1px solid var(--border); border-radius: 50px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px;
  background: white; color: var(--ink);
  outline: none;
  box-sizing: border-box;
  text-overflow: ellipsis;
}
.topnav-search input:focus { border-color: var(--border); }
.topnav-search input::placeholder { color: var(--muted); text-overflow: ellipsis; overflow: hidden; }
.topnav-search-clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px;
  display: none; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--cream); border: none;
  cursor: pointer; color: var(--muted);
  /* Match line-height to height so the × glyph is perfectly centred
     within the button's line box regardless of font metrics. */
  font-size: 16px; line-height: 22px;
  padding: 0;
  font-family: Arial, sans-serif;
}
.topnav-search-clear:hover { background: var(--border); color: var(--ink); }
.topnav-search-clear.visible { display: inline-flex; }
.topnav-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.topnav-share-btn {
  padding: 8px 18px; border-radius: 50px;
  background: var(--cream); color: var(--ink);
  border: 1px solid var(--border);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background 0.18s;
  white-space: nowrap;
}
.topnav-share-btn:hover { background: #F5F1EA; }
.topnav-share-btn .share-btn-short { display: none; }
.topnav-persuader-btn {
  padding: 8px 18px; border-radius: 50px;
  background: var(--cream); color: var(--ink);
  border: 1px solid var(--border);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background 0.18s, transform 0.18s;
  white-space: nowrap;
}
.topnav-persuader-btn:hover { background: #F5F1EA; }
.topnav-explore-wrap { position: relative; }
.topnav-explore-btn {
  padding: 8px 18px; border-radius: 50px;
  background: var(--cream); color: var(--ink);
  border: 1px solid var(--border);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background 0.18s;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
}
.topnav-explore-btn:hover { background: #F5F1EA; }
.topnav-explore-btn[aria-expanded="true"] { background: var(--ink); color: white; border-color: var(--ink); }
.topnav-explore-caret { font-size: 18px; transition: transform 0.18s; line-height: 1; font-weight: 600; }
.topnav-explore-btn[aria-expanded="true"] .topnav-explore-caret { transform: rotate(180deg); }
.topnav-explore-menu {
  position: absolute; top: calc(100% + 8px); right: 0;
  background: white; border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 12px 36px rgba(44,44,42,0.10);
  width: 300px; padding: 6px;
  display: none; z-index: 100;
}
.topnav-explore-menu.open { display: block; }
.topnav-explore-menu a, .topnav-explore-menu button {
  display: block; width: 100%; text-align: left;
  padding: 12px 14px; border-radius: 10px;
  background: transparent; border: 0;
  color: var(--ink); text-decoration: none; cursor: pointer;
  font-family: inherit;
}
.topnav-explore-menu a:hover, .topnav-explore-menu button:hover { background: var(--cream); text-decoration: none; }
.topnav-explore-menu strong {
  display: block;
  font-family: 'Lora', 'Lora Fallback', serif;
  font-size: 16px; font-weight: 600; color: var(--ink);
}
.topnav-explore-menu span {
  display: block; color: var(--muted);
  font-size: 13px; margin-top: 2px; line-height: 1.35;
}
.topnav-share-btn {
  display: inline-flex; align-items: center; gap: 8px;
}
.topnav-share-btn svg { flex-shrink: 0; width: 15px; height: 15px; }
@media (max-width: 1100px) {
  /* Drop both nav buttons to 13px in lock-step at 1100px so the
     row's CTAs read the same size at every viewport. The Persuader
     used to drop alone, leaving the longer "Share with a soon-to-be
     parent" button visibly larger between 860 and 1100px. */
  .topnav-persuader-btn,
  .topnav-explore-btn,
  .topnav-share-btn { padding: 7px 13px; font-size: 13px; }
}
@media (max-width: 1000px) {
  .topnav-search { width: 240px; }
  .topnav-share-btn .share-btn-full { display: none; }
  .topnav-share-btn .share-btn-short { display: inline; }
  .topnav-share-btn, .topnav-persuader-btn, .topnav-explore-btn { padding: 8px 14px; }
}
@media (max-width: 860px) {
  .topnav-search { width: 200px; }
  .topnav-share-btn, .topnav-persuader-btn, .topnav-explore-btn { padding: 7px 12px; font-size: 13px; }
  .topnav-inner { gap: 8px; padding: 10px 1rem; }
}
@media (max-width: 720px) {
  .topnav-inner { padding: 8px 1rem; gap: 8px; }
  .topnav-actions { display: none; }
  .topnav-search { width: 170px; margin-left: auto; }
}
@media (max-width: 540px) {
  .topnav-inner { padding: 8px 12px; gap: 6px; }
  .topnav-logo-text { font-size: 15px; }
  .topnav-search { width: 160px; }
  /* Keep computed font-size ≥16px so iOS Safari doesn't zoom on focus.
     Placeholder is styled smaller so the at-rest look matches the old compact size. */
  .topnav-search input { font-size: 16px; height: 34px; line-height: 34px; padding: 0 28px 0 16px; }
  .topnav-search input::placeholder { font-size: 13px; }
}

/* ── Share button on the name profile card ──────────────────── */
.name-card-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
/* The title row centres text + the inline audio button via flex so the
   audio glyph sits at the same y as the heart/share buttons in the
   sibling .name-actions — vertical-align: middle on a serif font line
   drifts with font-size, but flex centering does not. */
.name-card-header .name-title { flex: 1 1 auto; display: flex; align-items: center; flex-wrap: wrap; column-gap: 8px; row-gap: 4px; }
/* Wrap the inline audio button in an inline-flex container with its
   own line-height: 1 so it doesn't inherit the title's tall line-box
   metrics — keeps the button's bounding box the same size as the
   button itself. The 2px translateY corrects a constant residual
   offset (independent of title font-size) that comes from the inline
   button's baseline metric inside the flex line; with both pieces in
   place pron / heart / share line up to the pixel at every size. */
.name-card-header .pron-anchor { display: inline-flex; align-items: center; line-height: 1; transform: translateY(4px); }
.name-card-header .name-actions { transform: translateY(2px); }
/* Mobile uses a smaller title (32px vs 40px desktop). The 4px/2px
   shifts that visually centre the icons against the desktop serif
   title push them too low against the smaller mobile title — revert
   to the original 2px/0 baseline on narrow viewports. */
@media (max-width: 640px) {
  .ah-another { display: none; }
  .name-card-header .pron-anchor { transform: translateY(2px); }
  .name-card-header .name-actions { transform: none; }
}
.name-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.btn-label-short { display: none; }
/* Now that shortlist + share are 36px circles (no labels), they fit
   alongside the name title at every width — the previous reorder
   rule that dropped them below the meta on narrow viewports is no
   longer needed. */
@media (max-width: 640px) {
  .name-actions { gap: 6px; align-self: center; }
  .name-actions .heart-btn, .name-actions .share-name-btn { margin-top: 0; }
  /* Long names (≥8 chars, e.g. Muhammad) wrap the actions to a second
     line on narrow viewports — nudge the title down to 28px so the
     title + audio + heart + share all sit on one row. */
  .name-card-header--long .name-title { font-size: 28px; }
}
/* Iconified share + shortlist — circular, no text labels, sit beside
   the name title at every viewport. data-tip surfaces the meaning on
   hover. */
.heart-btn, .share-name-btn {
  flex-shrink: 0; margin-top: 0;
  display: flex; align-items: center; justify-content: center; gap: 0;
  width: 32px; height: 32px; padding: 0;
  border-radius: 50%; background: white; border: 1.5px solid var(--border);
  cursor: pointer; transition: all 0.18s;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  position: relative;
}
.heart-btn .btn-label, .heart-btn .btn-label-short,
.share-name-btn .btn-label, .share-name-btn .btn-label-short { display: none !important; }
.share-name-btn { color: var(--ink); }
.share-name-btn:hover { background: #FAFAFA; }
.share-name-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
/* Stylised hover tooltip for the iconified action buttons. data-tip
   carries the label; we render it in our own pill so the browser's
   native tooltip (title attribute) doesn't have a chance to fire. */
.heart-btn::after, .share-name-btn::after {
  content: attr(data-tip);
  position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  padding: 5px 10px; background: var(--ink); color: white; border-radius: 6px;
  font-size: 11px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.15s; margin-bottom: 6px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-weight: 500;
  z-index: 10;
}
.heart-btn:hover::after, .share-name-btn:hover::after { opacity: 1; }
.share-name-btn::after {
  content: attr(data-tip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  padding: 5px 10px; background: var(--ink); color: white; border-radius: 6px;
  font-size: 11px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.1s; margin-bottom: 6px; font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
}
.share-name-btn::after { display: none; }

/* ── Heart / shortlist button ────────────────────────────────── */
.heart-btn { color: #B8943E; }
.heart-btn:hover { background: #FDF6E3; }
.heart-btn.hearted { background: #FDF6E3; border-color: #B8943E; }
.heart-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.heart-btn.hearted svg { animation: heartPop 0.3s ease; }
/* Desktop: revert to the labelled pill version of the shortlist
   button so it doesn't get lost next to the title. Keeps the
   share button as an icon. */
@media (min-width: 641px) and (hover: hover) {
  .heart-btn {
    width: auto;
    height: 34px;
    padding: 0 16px 0 13px;
    border-radius: 50px;
    gap: 7px;
  }
  .heart-btn .btn-label { display: inline !important; font-size: 13px; font-weight: 500; }
  .heart-btn::after { display: none; }
}
@keyframes heartPop { 0% { transform: scale(1); } 50% { transform: scale(1.25); } 100% { transform: scale(1); } }

/* ── Veto button (left of shortlist) ───────────────────────── */
.veto-btn {
  flex-shrink: 0; margin-top: 10px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border-radius: 50px; background: white; border: 1px solid var(--border);
  cursor: pointer; transition: all 0.18s;
  color: #A8543C; padding: 7px 20px 7px 14px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500;
}
.veto-btn:hover { background: #FAF0EE; border-color: #A8543C; }
.veto-btn.vetoed {
  background: #A8543C; border-color: #A8543C; color: white;
}
.veto-btn.vetoed:hover { background: #B15F46; border-color: #B15F46; }
.veto-btn:disabled { opacity: 0.5; cursor: default; }
.veto-btn svg { width: 18px; height: 18px; flex-shrink: 0; }
.veto-btn .btn-label { display: inline; }
@media (max-width: 640px) {
  .veto-btn { padding: 6px 12px 6px 10px; font-size: 13px; gap: 5px; margin-top: 0; }
  .veto-btn svg { width: 15px; height: 15px; }
}

/* ── VETO dramatic animation overlay ───────────────────────── */
/* Page stays visible throughout. Stamp falls visibly from above,
   then crashes at impact — that's when splash, shockwave, shake and
   element recoil all trigger simultaneously. The stamp then HOLDS
   on screen until the user dismisses or pays. */
.veto-overlay {
  position: fixed; inset: 0; z-index: 99999;
  pointer-events: auto; /* Block clicks on the page behind; overlay handler dismisses on outside click */
  background: transparent;
  overflow: hidden;
  cursor: pointer; /* Whole overlay is dismissable except over stamp/CTA */
}
.veto-overlay .veto-stamp,
.veto-overlay .veto-cta-wrap { cursor: default; }
.veto-overlay .veto-cta-bar,
.veto-overlay .veto-dismiss-btn { cursor: pointer; }
/* Stamp: crashes down — short fast fall with a gravity feel, hard stop.
   Lands in the centre of the viewport. CTA sits below it. */
.veto-stamp {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -120vh) scale(1.2) rotate(-20deg);
  font-family: 'Impact', 'Arial Black', 'Helvetica Neue', sans-serif;
  font-size: clamp(60px, 14vw, 180px);
  font-weight: 900; letter-spacing: 0.04em;
  color: #fff;
  text-shadow: 0 0 40px rgba(231,76,60,0.9), 6px 6px 0 rgba(0,0,0,0.6);
  padding: 16px 48px;
  border: 12px solid #fff;
  border-radius: 8px;
  background: #A8543C;
  box-shadow: 0 0 80px rgba(231,76,60,0.7), inset 0 0 40px rgba(255,255,255,0.1),
              0 30px 60px rgba(0,0,0,0.35);
  opacity: 0;
  /* Steep accelerating curve for gravity-like fall */
  animation: vetoSlam 0.9s cubic-bezier(0.5, 0, 0.85, 0.05) forwards;
  transform-origin: center center;
  /* Absorb clicks so tapping the stamp itself doesn't dismiss the veto;
     only clicks on the surrounding overlay do that. */
  pointer-events: auto;
  cursor: default;
}
@keyframes vetoSlam {
  /* Off-screen top, opacity 0, appear at 8% */
  0%   { transform: translate(-50%, -120vh) scale(1.2) rotate(-20deg); opacity: 0; }
  8%   { transform: translate(-50%, -120vh) scale(1.2) rotate(-20deg); opacity: 1; }
  /* Fall — very fast, accelerating */
  42%  { transform: translate(-50%, -50%) scale(1.15, 0.85) rotate(-6deg); opacity: 1; }
  /* IMPACT at 42% (= ~380ms) — squash */
  48%  { transform: translate(-50%, -54%) scale(0.9, 1.1) rotate(-6deg); }
  56%  { transform: translate(-50%, -50%) scale(1.06, 0.96) rotate(-6deg); }
  64%  { transform: translate(-50%, -50%) scale(1) rotate(-6deg); }
  /* HOLD at settled position indefinitely */
  100% { transform: translate(-50%, -50%) scale(1) rotate(-6deg); opacity: 1; }
}
.veto-sub {
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: clamp(16px, 2vw, 24px);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: #fff;
  text-shadow: 2px 2px 0 rgba(0,0,0,0.45);
  margin-top: 6px;
  opacity: 0;
  animation: vetoSubFade 0.9s ease-out forwards;
  text-align: center;
}
@keyframes vetoSubFade {
  0%, 50% { opacity: 0; transform: translateY(6px); }
  70% { opacity: 1; transform: translateY(0); }
  100% { opacity: 1; }
}

/* Screen shake — AT impact (0.38s in, matching 42% of 0.9s stamp anim).
   Applied to top-level body children EXCEPT the overlay/modal so the
   stamp stays rock-steady while the page rattles around it. */
body.vetoing > *:not(.veto-overlay):not(.veto-modal):not(script):not(style) {
  animation: vetoShake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) 0.38s;
}
@keyframes vetoShake {
  0%, 100% { transform: translate(0, 0); }
  10%  { transform: translate(-20px, -11px) rotate(-0.5deg); }
  20%  { transform: translate(16px, 8px) rotate(0.4deg); }
  30%  { transform: translate(-11px, 5px) rotate(-0.3deg); }
  40%  { transform: translate(9px, -5px) rotate(0.2deg); }
  50%  { transform: translate(-6px, 3px) rotate(-0.15deg); }
  60%  { transform: translate(4px, -2px); }
  70%  { transform: translate(-2px, 1px); }
  80%  { transform: translate(1px, 0); }
}

/* Element recoil — surrounding page elements jolt outward at impact.
   Delay 0.38s so this also triggers AT impact. */
.veto-shock > *,
.veto-shock .name-card-header,
.veto-shock .name-meta,
.veto-shock .stat-row,
.veto-shock .origin-block,
.veto-shock .gift-inline,
.veto-shock .similar-grid,
.veto-shock .panel {
  animation: vetoRecoil 0.62s ease-out 0.38s;
}
@keyframes vetoRecoil {
  0%   { transform: translate(0, 0) rotate(0); }
  12%  { transform: translate(var(--vrx, -22px), var(--vry, 10px)) rotate(var(--vrr, -1.2deg)); }
  28%  { transform: translate(calc(var(--vrx, -22px) * -0.7), calc(var(--vry, 10px) * -0.6)) rotate(calc(var(--vrr, -1.2deg) * -0.6)); }
  48%  { transform: translate(calc(var(--vrx, -22px) * 0.4), calc(var(--vry, 10px) * 0.3)) rotate(calc(var(--vrr, -1.2deg) * 0.3)); }
  100% { transform: translate(0, 0) rotate(0); }
}
.veto-shock > *:nth-child(odd) { --vrx: 22px; --vrr: 1.1deg; }
.veto-shock > *:nth-child(3n) { --vrx: -28px; --vry: 14px; --vrr: -1.6deg; }
.veto-shock > *:nth-child(4n) { --vrx: 30px; --vry: -8px; --vrr: 1.4deg; }
.veto-shock .name-title { --vrx: 0; --vry: 20px; --vrr: 0deg; }

/* CTA row that appears under the stamp once it's settled.
   Matches the stamp's -6deg tilt so the three elements feel like
   one stamped composition. Click on Send replaces the stamp with
   the pay modal; Dismiss cancels the whole flow. */
.veto-cta-wrap {
  position: absolute; top: 75%;
  /* +12px right-shift so the Send button's long text + Dismiss visually
     centre beneath the stamp (without the shift they look left-heavy). */
  left: calc(50% + 12px);
  transform: translateX(-50%) rotate(-6deg);
  display: flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap;
  opacity: 0; pointer-events: none;
  animation: vetoCtaIn 0.45s ease-out 1.0s forwards;
  width: max-content; max-width: calc(100% - 32px);
}
@keyframes vetoCtaIn {
  from { opacity: 0; transform: translate(-50%, 8px) rotate(-6deg); }
  to   { opacity: 1; transform: translate(-50%, 0) rotate(-6deg); }
}
.veto-cta-bar, .veto-dismiss-btn {
  pointer-events: auto;
  border-radius: 50px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-weight: 600;
  cursor: pointer;
  transition: transform 0.18s, box-shadow 0.18s, background 0.18s;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
}
.veto-cta-bar {
  background: var(--ink); color: white;
  border: none;
  padding: 14px 26px; font-size: 15px;
  box-shadow: 0 10px 28px rgba(0,0,0,0.28);
}
.veto-cta-bar:hover { box-shadow: 0 14px 34px rgba(0,0,0,0.32); filter: brightness(1.06); }
.veto-dismiss-btn {
  background: white; color: var(--ink);
  border: 1px solid var(--border);
  padding: 13px 22px; font-size: 14px; font-weight: 500;
  box-shadow: 0 6px 18px rgba(0,0,0,0.12);
}
.veto-dismiss-btn:hover { background: #FAF8F5; border-color: var(--ink); }
.veto-cta-bar .cta-label-short { display: none; }
@media (max-width: 640px) {
  .veto-cta-wrap {
    /* Sit right under the stamp: stamp centre is at viewport 50%
       and the rotated card's bottom edge lands ~85px below that on
       mobile (138px tall card ÷ 2 + ~15px rotation offset). 95px
       below centre places the top button a hair below the card,
       which reads as "just underneath" rather than floating. */
    top: calc(50% + 95px);
    /* Same +12px right-shift as desktop to visually centre beneath the
       tilted stamp (straight 50% reads left-of-centre). */
    left: calc(50% + 12px);
    flex-direction: column;
    width: auto;
    max-width: 316px;
    gap: 8px;
  }
  .veto-cta-bar, .veto-dismiss-btn {
    width: 100%;
    font-size: 13px;
    padding: 12px 16px;
    white-space: nowrap;
  }
  .veto-cta-bar .cta-label-long { display: none; }
  .veto-cta-bar .cta-label-short { display: inline; }
}

/* Accessibility — respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .veto-stamp { animation: vetoSlamReduced 1s ease-out forwards; }
  body.vetoing > *:not(.veto-overlay):not(.veto-modal),
  .veto-shock > *, .veto-shock .name-card-header, .veto-shock .name-meta,
  .veto-shock .stat-row, .veto-shock .origin-block, .veto-shock .gift-inline,
  .veto-shock .similar-grid, .veto-shock .panel { animation: none !important; }
  .veto-sub { animation: vetoSubFade 1s ease-out forwards; }
  .veto-cta-wrap { animation: none !important; opacity: 1; transform: translateX(-50%) rotate(-6deg); pointer-events: auto; }
  @keyframes vetoSlamReduced {
    0%   { transform: translate(-50%, -80%) scale(0.9) rotate(-6deg); opacity: 0; }
    60%, 100% { transform: translate(-50%, -50%) scale(1) rotate(-6deg); opacity: 1; }
  }
}

/* ── Veto pay modal — big two-column layout centred in viewport.
   Left: preview of what the partner will see (with the stamping
   animation playing inside). Right: form + pay CTA. ───────── */
.veto-modal-backdrop {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(20, 20, 20, 0.38);
  opacity: 0; pointer-events: none;
  transition: opacity 0.25s ease;
}
.veto-modal-backdrop.open { opacity: 1; pointer-events: auto; }
.veto-modal {
  position: fixed; left: 50%; top: 50%; z-index: 10000;
  transform: translate(-50%, -50%) scale(0.94);
  width: calc(100% - 32px); max-width: 860px;
  display: block;
  transition: transform 0.32s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.22s ease;
  opacity: 0;
  pointer-events: none;
}
.veto-modal.open { transform: translate(-50%, -50%) scale(1); opacity: 1; pointer-events: auto; }
.veto-modal-content {
  position: relative;
  background: white; border-radius: 18px; width: 100%;
  padding: 28px; box-shadow: 0 20px 60px rgba(0,0,0,0.35), 0 0 0 1px rgba(0,0,0,0.06);
  max-height: calc(100vh - 48px); overflow-y: auto;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
}
.veto-modal-x {
  position: absolute; top: 12px; right: 14px;
  background: none; border: none;
  font-size: 26px; line-height: 1; color: var(--muted);
  cursor: pointer; padding: 4px 9px; border-radius: 8px;
  transition: background 0.15s, color 0.15s;
  z-index: 2;
}
.veto-modal-x:hover { background: rgba(0,0,0,0.06); color: var(--ink); }
.veto-modal-columns {
  display: grid; grid-template-columns: 1fr 1fr; gap: 28px; align-items: stretch;
}
@media (max-width: 720px) {
  .veto-modal-content { padding: 20px; }
  .veto-modal-columns { grid-template-columns: 1fr; gap: 20px; }
  /* Preview header sits just under the X close button when stacked;
     push the Replay pill inward so it clears the X. */
  .veto-preview-header { padding-right: 38px; }
}
.veto-modal-title { font-size: 20px; font-weight: 700; color: var(--ink); margin: 0 0 3px; }
.veto-modal-sub { font-size: 14px; color: rgba(44,44,42,0.5); margin: 0 0 22px; line-height: 1.45; }
.veto-modal-field { margin: 0 0 18px; }
.veto-modal-field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; font-weight: 500; }
.veto-modal-field input, .veto-modal-field textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
  font-family: inherit; font-size: 14px; box-sizing: border-box;
  color: var(--ink); background: #FAF8F5;
}
.veto-modal-field input::placeholder,
.veto-modal-field textarea::placeholder {
  color: var(--muted); opacity: 0.55;
}
.veto-modal-field textarea { resize: vertical; min-height: 78px; }
.veto-modal-field-name { margin-top: 3px; }
.veto-modal-field-msg { margin-top: 14px; }
.veto-modal-field-header {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; margin-bottom: 8px;
}
.veto-modal-field-header label { margin-bottom: 0; }
.veto-suggest-btn {
  padding: 4px 12px 4px 10px;
  background: white; color: var(--muted);
  border: 1px solid var(--border); border-radius: 50px;
  font-family: inherit; font-size: 12px; font-weight: 500;
  cursor: pointer; transition: background 0.15s, border-color 0.15s, color 0.15s;
  display: inline-flex; align-items: center; gap: 6px;
  flex-shrink: 0;
}
.veto-suggest-btn:hover { background: #FAF8F5; border-color: var(--ink); color: var(--ink); }
.veto-suggest-btn svg { width: 11px; height: 11px; }
.veto-pay-btn {
  width: 100%; padding: 14px; border: none; border-radius: 50px;
  background: var(--veto-pay-bg, var(--ink)); color: white; font-size: 15px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: filter 0.18s, transform 0.18s;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 8px;
}
.veto-pay-btn:hover { filter: brightness(0.9); transform: translateY(-1px); }
.veto-modal-close {
  background: none; border: none; color: var(--muted); font-family: inherit;
  font-size: 13px; cursor: pointer; margin-top: 8px; width: 100%; text-align: center;
  text-decoration: underline; text-underline-offset: 3px;
}

/* ── Preview column: mock browser window showing what the partner
   will see on the veto landing page, with the VETO stamp animation
   playing inside it. ────────────────────────────────────────── */
.veto-preview-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.veto-preview-header {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
}
.veto-preview-label {
  font-size: 11px; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.1em;
}
.veto-replay-btn {
  background: white; border: 1px solid var(--border);
  padding: 4px 12px 4px 10px; border-radius: 50px;
  font-family: inherit; font-size: 12px; font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: opacity 0.25s ease, background 0.15s, border-color 0.15s, color 0.15s;
}
.veto-replay-btn:hover { background: #FAF8F5; border-color: var(--ink); color: var(--ink); }
.veto-replay-btn svg { width: 11px; height: 11px; }
.veto-replay-btn.hidden { opacity: 0; pointer-events: none; }
.veto-preview-box {
  display: flex; flex-direction: column;
  flex: 1; min-height: 300px;
  background: white; border: 1px solid #d8d3c9;
  border-radius: 10px; overflow: hidden; cursor: pointer;
  user-select: none;
  box-shadow: 0 4px 14px rgba(0,0,0,0.08);
}
.veto-browser-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  background: linear-gradient(to bottom, #efeae0, #e6e0d2);
  border-bottom: 1px solid #d8d3c9;
  flex-shrink: 0;
}
.veto-browser-dots { display: flex; gap: 5px; }
.veto-browser-dot {
  width: 10px; height: 10px; border-radius: 50%;
  display: inline-block;
}
.veto-browser-url {
  flex: 1; min-width: 0;
  background: white; border: 1px solid #d8d3c9;
  border-radius: 6px; padding: 4px 10px;
  font-size: 11px; color: var(--muted);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.veto-preview-page {
  position: relative; flex: 1;
  background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px 16px;
  text-align: center; overflow: hidden;
  transition: background 0.3s ease;
}
.veto-preview-content {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.veto-preview-page.bumping .veto-preview-content {
  animation: vetoPreviewShake 0.45s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}
@keyframes vetoPreviewShake {
  0%, 100% { transform: translate(0, 0) rotate(0); }
  15% { transform: translate(-9px, -4px) rotate(-0.5deg); }
  30% { transform: translate(7px, 3px) rotate(0.4deg); }
  45% { transform: translate(-5px, 2px) rotate(-0.2deg); }
  60% { transform: translate(3px, -1px) rotate(0.15deg); }
  75% { transform: translate(-1px, 0); }
}
.veto-preview-name {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: clamp(44px, 8vw, 76px);
  font-weight: 700; line-height: 1; margin: 0;
  color: var(--ink);
}
.veto-preview-msg {
  position: absolute;
  top: calc(50% + 72px);
  left: 50%;
  transform: translateX(-50%);
  width: 90%; max-width: 300px;
  text-align: center;
  font-style: italic; font-size: 13px; color: var(--muted);
  line-height: 1.35;
}
/* Emoji within the italic preview msg render in their own (upright)
   font so they don't slant. Wrapping happens in updateVetoPreview. */
.veto-preview-msg .emoji {
  font-style: normal;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.veto-preview-msg:empty { display: none; }
.veto-preview-stamp {
  position: absolute; top: 50%; left: 50%;
  font-family: 'Impact', 'Arial Black', sans-serif;
  font-size: clamp(30px, 5.4vw, 48px);
  font-weight: 900; letter-spacing: 0.04em;
  color: #fff; padding: 8px 22px;
  border: 5px solid #fff; border-radius: 6px;
  background: #A8543C;
  text-shadow: 0 0 14px rgba(231,76,60,0.9), 2px 2px 0 rgba(0,0,0,0.55);
  box-shadow: 0 0 24px rgba(231,76,60,0.55), 0 10px 22px rgba(0,0,0,0.22);
  opacity: 0; pointer-events: none; text-align: center;
  transform: translate(-50%, -260%) scale(1.15) rotate(-20deg);
}
.veto-preview-stamp-from,
.veto-preview-stamp-sub {
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 10px; font-weight: 600; letter-spacing: 0.12em;
  text-shadow: 1px 1px 0 rgba(0,0,0,0.5);
  text-align: center;
}
.veto-preview-stamp-from { margin-bottom: 4px; }
.veto-preview-stamp-from:empty { display: none; }
.veto-preview-stamp-sub { margin-top: 2px; }
.veto-preview-stamp.playing {
  animation: vetoPreviewSlam 0.9s cubic-bezier(0.5, 0, 0.85, 0.05) forwards;
}
@keyframes vetoPreviewSlam {
  0%   { transform: translate(-50%, -260%) scale(1.15) rotate(-20deg); opacity: 0; }
  8%   { transform: translate(-50%, -260%) scale(1.15) rotate(-20deg); opacity: 1; }
  42%  { transform: translate(-50%, -50%) scale(1.1, 0.9) rotate(-6deg); opacity: 1; }
  48%  { transform: translate(-50%, -54%) scale(0.92, 1.08) rotate(-6deg); }
  64%  { transform: translate(-50%, -50%) scale(1) rotate(-6deg); }
  100% { transform: translate(-50%, -50%) scale(1) rotate(-6deg); opacity: 1; }
}
.veto-form-col { display: flex; flex-direction: column; min-width: 0; }

/* Mini heart for similar / less-common cards */
.similar-card { position: relative; }
.similar-card .mini-heart {
  position: absolute; top: 12px; right: 8px;
  width: 25px; height: 25px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: white; border: 1px solid var(--border);
  cursor: pointer; transition: all 0.18s;
  color: var(--muted); padding: 0; z-index: 2;
}
.similar-card .mini-heart:hover { color: #B8943E; }
.similar-card .mini-heart.hearted { color: #B8943E; background: #FDF6E3; border-color: #B8943E; }
.similar-card .mini-heart svg { width: 12px; height: 12px; }

/* ── Shortlist panel ─────────────────────────────────────────── */
.shortlist-empty { text-align: center; padding: 2.5rem 1rem; color: var(--muted); }
@media (max-width: 600px) { .desktop-only { display: none; } }
@keyframes emptyHeartPulse {
  0%, 100% { transform: scale(1); }
  15% { transform: scale(1.15); }
  30% { transform: scale(1); }
  45% { transform: scale(1.1); }
  60% { transform: scale(1); }
}
.shortlist-empty .big-emoji { font-size: 48px; margin-bottom: 12px; }
.shortlist-list { display: flex; flex-direction: column; gap: 8px; }
.shortlist-item {
  display: flex; align-items: center; gap: 12px;
  background: white; border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 14px; cursor: pointer; transition: all 0.18s;
}
.shortlist-item:hover { border-color: #B8943E; transform: translateY(-1px); }
.shortlist-item-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 18px; font-weight: 500; flex: 1; }
.shortlist-item-name.girl { color: var(--pink); }
.shortlist-item-name.boy { color: var(--blue); }
.shortlist-item-name.unisex { color: var(--amber); }
.shortlist-item-meta { font-size: 12px; color: var(--muted); }
.shortlist-remove {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--border); cursor: pointer;
  color: var(--muted); transition: all 0.18s; padding: 0; flex-shrink: 0;
}
.shortlist-remove:hover { color: var(--coral); border-color: var(--coral); background: #FDF6E3; }
.shortlist-goto {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--border); cursor: pointer;
  color: var(--muted); transition: all 0.18s; padding: 0; flex-shrink: 0;
}
.shortlist-goto:hover { color: var(--ink); border-color: var(--ink); background: var(--cream); }

/* Styled tooltips for shortlist action buttons */
.shortlist-goto, .shortlist-remove { position: relative; }
.shortlist-goto::after, .shortlist-remove::after {
  content: attr(data-tip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  padding: 5px 10px; background: var(--ink); color: white; border-radius: 6px;
  font-size: 11px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.1s; margin-bottom: 6px;
}
.shortlist-goto:hover::after, .shortlist-remove:hover::after { opacity: 1; }
.shortlist-remove svg { width: 14px; height: 14px; }
.shortlist-count { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; border-radius: 9px; background: var(--coral); color: white; font-size: 11px; font-weight: 600; margin-left: 4px; padding: 0 5px; }

/* Floating shortlist button */
.shortlist-fab {
  position: fixed; bottom: 24px; right: 24px; z-index: 900;
  display: none; align-items: center; gap: 6px;
  padding: 12px 18px; border-radius: 50px;
  background: linear-gradient(135deg, #B8943E 0%, #D4B05A 50%, #B8943E 100%); color: white; border: none; text-shadow: 0 1px 1px rgba(0,0,0,0.1);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 600;
  cursor: pointer; box-shadow: 0 4px 16px rgba(0,0,0,0.15);
  transition: all 0.2s; white-space: nowrap;
}
.shortlist-fab.visible { display: flex; }
.shortlist-fab:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.2); }
.shortlist-fab svg { width: 18px; height: 18px; }
.shortlist-fab .fab-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; border-radius: 10px;
  background: white; color: #B8943E; font-size: 12px; font-weight: 700;
  padding: 0 5px;
}
@media (max-width: 600px) {
  .shortlist-fab { bottom: 16px; right: 16px; padding: 10px 14px; font-size: 13px; }
  .shortlist-item-meta { display: none; }
  .shortlist-copy-full { display: none !important; }
  .shortlist-copy-short { display: inline !important; }
  .shortlist-item-grip { display: none; }
  .shortlist-item { draggable: false; }
  .shortlist-arrows { display: flex !important; }
  #persuaderModal .share-modal-content { margin-top: 0; }
}
.shortlist-arrows {
  display: none; flex-direction: column; gap: 2px; flex-shrink: 0;
}
.shortlist-arrow {
  width: 24px; height: 18px; border: none; background: none;
  color: var(--muted); cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px; transition: background 0.15s;
}
.shortlist-arrow:active { background: var(--cream); }
.shortlist-arrow:disabled { opacity: 0.2; }
/* FAB pulse + heart icon pulse when adding */
.shortlist-fab .fab-heart-icon {
  transition: transform 0.3s ease;
  display: inline-flex; align-items: center; position: relative; top: 1px;
}
.shortlist-fab.fab-added {
  animation: fabBtnPulse 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes fabBtnPulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.1); }
  100% { transform: scale(1); }
}
/* Hearts that float upward from FAB */
.fab-float-heart {
  position: fixed; pointer-events: none; z-index: 901;
  color: #B8943E; opacity: 0;
  animation: floatHeartUp var(--dur) ease-out forwards;
  animation-delay: var(--delay);
}
@keyframes floatHeartUp {
  0% { opacity: 0; transform: translate(0, 0) scale(0.5); }
  8% { opacity: 0.7; }
  20% { opacity: 0.6; transform: translate(var(--drift1), -12px) scale(0.85); }
  50% { opacity: 0.4; transform: translate(var(--drift2), -35px) scale(0.75); }
  80% { opacity: 0.12; transform: translate(var(--drift3), -58px) scale(0.6); }
  100% { opacity: 0; transform: translate(var(--drift3), -70px) scale(0.5); }
}
.shortlist-partner-cta {
  display: block; width: 100%; margin-top: 1.25rem; padding: 14px;
  background: var(--ink); color: white; border: none; border-radius: 12px;
  font-size: 15px; font-weight: 500; cursor: pointer; text-align: center;
  transition: all 0.18s;
}
.shortlist-partner-cta:hover { background: #1a1a18; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
.shortlist-partner-hint {
  text-align: center; font-size: 13px; color: var(--ink); margin-top: 10px; line-height: 1.5;
  padding: 12px 16px; background: #F5F1EA; border-radius: 10px;
}

/* Drag-and-drop for shortlist items */
.shortlist-item { cursor: grab; user-select: none; -webkit-user-select: none; touch-action: manipulation; transition: transform 0.15s ease, opacity 0.15s ease; }
.shortlist-item:active { cursor: grabbing; }
.shortlist-item.dragging { opacity: 0.4; transform: scale(0.97); border-color: #B8943E; }
.shortlist-item-grip { color: var(--muted); font-size: 16px; flex-shrink: 0; margin-right: 2px; }
.shortlist-item-rank {
  width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; background: var(--cream); color: var(--muted);
}

/* Add name input in shortlist */
.shortlist-add {
  display: flex; gap: 8px; margin-bottom: 12px;
}
.shortlist-add input {
  flex: 1; padding: 10px 14px; border: 1.5px solid var(--border); border-radius: 10px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; outline: none;
  transition: border-color 0.18s;
}
.shortlist-add input::placeholder { color: #b0afa8; }
.shortlist-add input:focus { border-color: #B8943E; }
.shortlist-add button {
  padding: 10px 16px; border-radius: 10px; border: 1.5px solid var(--border);
  background: var(--cream); cursor: pointer; font-size: 13px; font-weight: 500;
  color: var(--ink); transition: all 0.18s; white-space: nowrap;
}
.shortlist-add button:hover { border-color: var(--ink); }

/* Quick-add chip — surfaces the currently-viewed name as a one-click
   add at the top of the shortlist widget (and at the bottom of the
   Name Harmony result). Uses the same gold palette as the heart
   shortlist button on the profile so the "add to shortlist" action
   reads as one consistent affordance across the site. */
.shortlist-quick-add {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; padding: 10px 14px;
  margin-bottom: 12px;
  border: 1.5px solid rgba(184,148,62,0.5); border-radius: 10px;
  background: white; color: #B8943E;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 14px; font-weight: 500;
  cursor: pointer; transition: all 0.18s;
  text-align: center;
}
.shortlist-quick-add:hover { background: #FDF6E3; border-color: #B8943E; }
.shortlist-quick-add strong { font-weight: 600; }
.shortlist-quick-add svg { width: 14px; height: 14px; flex-shrink: 0; }
.shortlist-quick-add.saved { background: #FDF6E3; border-color: #B8943E; }

/* Side-by-side row: chip on the left, type-a-name input + Add
   button on the right. Stacks on mobile so each row keeps its
   width budget. When the chip is hidden (no current name) the
   input fills the row naturally. */
.shortlist-add-pair {
  display: flex; gap: 8px; align-items: stretch; margin-bottom: 12px;
}
.shortlist-add-pair > .shortlist-quick-add {
  width: auto; flex: 0 0 auto; margin-bottom: 0;
}
.shortlist-add-pair > .shortlist-add {
  flex: 1 1 0; margin-bottom: 0;
}
@media (max-width: 640px) {
  .shortlist-add-pair { flex-direction: column; }
  .shortlist-add-pair > .shortlist-quick-add { width: 100%; }
}

/* ── Partner ranking UI ──────────────────────────────────────── */
.partner-overlay {
  position: fixed; inset: 0; z-index: 2000;
  background: var(--cream); overflow-y: auto;
  display: none; flex-direction: column;
}
.partner-overlay.visible { display: flex; }
.partner-header {
  position: sticky; top: 0; z-index: 100;
  background: white;
  border-bottom: 1px solid var(--border);
}
.partner-header .topnav-logo { top: 1px; }
.partner-header h2 { display: none; }
.partner-header p { display: none; }
.partner-body { flex: 1; max-width: 590px; margin: 0 auto; width: 100%; padding: 1rem; }
.partner-signin-prompt { text-align: center; padding: 3rem 1rem; }
.partner-signin-prompt p { margin-bottom: 1rem; color: var(--muted); }

/* Drag-and-drop ranking list */
.rank-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.rank-item {
  display: flex; align-items: center; gap: 10px;
  background: white; border: 1.5px solid var(--border); border-radius: 12px;
  padding: 12px 14px; cursor: grab; transition: all 0.15s;
  user-select: none; -webkit-user-select: none; touch-action: manipulation;
}
.rank-item:active { cursor: grabbing; }
.rank-item.dragging { opacity: 0.5; border-color: #B8943E; }
.rank-item.drag-over { border-color: #B8943E; transform: scale(1.02); }
.rank-num {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; flex-shrink: 0;
  background: var(--cream); color: var(--muted);
}
/* All rank numbers use consistent styling */
.rank-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 18px; font-weight: 500; flex: 1; }
.rank-grip { color: var(--muted); font-size: 18px; flex-shrink: 0; }
.rank-submit {
  display: block; width: 100%; margin-top: 1.5rem; padding: 14px;
  background: var(--coral); color: white; border: none; border-radius: 12px;
  font-size: 15px; font-weight: 500; cursor: pointer; text-align: center; transition: all 0.18s;
}
.rank-submit:hover { opacity: 0.9; transform: translateY(-1px); }
.rank-hint { text-align: center; font-size: 13px; color: var(--muted); margin: 0.75rem 0 0.5rem; }

/* Results view */
.results-list { display: flex; flex-direction: column; gap: 8px; margin-top: 1rem; }
.result-item {
  display: flex; align-items: center; gap: 10px;
  background: white; border: 1.5px solid var(--border); border-radius: 12px;
  padding: 12px 14px;
}
.result-item.match { border-color: var(--result-match-border, var(--border)); background: white; }
.result-medal { font-size: 22px; width: 32px; text-align: center; flex-shrink: 0; }
.result-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 18px; font-weight: 500; flex: 1; }
.result-ranks { font-size: 12px; color: var(--muted); text-align: right; line-height: 1.5; }
.partner-close {
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--cream); border: 1px solid var(--border);
  cursor: pointer; font-size: 18px; color: var(--ink); flex-shrink: 0;
}

/* ── Share page tabs ─────────────────────────────────────────── */
.share-tab-view { display: none; }
.share-tab-view.active { display: block; }

/* Stepper progress */
.share-stepper { display: flex; align-items: center; justify-content: center; gap: 0; }
.step { display: flex; align-items: center; gap: 6px; }
.step-num {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; border: 1.5px solid var(--border);
  color: var(--muted); background: white; transition: all 0.2s;
}
.step.done .step-num { background: var(--ink); color: white; border-color: var(--ink); }
.step.active .step-num { background: var(--ink); color: white; border-color: var(--ink); }
.step-label { font-size: 13px; font-weight: 500; color: var(--muted); }
.step.done .step-label { color: var(--ink); }
.step.active .step-label { color: var(--ink); }
.step-line { width: 32px; height: 1.5px; background: var(--border); margin: 0 8px; }
.step.done + .step-line { background: var(--ink); }

/* Animated waiting dots */
.waiting-dots::after {
  content: '';
  animation: waitDots 1.5s steps(4, end) infinite;
}
@keyframes waitDots {
  0% { content: ''; }
  25% { content: '.'; }
  50% { content: '..'; }
  75% { content: '...'; }
}

/* Legacy toggle (keep for switchShareMode) */
.share-toggle-btn { display: none; }

/* Editable heading fields */
.editable-field {
  border: none; background: none; font-family: 'Lora', 'Lora Fallback', serif; text-align: center;
  width: 100%; outline: none; padding: 2px 4px; border-radius: 6px;
  transition: background 0.15s;
}
.editable-field.editable:hover { background: rgba(0,0,0,0.03); cursor: text; }
.editable-field.editable:focus { background: rgba(0,0,0,0.05); }
.editable-field.heading { font-size: 26px; font-weight: 600; color: var(--ink); }
.editable-field.subtext { font-size: 16px; font-weight: 400; color: var(--muted); font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; }
.edit-hint { font-size: 11px; color: var(--muted); text-align: center; margin-top: 4px; opacity: 0.7; }

/* Price badge */
.price-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 600;
  background: var(--cream); color: var(--ink); border: 1px solid var(--border);
}

/* ── Sign-in button ──────────────────────────────────────────── */
.signin-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: 50px;
  font-size: 13px; font-weight: 500;
  border: 1.5px solid var(--border); background: white;
  cursor: pointer; transition: all 0.18s; color: var(--ink);
  white-space: nowrap;
}
.signin-btn:hover { border-color: var(--coral); }
.signin-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.signin-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  object-fit: cover; border: 1.5px solid var(--border);
}
.signin-dropdown {
  position: absolute; right: 0; top: 100%; margin-top: 6px;
  background: white; border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.08); padding: 6px 0;
  min-width: 180px; z-index: 1000; display: none;
}
.signin-dropdown.visible { display: block; }
.signin-dropdown-item {
  display: block; width: 100%; padding: 10px 16px;
  font-size: 14px; color: var(--ink); background: none; border: none;
  cursor: pointer; text-align: left;
}
.signin-dropdown-item:hover { background: var(--cream); }
.signin-wrapper { position: relative; }

/* ── Share modal ─────────────────────────────────────────────── */
.share-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: none; align-items: center; justify-content: center;
}
.share-modal.open { display: flex; }
.share-modal-backdrop { position: absolute; inset: 0; background: rgba(20, 20, 20, 0.45); }
.share-modal-content {
  position: relative; background: white;
  border-radius: 18px; padding: 1.5rem 1.5rem 1.25rem;
  width: calc(100% - 2rem); max-width: 380px;
  box-shadow: 0 14px 40px rgba(0,0,0,0.18);
  animation: shareModalIn 0.22s ease;
}
.share-modal-content.has-card { max-width: 380px; padding: 1.5rem 1.5rem 1.75rem; }
.share-modal-content.has-card .share-links-col { display: none; }
.share-modal-content:not(.has-card) .share-card-col { display: none !important; }
.share-modal-content.site-share { max-width: 500px; padding: 1.75rem 1.75rem 1.75rem; }
.share-link-icon { width: 32px; height: 32px; border-radius: 50%; background: var(--cream); border: 1px solid var(--border); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.16s; text-decoration: none; color: var(--ink); font-size: 14px; }
.share-link-icon:hover { border-color: var(--ink); background: white; }
@keyframes shareModalIn { from { opacity: 0; transform: translateY(8px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }
.share-modal-close {
  position: absolute; top: 12px; right: 12px;
  width: 30px; height: 30px; border-radius: 50%;
  border: none; background: var(--cream); color: var(--muted);
  cursor: pointer; font-size: 18px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  z-index: 2;
}
.share-modal-close:hover { background: var(--border); color: var(--ink); }
.share-modal-title {
  font-family: 'Lora', 'Lora Fallback', serif; font-size: 20px; font-weight: 600;
  color: var(--ink); margin: 0 0 1.25rem; padding-right: 30px;
}
.share-modal-sub {
  font-size: 14px; color: var(--muted);
  margin: -1rem 0 1.25rem; line-height: 1.45;
  padding-right: 30px;
}
.share-modal-sub:empty { display: none; }
.share-options { display: flex; flex-direction: column; gap: 8px; }
.share-option {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; border-radius: 12px;
  background: var(--cream); border: 1px solid var(--border);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500; color: var(--ink);
  text-decoration: none; cursor: pointer; transition: all 0.16s;
}
.share-option:hover { background: white; border-color: var(--ink); transform: translateY(-1px); }
#shareCardDownloadBtn:hover { background: rgba(0,0,0,0.03); border-color: var(--border); }
.share-option-icon { width: 20px; height: 20px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
/* Stat card preview */
.card-preview-wrap { position: relative; border-radius: 10px; overflow: hidden; background: #f5f2ed; }
.card-preview-wrap canvas { display: block; width: 100%; height: auto; }
@keyframes cardShimmer { 0% { transform: translateX(-100%) skewX(-15deg); } 100% { transform: translateX(250%) skewX(-15deg); } }
.card-preview-wrap.shimmer::after {
  content: ''; position: absolute; top: -20%; left: 0; width: 50%; height: 140%;
  background: linear-gradient(110deg, transparent, rgba(255,255,255,0.35), transparent);
  animation: cardShimmer 0.7s ease 0.2s both;
  pointer-events: none;
}
.card-bottom { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.card-bottom .card-nav-dots { display: flex; gap: 5px; flex: 1; }
.card-nav-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border); transition: background 0.2s; }
.card-nav-dot.active { background: var(--ink); }
.card-switch-btn { background: var(--cream); border: 1px solid var(--border); border-radius: 50px; padding: 5px 14px; font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 12px; cursor: pointer; color: var(--ink); transition: all 0.16s; white-space: nowrap; }
.card-switch-btn:hover { border-color: var(--ink); }
@keyframes spinOnce { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.card-rotate-btn { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--border); background: white; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; transition: background 0.16s, border-color 0.16s; color: #aaa; position: absolute; z-index: 2; }
.card-rotate-btn:hover { opacity: 0.85; }
.card-rotate-btn.spinning svg { animation: spinOnce 0.4s ease; }
.card-actions { display: flex; gap: 8px; margin-top: 8px; }
.card-actions button { flex: 1; padding: 8px; border-radius: 50px; font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 13px; font-weight: 500; cursor: pointer; }
.card-save-btn { border: 1.5px solid var(--border); background: white; color: var(--ink); }
.card-share-btn { border: none; background: var(--ink); color: white; }
.share-toast {
  position: absolute; bottom: -40px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: white;
  padding: 8px 16px; border-radius: 50px;
  font-size: 13px; font-weight: 500;
  opacity: 0; transition: opacity 0.2s, bottom 0.2s;
  pointer-events: none;
}
.share-toast.visible { opacity: 1; bottom: -52px; }
#persuaderNameInput::placeholder { font-size: 15px; color: var(--muted); opacity: 0.7; }
#persuaderModal .share-modal-content { max-width: 430px; margin-top: -30px; }
.persuader-toggle {
  display: flex; gap: 4px; padding: 4px;
  background: #F5F1EA; border-radius: 50px;
  margin: 0 0 1rem;
}
.persuader-toggle button {
  flex: 1; padding: 8px 12px;
  border: none; border-radius: 50px; background: transparent;
  color: var(--muted);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif; font-size: 14px; font-weight: 500;
  /* Colour transitions are deliberately omitted: when an inactive pill is
     hovered red/teal then clicked, easing the text colour from red/teal
     to white while the bg eases from transparent to solid red/teal causes
     the text to briefly match the bg mid-fade and read as invisible.
     Snapping colour instantly while the bg still eases keeps the
     transition smooth without the disappearing-text glitch. */
  cursor: pointer; transition: background 0.18s, box-shadow 0.18s;
  line-height: 1.2;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
}
.persuader-toggle button svg { width: 14px; height: 14px; flex-shrink: 0; }
/* Active states mirror the cta-pair colours used on the cards (teal for
   "Make the case", #A8543C for "Veto") so the popup reads as the same
   visual family as the inline CTA bars the user already saw. */
.persuader-toggle #persuaderToggleConvince.active {
  background: var(--teal); color: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
.persuader-toggle #persuaderToggleVeto.active {
  background: #A8543C; color: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
/* Inactive-pill hover preview — tint the text in its mode colour so the
   user can see what they're about to switch to before clicking. */
#persuaderToggleConvince:not(.active):hover { color: var(--teal); }
#persuaderToggleConvince:not(.active):hover svg { color: var(--teal); }
#persuaderToggleVeto:not(.active):hover { color: #A8543C; }
#persuaderToggleVeto:not(.active):hover svg { color: #A8543C; }
/* Submit-button hover — JS sets the background colour inline based on
   mode, so we use filter: brightness() to darken on hover without
   needing to know which colour is currently applied. */
#persuaderSubmitBtn:not(:disabled):hover { filter: brightness(0.92); }
.share-msg-block { margin: 0 0 8px; }
.share-options-copy { margin-bottom: 10px; }
.share-options-copy + .share-options { margin-top: 0; }
.share-modal-content.site-share .share-options-copy .share-option.share-option-primary {
  background: var(--ink); color: white; border-color: var(--ink);
  font-weight: 600; justify-content: center;
}
.share-modal-content.site-share .share-options-copy .share-option.share-option-primary:hover {
  filter: brightness(1.15); background: var(--ink);
}
.share-modal-content.site-share #shareOptionsMain .share-option:hover {
  background: #F5F1EA; border-color: var(--border);
}
.share-or-divider {
  display: flex; align-items: center; gap: 10px;
  margin: 18px 0 14px;
}
.share-or-divider div { flex: 1; height: 1px; background: var(--border); }
.share-or-divider span {
  font-size: 13px; color: var(--muted); font-weight: 500;
}
.share-msg-heading {
  font-family: 'Lora', 'Lora Fallback', serif; font-size: 17px;
  font-weight: 600; color: var(--ink);
}
.share-msg-header {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; margin-bottom: 16px;
}
.share-msg-header label {
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 13px; font-weight: 500; color: var(--ink);
}
#siteShareMsgInput {
  width: 100%; padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
  font-family: inherit; font-size: 14px; line-height: 1.45;
  box-sizing: border-box; color: var(--ink); background: white;
  resize: vertical; min-height: 68px; outline: none;
}
#siteShareMsgInput:focus { border-color: var(--ink); }
.about-section h2, .about-section h3 {
  font-family: 'Lora', 'Lora Fallback', serif; font-size: 20px; color: var(--ink);
  margin-bottom: 0.75rem; margin-top: 1.5rem; font-weight: 600;
}
.about-section h2 { margin-top: 0; margin-bottom: 1rem; }
.about-section p {
  font-size: 16px; color: var(--muted); line-height: 1.8; margin-bottom: 1rem;
}
.expert-cta-primary, .expert-cta-secondary {
  transition: transform 0.16s ease, background 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}
.expert-cta-primary:hover {
  background: #000 !important;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.18);
}
.expert-cta-secondary:hover {
  background: white !important;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.08);
}
.expert-cta-primary:focus-visible, .expert-cta-secondary:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px;
}

/* "Convince them on X" buttons in the 3-strikes nudge modal. The
 * inline style sets the resting look (ink background, white text);
 * this just adds the hover/focus polish that earlier was missing. */
.nudge-cta-btn:hover {
  background: #000 !important;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.18);
}
.nudge-cta-btn:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px;
}

/* Michelle's name of the week — AU-only, pre-search only. Full-width
   section sitting just above About. Colour scheme follows the name's
   gender via data-gender on the card (g=pink, b=blue, u=amber).
   refreshExpertFooterVisibility toggles data-au=1 once geo is known. */
#nameOfWeekCard {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin: 3rem 0 0;
  padding: 1.75rem 1.5rem 1.5rem;
  border: 1px solid transparent;
  border-radius: 18px;
  text-align: center;
  box-sizing: border-box;
}
body.pre-search #nameOfWeekCard[data-au="1"] { display: flex; }
#nameOfWeekCard[data-gender="g"] {
  background: #FDF3F7;
  border-color: rgba(194,84,122,0.18);
}
#nameOfWeekCard[data-gender="g"] .now-name { color: var(--pink); }
#nameOfWeekCard[data-gender="g"] .now-name-btn:hover .now-arrow,
#nameOfWeekCard[data-gender="g"] .now-name-btn:focus-visible .now-arrow { color: var(--pink); }
#nameOfWeekCard[data-gender="b"] {
  background: #F1F6FA;
  border-color: rgba(74,144,191,0.18);
}
#nameOfWeekCard[data-gender="b"] .now-name { color: var(--blue); }
#nameOfWeekCard[data-gender="b"] .now-name-btn:hover .now-arrow,
#nameOfWeekCard[data-gender="b"] .now-name-btn:focus-visible .now-arrow { color: var(--blue); }
#nameOfWeekCard[data-gender="u"] {
  background: #FDF6EC;
  border-color: rgba(200,147,26,0.18);
}
#nameOfWeekCard[data-gender="u"] .now-name { color: var(--amber); }
#nameOfWeekCard[data-gender="u"] .now-name-btn:hover .now-arrow,
#nameOfWeekCard[data-gender="u"] .now-name-btn:focus-visible .now-arrow { color: var(--amber); }
.now-name-btn {
  background: none; border: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 14px;
  padding: 0;
  font-family: 'Lora', 'Lora Fallback', serif;
  line-height: 1;
}
.now-name {
  font-size: 54px; font-weight: 600;
  line-height: 1; letter-spacing: -0.015em;
}
.now-arrow {
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 30px; font-weight: 400;
  line-height: 1;
  color: rgba(0,0,0,0.28);
  transition: transform 0.18s ease, color 0.18s ease;
  display: inline-block;
}
.now-name-btn:hover .now-arrow,
.now-name-btn:focus-visible .now-arrow { transform: translateX(6px); }
.now-name-btn:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 6px; border-radius: 4px;
}
.now-quote {
  font-family: 'Lora', 'Lora Fallback', serif; font-style: italic;
  font-size: 17px; color: var(--muted);
  line-height: 1.55;
  max-width: 520px;
  margin: 0;
  text-wrap: balance;
}
.now-credit {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: 2px;
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 13px; color: var(--muted);
}
.now-avatar {
  border: none; padding: 0; cursor: pointer;
  width: 36px; height: 36px; border-radius: 50%;
  overflow: hidden; background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  transition: transform 0.16s ease;
  flex-shrink: 0;
}
.now-avatar:hover { transform: scale(1.08); }
.now-avatar img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
  display: block;
}
.now-handle {
  color: var(--ink); font-weight: 500;
  text-decoration: none;
}
.now-handle:hover { text-decoration: underline; }
@media (max-width: 640px) {
  #nameOfWeekCard { padding: 1.5rem 1rem 1.25rem; gap: 12px; margin-top: 2.25rem; }
  .now-name { font-size: 42px; }
  .now-arrow { font-size: 22px; }
  .now-quote { font-size: 15px; }
}

/* ── Shortlist insight: a one-line read of the user's shortlist ─── */
.tot-insight {
  display: flex; align-items: flex-start; gap: 12px;
  width: 100%; margin: 0 0 14px; padding: 12px 14px;
  background: linear-gradient(135deg, #FDF6E3 0%, #FAECE7 100%);
  border: 1px solid #E8D9B0; border-radius: 12px;
  font-size: 14px; line-height: 1.45; color: var(--ink);
  font-family: inherit; text-align: left;
  cursor: pointer; transition: all 0.18s;
}
.tot-insight:hover {
  border-color: #B8943E;
  background: linear-gradient(135deg, #FDF1D6 0%, #FBE2D5 100%);
  box-shadow: 0 4px 14px rgba(184,148,62,0.15);
  transform: translateY(-1px);
}
.tot-insight:hover .tot-insight-link { color: #8E7030; text-decoration-color: #B8943E; }
.tot-insight:focus-visible { outline: 2px solid #B8943E; outline-offset: 2px; }
.tot-insight-icon {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  margin-top: 0;
}
.tot-insight-icon svg { display: block; width: 22px; height: 22px; }
/* Trait emoji on the bar — sized up so it reads at the same visual
   weight as the previous SVG sparkle. */
.tot-insight-emoji {
  font-size: 20px;
  line-height: 24px;
}
/* Gender tint applies to anything coloured by currentColor (the modal
   title sparkle, and the bar icon when it's an SVG). */
.tot-insight-amber { color: #B8943E; }
.tot-insight-girl  { color: var(--pink); }
.tot-insight-boy   { color: var(--blue); }
/* Search-pattern toast — light gender-tinted backgrounds with full-tint
   borders and SVG sparkle particles in a darker shade of the same hue.
   Mirrors the seasonal toasts' light-on-dark-text aesthetic (winter /
   spring / summer / autumn). */
.tot-search-toast {
  max-width: 820px !important;
  cursor: pointer;
  overflow: hidden !important;
  transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
}
.tot-search-toast:hover {
  transform: translateX(-50%) translateY(-2px);
}
@media (max-width: 768px) {
  .tot-search-toast:hover { transform: translateY(-2px); }
}

/* Girls — pink */
.tot-search-toast.tot-toast-girl {
  background: linear-gradient(135deg, #FAE8EF 0%, #FCEEF3 100%) !important;
  border: 2px solid var(--pink) !important;
  color: #6a2c4a !important;
  box-shadow: 0 10px 28px rgba(194, 84, 122, 0.22) !important;
}
.tot-search-toast.tot-toast-girl:hover {
  box-shadow: 0 14px 36px rgba(194, 84, 122, 0.32) !important;
}
.tot-search-toast.tot-toast-girl .tot-search-particle { color: var(--pink); }
.tot-search-toast.tot-toast-girl button { color: rgba(106, 44, 74, 0.4) !important; }
.tot-search-toast.tot-toast-girl button:hover { color: #6a2c4a !important; }

/* Boys — blue */
.tot-search-toast.tot-toast-boy {
  background: linear-gradient(135deg, #E4EEF5 0%, #ECF3F8 100%) !important;
  border: 2px solid var(--blue) !important;
  color: #1e3a5c !important;
  box-shadow: 0 10px 28px rgba(74, 144, 191, 0.22) !important;
}
.tot-search-toast.tot-toast-boy:hover {
  box-shadow: 0 14px 36px rgba(74, 144, 191, 0.32) !important;
}
.tot-search-toast.tot-toast-boy .tot-search-particle { color: var(--blue); }
.tot-search-toast.tot-toast-boy button { color: rgba(30, 58, 92, 0.4) !important; }
.tot-search-toast.tot-toast-boy button:hover { color: #1e3a5c !important; }

/* Mixed / unisex — amber/gold */
.tot-search-toast.tot-toast-amber {
  background: linear-gradient(135deg, #FDF3D8 0%, #FAE6C4 100%) !important;
  border: 2px solid var(--amber) !important;
  color: #5c4400 !important;
  box-shadow: 0 10px 28px rgba(200, 147, 26, 0.22) !important;
}
.tot-search-toast.tot-toast-amber:hover {
  box-shadow: 0 14px 36px rgba(200, 147, 26, 0.32) !important;
}
.tot-search-toast.tot-toast-amber .tot-search-particle { color: var(--amber); }
.tot-search-toast.tot-toast-amber button { color: rgba(92, 68, 0, 0.4) !important; }
.tot-search-toast.tot-toast-amber button:hover { color: #5c4400 !important; }

/* Particle styling — particles inherit the tint colour from the toast
   class above. Opacity dialed in via the keyframes. */
.tot-search-particle { opacity: 0; }
.tot-search-particle svg { display: block; }

/* Floating sparkle particles — drift diagonally down through the toast,
   staggered so they don't all enter at the same time. Mirrors the
   cleverPetal / cleverLeaf timing used by the seasonal toasts. */
@keyframes tot-toast-sparkle {
  0% { transform: translate(0, -10px) rotate(0deg); opacity: 0; }
  10% { opacity: 0.85; }
  50% { transform: translate(10px, 35px) rotate(80deg); opacity: 0.65; }
  90% { opacity: 0.5; }
  100% { transform: translate(-4px, 80px) rotate(180deg); opacity: 0; }
}

/* When a trait uses the sparkle emoji (Classic, light, etc.), we swap to
   a gender-tinted SVG so it reads as part of the brand language. */
.tot-dna-trait-emoji-svg {
  display: inline-flex; align-items: center; justify-content: center;
}
.tot-dna-trait-emoji-svg svg { display: block; }
.tot-insight-content {
  flex: 1; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 4px 12px;
  /* Match the icon container's height so the visible glyphs of the text
     line up with the icon's geometric centre. Without this, a 14-px font
     at 1.45 line-height creates extra leading space below the baseline
     that makes the text read 2px above centre. */
  line-height: 24px;
}
.tot-insight-text { font-weight: 500; flex: 1 1 auto; min-width: 0; }
.tot-insight-link {
  font-size: 13px; color: #B8943E;
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(184,148,62,0.5);
  flex-shrink: 0; font-weight: 600;
  transition: color 0.18s, text-decoration-color 0.18s;
}
@media (max-width: 600px) {
  .tot-insight { padding: 11px 12px; gap: 10px; }
  .tot-insight-content { flex-direction: column; gap: 4px; align-items: flex-start; }
}

/* Heart button on each "more names you might love" recommendation */
.tot-dna-rec-heart {
  align-self: center; flex-shrink: 0;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--border); background: white; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--muted);
  transition: all 0.15s; font-family: inherit;
}
.tot-dna-rec-heart:hover { color: #B8943E; border-color: #B8943E; background: #FDF6E3; }
.tot-dna-rec-heart.hearted {
  color: #B8943E; border-color: #B8943E; background: #FDF6E3;
}
.tot-dna-rec-heart.hearted:hover { background: white; }

/* Body scroll-lock while the insights modal is open. */
body.tot-modal-open { overflow: hidden; }

/* Name DNA modal content (reuses .share-modal base).
   Padding is moved onto the inner scroll wrapper so the close button
   stays pinned at the top corner of the visible modal — not the top of
   the (potentially scrolled) content. */
.tot-dna-modal {
  /* Wider on desktop so the longer "Insights about your recent searches"
     title fits on one line and the content has more room to breathe. */
  max-width: 560px; padding: 0;
  display: flex; flex-direction: column;
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem); /* dvh accounts for the iOS URL bar */
}
.tot-dna-modal-scroll {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Required for a flex child to actually shrink below its content size
     and produce a scrollbar. Without this it'll grow to fit content. */
  flex: 1 1 auto; min-height: 0;
  /* Symmetric horizontal padding (close button overlaps top-right). */
  padding: 1.75rem 1.5rem 1.5rem;
}
@media (max-width: 600px) {
  /* Dock the modal to the top on mobile via align-self (overrides the
     parent's align-items: center). Flex centering on a tall modal can
     push the top — and therefore the close button — off-screen. */
  .tot-dna-modal {
    align-self: flex-start;
    margin-top: 1rem;
    max-width: none;
    width: calc(100% - 2rem);
  }
}
.tot-dna-title {
  font-family: 'Lora', 'Lora Fallback', serif; font-size: 22px; font-weight: 600;
  margin-bottom: 4px; padding-right: 30px;
}
.tot-dna-sub { font-size: 14px; color: var(--muted); margin-bottom: 1.25rem; }
.tot-dna-sub strong { color: var(--ink); font-weight: 500; }
.tot-dna-traits { display: flex; flex-direction: column; gap: 10px; margin-bottom: 1.25rem; }
.tot-dna-trait {
  display: flex; gap: 12px; background: var(--cream); border: 1px solid var(--border);
  border-radius: 12px; padding: 12px 14px;
  /* Top-align so the icon sits next to the trait title rather than the
     vertical centre of (title + description). */
  align-items: flex-start;
}
/* Fixed-size box for the emoji so different glyphs (📜 vs ✂️ vs 🪞)
   render at a consistent visual size — without this, the scroll/📜 emoji
   reads ~20% larger than the others. */
.tot-dna-trait-emoji {
  flex-shrink: 0;
  width: 26px; height: 26px;
  font-size: 20px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.tot-dna-trait-emoji-svg svg { width: 22px; height: 22px; }
.tot-dna-trait-body { flex: 1; min-width: 0; }
.tot-dna-trait-title { font-weight: 600; font-size: 14px; margin-bottom: 2px; line-height: 26px; }
.tot-dna-trait-text { font-size: 13px; color: var(--muted); line-height: 1.45; }
.tot-dna-empty { font-size: 14px; color: var(--muted); margin: 0 0 1rem; line-height: 1.5; }
.tot-dna-section { border-top: 1px solid var(--border); padding-top: 1rem; }
.tot-dna-heading { font-family: 'Lora', 'Lora Fallback', serif; font-size: 16px; margin-bottom: 10px; }
.tot-dna-recs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tot-dna-rec {
  display: flex; align-items: stretch; gap: 6px;
  background: white; border: 1px solid var(--border); border-radius: 10px;
  padding: 6px 8px 6px 12px;
  transition: border-color 0.15s, background 0.15s;
}
.tot-dna-rec:hover { border-color: #B8943E; background: #FDF6E3; }
.tot-dna-rec-main {
  flex: 1; display: flex; flex-direction: column; align-items: flex-start;
  gap: 1px; padding: 4px 0;
  background: none; border: none; cursor: pointer; font-family: inherit;
  text-align: left;
}
.tot-dna-rec-name { font-family: 'Lora', 'Lora Fallback', serif; font-size: 18px; font-weight: 500; }
.tot-dna-rec-name.girl { color: var(--pink); }
.tot-dna-rec-name.boy { color: var(--blue); }
.tot-dna-rec-name.unisex { color: var(--amber); }
.tot-dna-rec-meta { font-size: 11px; color: var(--muted); }
/* The Noah easter egg aside — italic (via <em>) plus coral tint so it
   reads as a wink alongside the matter-of-fact reason that precedes it. */
.tot-dna-rec-noah { color: var(--coral); font-weight: 500; }
.tot-dna-foot { font-size: 12px; color: var(--muted); margin-top: 10px; text-align: center; }

@media (max-width: 600px) {
  .tot-dna-recs { grid-template-columns: 1fr; }
}


/* Harmony share chooser — small modal asking 'this result or the tool?'
   before opening the site share sheet with the picked URL. */
.harmony-chooser-backdrop {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(20, 20, 20, 0.38);
  opacity: 0; pointer-events: none;
  transition: opacity 0.22s ease;
}
.harmony-chooser-backdrop.open { opacity: 1; pointer-events: auto; }
.harmony-chooser {
  position: fixed; left: 50%; top: 50%; z-index: 10000;
  transform: translate(-50%, -50%) scale(0.96);
  width: calc(100% - 32px); max-width: 420px;
  opacity: 0; pointer-events: none;
  transition: transform 0.24s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.2s ease;
}
.harmony-chooser.open { transform: translate(-50%, -50%) scale(1); opacity: 1; pointer-events: auto; }
.harmony-chooser-content {
  position: relative;
  background: white; border-radius: 18px; padding: 24px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3), 0 0 0 1px rgba(0,0,0,0.06);
}
.harmony-chooser-x {
  position: absolute; top: 10px; right: 12px;
  background: none; border: none;
  font-size: 26px; line-height: 1; color: var(--muted);
  cursor: pointer; padding: 4px 9px; border-radius: 8px;
  transition: background 0.15s, color 0.15s;
}
.harmony-chooser-x:hover { background: rgba(0,0,0,0.06); color: var(--ink); }
.harmony-chooser-title {
  margin: 0 0 14px; font-family: 'Lora', 'Lora Fallback', serif;
  font-size: 19px; font-weight: 600; color: var(--ink);
}
.harmony-chooser-options { display: flex; flex-direction: column; gap: 10px; }
.harmony-chooser-option {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start;
  width: 100%; padding: 14px 16px;
  background: white; border: 1px solid var(--border); border-radius: 12px;
  font-family: inherit; text-align: left; cursor: pointer;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.harmony-chooser-option:hover {
  border-color: var(--ink);
  box-shadow: 0 4px 14px rgba(0,0,0,0.06);
  transform: translateY(-1px);
}
.harmony-chooser-label { font-size: 15px; font-weight: 600; color: var(--ink); }
.harmony-chooser-desc { font-size: 13px; color: var(--muted); line-height: 1.4; }

/* Tool-level share button on the harmony tab — shares the /harmony
   blank tool URL itself, distinct from the result-level share pill.
   Lives in a flex row to the right of the section header. */
.harmony-header-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap;
}
.harmony-header-row .harmony-header { margin-bottom: 0; }
.harmony-tool-share-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  background: white; border: 1px solid var(--border); border-radius: 999px;
  font-family: inherit; font-size: 13px; font-weight: 500;
  color: var(--ink); cursor: pointer; flex-shrink: 0;
  transition: border-color 0.15s, transform 0.15s;
}
.harmony-tool-share-btn:hover { border-color: var(--ink); transform: translateY(-1px); }
.harmony-tool-share-btn svg { flex-shrink: 0; }
/* Inline share-tool button (mobile-only) sits in a row beside the
   "Check harmony" submit, so the share affordance is right next to
   the primary action on a narrow viewport. Hidden on desktop, where
   the share-tool button lives in the section header instead and the
   submit stays at its natural content-width. */
.harmony-submit-row {
  display: flex; align-items: stretch; gap: 10px;
  margin-bottom: 1.25rem;
}
.harmony-tool-share-btn--inline { display: none; }
@media (max-width: 640px) {
  .harmony-header-row .harmony-tool-share-btn:not(.harmony-tool-share-btn--inline) { display: none; }
  .harmony-tool-share-btn--inline { display: inline-flex; flex-shrink: 0; padding: 0 14px; }
  /* On mobile the submit fills the leftover width next to the inline
     share button. On desktop it stays content-width as it was before. */
  .harmony-submit-row .search-btn { flex: 1; }
}

/* Share pill in the harmony result panel — sits to the right of the
   full name, gender-tinted, with a one-shot shimmer on render. */
.harmony-share-pill {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border: 0; border-radius: 999px;
  background: var(--pill-color, var(--amber)); color: white;
  font-family: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; flex-shrink: 0;
  transition: filter 0.15s, transform 0.15s, box-shadow 0.15s;
}
.harmony-share-pill[data-gender="g"] { --pill-color: var(--pink); }
.harmony-share-pill[data-gender="b"] { --pill-color: var(--blue); }
.harmony-share-pill[data-gender="u"] { --pill-color: var(--amber); }
.harmony-share-pill:hover {
  filter: brightness(0.92);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  transform: translateY(-1px);
}
.harmony-share-pill::after {
  content: '';
  position: absolute; top: 0; bottom: 0; left: -50%;
  width: 50%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  pointer-events: none;
  animation: harmonyPillShimmer 1.4s ease 0.5s 1;
}
@keyframes harmonyPillShimmer {
  0%   { left: -50%; }
  100% { left: 110%; }
}
@media (prefers-reduced-motion: reduce) {
  .harmony-share-pill::after { animation: none; }
}

/* Harmony result card — tints to a light wash of the first name's
   gender colour, matching the standalone /harmony share page. The class
   is added by calcMatch() in app.js based on _harmonyCtx.gender. */
.harmony-result-card { background: var(--cream); transition: background-color 0.4s ease; }
.harmony-result-card.gender-g { background: var(--pink-light); }
.harmony-result-card.gender-b { background: var(--blue-light); }
.harmony-result-card.gender-u { background: var(--amber-light); }

/* Harmony notes list — used for the "Things to consider" / "Just so you
   know" bullets under a harmony result. Custom markers let us style
   concerns and observations differently without spelling it out in
   words: amber dot for concerns (asks for attention), softer muted dot
   for observations (just FYI). The standalone /harmony share page uses
   the same classes so both surfaces stay in sync. */
.harmony-notes-list { list-style: none; padding-left: 0; margin: 0; }
.harmony-note {
  position: relative;
  padding: 4px 0 4px 18px;
  line-height: 1.5;
}
.harmony-note::before {
  content: '';
  position: absolute;
  left: 4px; top: 12px;
  width: 6px; height: 6px;
  border-radius: 50%;
}
.harmony-note--concern,
.harmony-note--observation { color: var(--muted); }
.harmony-note--concern::before,
.harmony-note--observation::before { background: #B6B4AB; }

/* ── Harmony score celebration ─────────────────────────────────────────
   Fired by triggerHarmonyCelebration() in app.js when a passing harmony
   result lands (score ≥ 80, no bad initials). Mirrors the keyframes used
   on the standalone /harmony share page so both surfaces feel identical.
   The matching JS-driven confetti burst is appended as a canvas inside
   .harmony-ring-wrap. */
/* Harmony result layout — ring on the left, breakdown grid on the
   right. Defined here so the mobile media query can shrink the ring
   and tighten the gap without fighting inline styles in app.js. */
.harmony-ring-row {
  display: flex; align-items: center; gap: 2rem;
}
.harmony-ring-wrap {
  position: relative; width: 120px; height: 120px; flex-shrink: 0;
}
.harmony-ring-wrap svg {
  width: 100%; height: 100%; display: block; transform: rotate(-90deg);
}
.harmony-ring-num {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-size: 30px; font-weight: 600; color: var(--ink); z-index: 1;
}
.harmony-ring-grid { flex: 1; min-width: 0; }
@media (max-width: 540px) {
  /* Mobile: shrink the ring 10% and tighten the gap so the breakdown
     rows on the right have more horizontal room. The card padding +
     375px viewport leaves the right column quite squeezed at the
     desktop sizing. */
  .harmony-ring-row { gap: 1rem; }
  .harmony-ring-wrap { width: 108px; height: 108px; }
  .harmony-ring-num { font-size: 27px; }
}
.harmony-ring-wrap::after {
  content: ''; position: absolute; inset: -3px;
  border: 2px solid #0F6E56; border-radius: 50%;
  pointer-events: none; opacity: 0;
}
.harmony-ring-wrap.celebrate { animation: harmony-ring-pulse 700ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.harmony-ring-wrap.celebrate::after { animation: harmony-ring-ripple 1000ms cubic-bezier(0.15, 0.6, 0.3, 1); }
.harmony-ring-num.pop { animation: harmony-num-pop 520ms ease-out; }
@keyframes harmony-ring-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.08); }
  65%  { transform: scale(0.985); }
  100% { transform: scale(1); }
}
@keyframes harmony-ring-ripple {
  0%   { transform: scale(1);   opacity: 0.7; }
  100% { transform: scale(1.6); opacity: 0; }
}
@keyframes harmony-num-pop {
  0%   { transform: translate(-50%, -50%) scale(1); }
  40%  { transform: translate(-50%, -50%) scale(1.18); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .harmony-ring-wrap.celebrate,
  .harmony-ring-wrap.celebrate::after,
  .harmony-ring-num.pop { animation: none; }
}

/* ── Mobile name-profile stat boxes ─────────────────────────────────────
   The three boxes (rank / births / class-clash) at narrow widths. The
   default `.stat-row { grid-template-columns: repeat(3, 1fr); ... }`
   rule sits below the earlier mobile-block @media — same specificity,
   later wins — so this block lives at the end of the file to ensure
   the mobile overrides actually take effect. minmax(0, 1fr) keeps the
   columns equal-width even when the middle label "Registered 2024"
   would otherwise push its column wider. The jump/info icon goes
   absolute so it doesn't crowd the third label or force extra wrap. */
br.mobile-only-break { display: none; }
@media (max-width: 640px) {
  .stat-row { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 6px !important; }
  .stat-box { padding: 10px 6px; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 78px; position: relative; }
  .stat-box .stat-num { font-size: 19px; }
  .stat-box .stat-lbl { font-size: 10px; letter-spacing: 0.02em; line-height: 1.25; }
  .stat-box .stat-info-icon { display: none !important; }
  br.mobile-only-break { display: inline; }
}

/* ── Historic popularity chart (trend-chart.js) ─────────────────────
   Mounted on US name profiles. Single card containing: header,
   pill-style controls, chart with HTML axis labels (so text doesn't
   warp with the SVG's stretchy viewBox), legend, divider, and the
   absorbed Last-3-years bars. */
.trend-chart-mount { margin: 1.25rem 0 1rem; }
.tc-card {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 20px 20px;
  background: white;
}
.tc-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; margin-bottom: 24px;
}
.tc-head-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 0; }
.tc-title {
  font-size: 13px; font-weight: 500; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  line-height: 1.2;
}
.tc-source { font-size: 11px; color: var(--muted); white-space: nowrap; line-height: 1.2; }

.tc-controls {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center; justify-content: flex-end;
  position: relative; flex-shrink: 0;
}
/* Pills: fixed height + flex centring so the icon, label, input, and
   submit button all share the same baseline regardless of glyph metrics.
   The 1px padding-top compensates for DM Sans's cap-height being
   slightly below the geometric centre of the line box, otherwise
   text appears optically high on mobile renderings. */
.tc-pill {
  display: inline-flex; align-items: center; gap: 5px;
  height: 30px; padding: 1px 13px 0; border-radius: 50px;
  background: var(--cream); border: 1px solid var(--border);
  color: var(--muted); font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; transition: color 0.15s, border-color 0.15s, background 0.15s;
  line-height: 1; white-space: nowrap; box-sizing: border-box;
}
/* Soft hover: just darken the text, no harsh background/border swap. */
.tc-pill:hover { color: var(--ink); }
/* Static name pill (home name in the controls row). No hover, no
   click handler — JS sets the gender-tinted background/colour/border
   inline so it tracks the home name. */
.tc-pill-static { cursor: default; }
.tc-pill-static:hover { color: inherit; }
/* Active state for the comparison pill — light teal, on-brand. */
.tc-pill-on, .tc-compare-active {
  background: var(--teal-light); color: var(--teal); border-color: var(--teal);
}
.tc-pill-on:hover, .tc-compare-active:hover {
  background: var(--teal-light); color: var(--teal); border-color: var(--teal);
  filter: brightness(0.97);
}
.tc-pill-icon { font-size: 14px; line-height: 1; font-weight: 500; display: inline-block; }
.tc-pill-x {
  font-size: 16px; line-height: 1; margin-left: 2px; opacity: 0.85;
}

/* `display: inline-flex` on the controls overrides the [hidden]
   attribute's default display:none — restore it explicitly, and use
   data-mode on the wrapper to drive which child shows. */
.tc-pill[hidden],
.tc-compare-input-wrap[hidden],
.tc-compare-state[data-mode="idle"] .tc-compare-input-wrap,
.tc-compare-state[data-mode="idle"] .tc-compare-active,
.tc-compare-state[data-mode="editing"] .tc-compare-trigger,
.tc-compare-state[data-mode="editing"] .tc-compare-active,
.tc-compare-state[data-mode="active"] .tc-compare-trigger,
.tc-compare-state[data-mode="active"] .tc-compare-input-wrap { display: none; }

.tc-compare-state { display: inline-flex; align-items: center; }
/* Pin the trigger and the editing input to the same width — keeps
   the controls row from reflowing when the user clicks the trigger
   to start typing. Width is set just a touch wider than the
   trigger's natural content ("+ Compare another name") so there's
   a small breathing margin around the text without leaving a chunk
   of dead whitespace. */
.tc-compare-trigger { width: 186px; max-width: 100%; }

/* Compare input — same affordance as .harmony-inputs (pill, cream
   fill, soft border, ✕ absolutely positioned right) but sized to
   match the .tc-pill so clicking the trigger doesn't change row
   height. */
.tc-compare-input-wrap {
  position: relative;
  display: inline-flex; align-items: center;
  width: 186px; max-width: 100%; height: 30px;
}
.tc-compare-input {
  width: 100%; height: 30px; padding: 0 36px 0 16px;
  border: 1px solid var(--border); border-radius: 50px;
  background: var(--cream);
  font-family: 'DM Sans', 'DM Sans Fallback', sans-serif;
  font-size: 13px; color: var(--ink); line-height: 1;
  outline: none; transition: border-color 0.15s;
  box-sizing: border-box;
}
/* When the input is empty the clear (×) button is hidden, so the
   36px right padding becomes dead space — free it up so the
   placeholder "Type a name to compare…" can fit at the trimmed
   186px width. Reverts to 36px once the user starts typing. */
.tc-compare-input:placeholder-shown { padding-right: 16px; }
.tc-compare-input::placeholder { color: var(--muted); }
.tc-compare-clear {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 22px; height: 22px;
  display: none; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 50%;
  background: rgba(44, 44, 42, 0.08); color: var(--muted);
  font-size: 14px; line-height: 1; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
/* Match harmony's "appears as soon as you type" rule. */
.tc-compare-input:not(:placeholder-shown) ~ .tc-compare-clear {
  display: inline-flex;
}
.tc-compare-clear:hover { background: rgba(44, 44, 42, 0.18); color: var(--ink); }

/* Spellings pill (active state) — tint matches the dominant-gender
   colour of the focused name. JS sets --tc-spell-bg/-color/-border
   when the trend data loads. Falls back to blue-light if unset. */
.tc-spellings-btn[aria-pressed="true"] {
  background: var(--tc-spell-bg, var(--blue-light));
  color: var(--tc-spell-color, var(--blue));
  border-color: var(--tc-spell-border, var(--blue));
}
.tc-spellings-btn[aria-pressed="true"]:hover {
  filter: brightness(0.97);
}
.tc-info-icon {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; margin-left: 4px;
  border-radius: 50%;
  background: transparent; color: currentColor;
  border: 1px solid currentColor;
  opacity: 0.55;
  font-size: 9px; font-weight: 700; line-height: 1;
  cursor: help; user-select: none;
  transition: opacity 0.15s;
}
.tc-info-icon:hover { opacity: 1; }
.tc-info-glyph { font-style: italic; font-family: serif; line-height: 1; }
.tc-info-popover {
  position: absolute; top: calc(100% + 8px); left: 50%;
  transform: translateX(-50%);
  background: white; color: var(--ink);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.08);
  font-size: 12px; font-weight: 400; line-height: 1.5;
  padding: 8px 12px; width: max-content; max-width: 480px;
  z-index: 20; white-space: nowrap; text-align: left;
  text-transform: none; letter-spacing: 0;
}
.tc-info-popover[hidden] { display: none; }
.tc-info-popover .tc-pop-row { white-space: nowrap; }
.tc-info-popover .tc-pop-row + .tc-pop-row { margin-top: 4px; }

/* Chart area: 30px label column + flex plot column. Top margin gives
   the chart breathing room from the controls above. The small
   negative left margin lines up the leading edge of the largest
   y-axis label (e.g. "80k") with the header above. */
.tc-chart-area {
  display: grid;
  grid-template-columns: 30px 1fr;
  grid-template-rows: 1fr 22px;
  column-gap: 4px;
  margin: 20px 0 0 -8px;
}
.tc-y-col { position: relative; height: 162px; grid-column: 1; grid-row: 1; }
/* Y-labels right-aligned so their right edge sits flush against the
   axis line — no big visual gap between the labels and the chart. */
.tc-y-label {
  position: absolute; right: 0;
  transform: translateY(-50%);
  font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.tc-y-label:last-child { transform: translateY(-100%); }   /* baseline tick (0) */
.tc-y-label:first-child { transform: translateY(0); }       /* topmost tick   */
.tc-plot { position: relative; grid-column: 2; grid-row: 1; }
/* Block text selection across the chart so dragging a finger across
   it on mobile only moves the hover guide — without `user-select:none`
   the scrub gesture grabs the SVG + axis labels and lights up an
   ugly blue highlight. `touch-action: pan-y` keeps vertical page
   scrolling responsive while letting our touchmove handler claim
   horizontal swipes for the guide. `-webkit-touch-callout: none`
   suppresses the iOS long-press menu on the chart area. */
.tc-chart-area, .tc-tooltip {
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
.tc-svg { display: block; width: 100%; height: 162px; overflow: visible; touch-action: pan-y; }
/* Marker overlay — "moments" (birth/release-year dots for cultural
   figures associated with the name). Drawn as absolutely-positioned
   HTML so the dots stay round under the SVG's non-uniform aspect-ratio
   stretch. Pointer events disabled so the chart's hover handler still
   owns the cursor. */
.tc-markers { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.tc-marker-moment {
  position: absolute;
  font-size: 18px; line-height: 1;
  transform: translate(-50%, -50%);
  /* Soft halo so the star reads cleanly against the chart fill or
     baseline axis. */
  text-shadow:
    0 0 2px var(--bg, #f7f3ec),
    0 0 2px var(--bg, #f7f3ec),
    0 0 3px var(--bg, #f7f3ec);
  /* `currentColor` makes inline `style="color: …"` drive the glyph. */
  color: currentColor;
}
/* Fly-in is on a one-shot class so hover-toggling .tc-marker-active
   doesn't re-trigger the animation. JS removes the class after the
   staggered run completes. From-position is the toggle button's
   centre (offset computed in JS), so each star sails straight from
   the button to its spot on the axis. */
.tc-marker-moment.tc-marker-flyin {
  animation: tc-marker-flyin 0.85s cubic-bezier(0.22, 1, 0.36, 1) var(--marker-delay, 0ms) backwards;
}
@keyframes tc-marker-flyin {
  /* Direct diagonal: starts at the button's centre, lands at target.
     No intermediate keyframe — the L-shaped two-stage path read as
     jerky "drop then scroll". A clean ease-out curve carries the
     whole motion. */
  from {
    transform:
      translate(-50%, -50%)
      translate(var(--from-x, -120px), var(--from-y, -50px))
      scale(0.4);
    opacity: 0;
  }
  to {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
}
/* z-index lift on snap so the active marker sits above the others.
   No scale change — that caused a "dance" effect when the cursor
   moved between adjacent markers. The dashed guide + tooltip are
   the canonical signal that a snap has happened. */
.tc-marker-moment.tc-marker-active {
  z-index: 3;
}
@media (prefers-reduced-motion: reduce) {
  .tc-marker-moment.tc-marker-flyin { animation: none; }
}
/* Moment line in the chart tooltip — sits below the count rows. */
.tc-tt-moment {
  margin-top: 5px; padding-top: 5px;
  border-top: 1px solid var(--border, rgba(44,44,42,0.12));
  font-size: 11.5px; line-height: 1.35;
  color: var(--ink);
  white-space: normal;
  max-width: 280px;
}
.tc-tt-moment-glyph {
  color: var(--amber, #C8931A);
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  position: relative; top: 1px;
  /* The ✦ at 14px renders ~11px wide. Without these the flex item's
     auto min-width grows the box to fit the glyph, which shifts the
     box centre ~1.5px right of the dot above. Force the box to
     exactly 8px (matching .tc-tt-dot's column) and let the glyph
     overflow visibly, then center it inside the box so its visual
     centre sits precisely under the dot's centre above. */
  width: 8px; min-width: 0; box-sizing: border-box;
  overflow: visible;
  text-align: center;
}
/* Cultural-reference line: ✦ + label + verb + desc as one sentence.
   Two-column flex so the icon sits in an 8px column with an 8px gap,
   matching the .tc-tt-row's dot (8px) + gap (8px) above. Result: text
   starts at the same x-offset as the names in the count rows above
   (e.g. "Britney 314"), so the tooltip reads as a vertically aligned
   list rather than two slightly-offset blocks. */
.tc-tt-moment-ref {
  display: flex; align-items: flex-start; gap: 8px;
  line-height: 1.4;
}
.tc-tt-moment-glyph {
  flex: 0 0 8px;
  font-weight: 600;
}
.tc-tt-moment-textblock { flex: 1; min-width: 0; }
.tc-tt-moment-verb,
.tc-tt-moment-context {
  color: var(--ink);
}
/* Impact line — looks like an insight badge rather than continuation
   prose. Coloured background, indented to sit under the cultural line,
   with the directional arrow as a leading icon. Wraps to multiple
   lines when the text is long; padding adjusts so it doesn't blow up
   the tooltip width. */
.tc-tt-moment-impact {
  display: flex; align-items: flex-start; gap: 5px;
  margin-top: 5px; margin-left: 16px; margin-right: 0;
  padding: 3px 8px; border-radius: 8px;
  font-size: 10.5px; font-weight: 600; line-height: 1.35;
}
.tc-tt-moment-impact-arrow {
  font-size: 13px; line-height: 1.2; flex: 0 0 auto;
}
.tc-tt-moment-impact-text { flex: 1 1 auto; }
.tc-tt-moment-impact-surge {
  background: rgba(46,125,50,0.10);
  color: #1B5E20;
}
.tc-tt-moment-impact-dip {
  background: rgba(198,40,40,0.10);
  color: #B71C1C;
}
/* Shared impact pill — sits at the bottom of the year's moment block
   when multiple moments at the same year share a delta direction (we
   can't honestly attribute the rise/fall to a specific one). Thin
   top border separates it from the moments above. */
.tc-tt-shared-impact {
  margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--border, rgba(44,44,42,0.12));
}
.tc-tt-shared-impact .tc-tt-moment-impact { margin-left: 0; margin-top: 0; }
/* Moments toggle pill — off-state matches the sibling controls
   (Compare, Spellings) so the row reads as one cohesive group; the
   amber `✦` glyph signals the brand colour for "insight". On-state
   tints the whole pill amber so it reads as "selected" without
   shouting like a solid filled button. */
.tc-moments-glyph { color: var(--amber, #C8931A); font-size: 12px; line-height: 1; }
.tc-moments-btn.tc-moments-on {
  /* Matches the active-state fill of .tc-spellings-btn so the two
     toggles read as a single visual group when both are on amber —
     light amber background + amber text + amber border. */
  background: var(--amber-light, #FCF5E5);
  color: var(--amber, #C8931A);
  border-color: var(--amber, #C8931A);
}
.tc-moments-btn.tc-moments-on:hover {
  filter: brightness(0.97);
}
.tc-x-spacer { grid-column: 1; grid-row: 2; }
.tc-x-row { position: relative; grid-column: 2; grid-row: 2; height: 22px; }
.tc-x-label {
  position: absolute; top: 6px;
  transform: translateX(-50%);
  font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
  line-height: 1;
}

.tc-tooltip {
  position: absolute; pointer-events: none;
  background: white; color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 12px; line-height: 1.4;
  padding: 8px 11px;
  max-width: 340px; z-index: 5;
  box-shadow: 0 6px 18px rgba(0,0,0,0.08);
  white-space: nowrap;
}
@media (max-width: 600px) {
  /* Tighter ceiling on mobile to leave breathing room next to the
     guide line; the wrap is acceptable when there's no horizontal
     real estate left. */
  .tc-tooltip { max-width: 240px; white-space: normal; }
}
.tc-tt-year { font-weight: 600; margin-bottom: 4px; font-size: 12px; }
.tc-tt-row {
  display: flex; align-items: center; gap: 8px;
  font-variant-numeric: tabular-nums;
}
.tc-tt-row + .tc-tt-row { margin-top: 2px; }
.tc-tt-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
}
.tc-tt-name { color: var(--muted); flex: 1; min-width: 0; }
.tc-tt-val { font-weight: 600; color: var(--ink); }
.tc-status {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-size: 13px; color: var(--muted); text-align: center;
  max-width: 80%; pointer-events: none; line-height: 1.4;
}
.tc-status:empty { display: none; }

/* Skeleton placeholder while the chart fetches its data. A subtle
   horizontal shimmer in the same plot area, no "Loading…" text. */
.tc-skeleton {
  position: absolute; inset: 0;
  pointer-events: none;
}
.tc-skeleton[hidden] { display: none; }
.tc-sk-fill {
  height: 100%; border-radius: 6px;
  background: linear-gradient(90deg,
    rgba(44,44,42,0.04) 0%,
    rgba(44,44,42,0.10) 50%,
    rgba(44,44,42,0.04) 100%);
  background-size: 200% 100%;
  animation: tc-shimmer 1.6s ease-in-out infinite;
}
@keyframes tc-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* No persistent toast: errors are signalled by shaking the input and
   briefly turning its border red + showing the error text in the
   placeholder slot. Avoids any layout shift or stacking-context
   battles with the chart below. */
.tc-toast { display: none; }
.tc-controls { position: relative; }

@keyframes tc-input-shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-4px); }
  40%, 80% { transform: translateX(4px); }
}
.tc-compare-input-wrap.tc-shake {
  animation: tc-input-shake 0.35s ease;
}
.tc-compare-input.tc-input-error {
  border-color: var(--muted);
  background: var(--cream);
}
.tc-compare-input.tc-input-error::placeholder {
  color: var(--muted);
  font-style: italic;
}

/* Legend retired in favour of the colored name badges in the controls
   row above the chart — the per-line tooltip provides the breakdown. */
.tc-legend { display: none; }
.tc-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.tc-legend-dot {
  display: inline-block; width: 12px; height: 2px; border-radius: 2px;
  flex-shrink: 0;
}
/* Insights legend — appears under the chart when the moments toggle
   is active AND the visible markers span multiple gender/category
   colours. Explains the ✦ pink/blue/amber convention without an
   always-on caption.
   Padding-left matches the chart's left axis offset (.tc-chart-area
   has 30px y-col + 4px gap with -8px margin = 26px to plot edge),
   so legend items sit aligned with the chart's first data column.
   Slightly larger font and a touch more breathing room above. */
.tc-insights-legend {
  display: flex; flex-wrap: wrap; gap: 8px 16px;
  margin-top: 12px; padding-left: 26px; padding-bottom: 4px;
  font-size: 12px; color: var(--muted);
}
.tc-insights-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.tc-insights-legend-glyph { font-size: 14px; line-height: 1; font-weight: 600; }

.tc-divider {
  height: 1px; background: var(--border);
  margin: 16px 0 14px;
}
/* No-legend tightening: when the insights legend is empty (single-
   colour or insights off) there's no content filling the space between
   the chart's x-axis row and the divider, so the default 16px gap
   reads as too much air. Halve it. */
.tc-card.tc-no-legend .tc-divider { margin-top: 4px; }
/* Minor-gender insight: shown when the SSA/ONS data has a non-trivial
   minority count for the home name but the line is too small to
   plot (suppressed below 5% of the major line). Reads as a quiet
   footer to the chart, not as a header. */
.tc-minor-note[hidden] { display: none; }
.tc-minor-note {
  margin-top: 12px;
  font-size: 12.5px; line-height: 1.4;
  color: var(--muted);
  display: flex; align-items: center; gap: 8px;
}
.tc-minor-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: rgba(44,44,42,0.35);
  flex-shrink: 0;
}
.tc-minor-pct { color: rgba(44,44,42,0.55); }
.tc-recent { padding: 0; }
.tc-recent-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; margin-bottom: 14px; flex-wrap: wrap;
}
.tc-recent-label {
  font-size: 13px; font-weight: 500; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.tc-recent-switcher { position: relative; display: inline-flex; }
.tc-switcher-trigger {
  display: inline-flex; align-items: center; gap: 4px;
  background: transparent;
  border: 1px solid var(--tc-sw-color, var(--border));
  color: var(--tc-sw-color, var(--ink));
  border-radius: 50px; padding: 3px 10px;
  font: inherit; font-size: 12px; font-weight: 500;
  cursor: pointer; line-height: 1;
}
.tc-switcher-arrow { font-size: 10px; line-height: 1; }
.tc-switcher-menu {
  position: absolute; right: 0; top: calc(100% + 4px);
  background: white; border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 6px 18px rgba(0,0,0,0.08);
  padding: 4px; min-width: 120px; z-index: 30;
  display: flex; flex-direction: column;
}
.tc-switcher-menu[hidden] { display: none; }
.tc-switcher-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 10px; border-radius: 6px;
  background: transparent; border: 0;
  font: inherit; font-size: 13px; color: var(--ink);
  cursor: pointer; text-align: left;
}
.tc-switcher-item:hover { background: var(--cream); }
.tc-switcher-item.is-active { color: var(--tc-sw-color, var(--ink)); font-weight: 500; }
.tc-switcher-check { font-size: 11px; opacity: 0.8; }
.tc-bar-row {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 9px;
}
.tc-bar-row:last-child { margin-bottom: 0; }
.tc-bar-yr { width: 36px; flex-shrink: 0; font-size: 12px; font-variant-numeric: tabular-nums; }
.tc-bar-track { flex: 1; height: 7px; background: #EEE; border-radius: 99px; overflow: hidden; }
.tc-bar-fill { height: 100%; border-radius: 99px; }
.tc-bar-val { width: 56px; flex-shrink: 0; text-align: right; font-size: 12px; font-variant-numeric: tabular-nums; }
.tc-recent-summary {
  margin-top: 14px;
  font-size: 12.5px; color: var(--muted); line-height: 1.4;
}

/* Stack the controls below the header at intermediate widths too —
   with four pills (home, compare, spellings, insights) the row no
   longer fits next to "Popularity over time" in narrower embeds.
   600px tightens further with mobile-only adjustments below. */
@media (max-width: 820px) {
  .tc-head { flex-direction: column; gap: 12px; margin-bottom: 18px; }
  .tc-controls { width: 100%; justify-content: flex-start; }
}
@media (max-width: 600px) {
  .tc-card { padding: 14px 14px 16px; }
  .tc-y-col, .tc-svg { height: 150px; }
  .tc-source { display: none; }
  /* DM Sans renders slightly higher on mobile than desktop —
     bump padding-top so the name reads optically centred. */
  .tc-pill { padding: 2px 13px 0; }
  /* Spellings popover: wrap onto multiple lines and anchor the right
     edge to the icon (instead of centring) so it doesn't overflow
     past the right side of a narrow viewport. */
  .tc-info-popover {
    white-space: normal; max-width: calc(100vw - 40px);
    right: 0; left: auto; transform: none;
  }
  .tc-info-popover .tc-pop-row { white-space: normal; }
  /* Keep the input close to the trigger pill's width on mobile so
     clicking "Compare another name" doesn't expand the control to
     the full row width. 200px fits "Type a name to compare" with a
     breathing margin and still respects the 100% cap on very narrow
     screens. */
  .tc-compare-input-wrap { width: 200px; max-width: 100%; }
  .tc-compare-input { width: 100%; min-width: 0; }
  .tc-compare-state { flex: 0 0 auto; }
  .tc-legend { padding-left: 0; gap: 10px 14px; }
  /* Tighter gap + slightly smaller pill text for true mobile widths. */
  .tc-head { margin-bottom: 18px; }
  .tc-controls { gap: 6px; }
  .tc-spellings-btn .tc-spellings-label,
  .tc-compare-trigger > span:not(.tc-pill-icon) { font-size: 12.5px; }
}
