/* ════════════════════════════════════════════════════════════════════════
   JomPlan Public Website Phase (2026-09-21) — shared styles for the new
   public-agent pages: the Agents directory (agents.html), the individual
   Agent page shell (agent/index.html), and the JomPlan-specific additions
   to the homepage (index.html).

   Deliberately a NEW, additive file, loaded ALONGSIDE the existing
   assets/css/design-system.css — every color, radius and shadow below is
   read from that file's own custom properties (--navy-*, --gold-*,
   --gray-*, --r-*, --sh-*), so this stays visually consistent with the
   rest of the site without editing (or risking) that shared stylesheet.
   Nothing in this file is referenced by any existing page.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Agent card (used on the homepage's featured strip and the directory) ── */
.jp-agent-card {
  background: var(--white);
  border: 1.5px solid var(--gray-100);
  border-radius: var(--r-xl);
  padding: 28px;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.jp-agent-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--sh-lg);
  border-color: var(--navy-200);
}
.jp-agent-card-top { display: flex; align-items: center; gap: 16px; }
.jp-agent-photo {
  width: 64px; height: 64px; border-radius: 50%;
  object-fit: cover; background: var(--navy-100); flex-shrink: 0;
  border: 2px solid var(--gray-100);
}
.jp-agent-initials {
  width: 64px; height: 64px; border-radius: 50%;
  background: linear-gradient(135deg, var(--navy-700), var(--navy-500));
  color: var(--white); display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.15rem; flex-shrink: 0; letter-spacing: -0.02em;
}
.jp-agent-name { font-size: 1.05rem; font-weight: 800; color: var(--navy-800); line-height: 1.3; }
.jp-agent-role { font-size: 0.8rem; color: var(--gray-500); font-weight: 600; margin-top: 2px; }
.jp-agent-location {
  font-size: 0.8rem; color: var(--navy-500); font-weight: 600;
  display: flex; align-items: center; gap: 6px;
}
.jp-agent-location svg { flex-shrink: 0; }
.jp-agent-cta {
  margin-top: auto; font-size: 0.82rem; font-weight: 700; color: var(--navy-500);
  display: inline-flex; align-items: center; gap: 6px;
}
.jp-agent-card:hover .jp-agent-cta { color: var(--gold-500); }

/* ── Directory page layout ── */
.jp-directory-hero {
  background: var(--navy-900); padding: clamp(56px, 8vw, 88px) 0 clamp(40px, 5vw, 56px);
  text-align: center;
}
.jp-directory-hero h1 { color: var(--white); font-size: clamp(2rem, 1.5rem + 2vw, 2.9rem); font-weight: 800; letter-spacing: -0.03em; margin-bottom: 14px; }
.jp-directory-hero p { color: rgba(255,255,255,0.6); font-size: 1rem; max-width: 560px; margin: 0 auto; line-height: 1.7; }

.jp-directory-body { padding: clamp(40px, 5vw, 64px) 0 clamp(64px, 8vw, 96px); }
.jp-directory-layout { display: grid; grid-template-columns: 1fr; gap: 40px; }
@media (min-width: 960px) {
  .jp-directory-layout { grid-template-columns: 0.9fr 1.1fr; align-items: start; gap: 48px; }
}

.jp-map-panel {
  background: var(--gray-50); border: 1.5px solid var(--gray-200); border-radius: var(--r-xl);
  padding: 20px; position: sticky; top: 24px;
}
.jp-map-title { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gray-500); margin-bottom: 14px; }
.jp-map-svg-wrap { position: relative; width: 100%; }
.jp-map-svg-wrap svg { width: 100%; height: auto; display: block; }
/* JOMPLAN PREMIUM MAP — PHASE 2 (2026-09-22): premium coverage-map treatment
   for the Agent Directory map (/agents.html, /zh/agents.html). Replaces the
   old always-visible oversized state circles with: a data-driven subtle
   gold tint on the real state geometry (Phase 1's geography/boundary
   layers, still populated once and never replaced — only classList is
   toggled here), small refined advisor markers shown ONLY for states with
   a live agent, and elegant state labels. See jomplan-map-data.js and
   JOMPLAN_PREMIUM_MAP_PHASE1_REPORT.md for the underlying geometry source. */
.jp-map-geography path { fill: var(--gray-100); stroke: none; transition: fill 0.25s ease; }
.jp-map-geography path.has-agents { fill: rgba(201,168,76,0.14); }
.jp-map-geography path.has-agents:hover { fill: rgba(201,168,76,0.22); }
.jp-map-geography path.active { fill: rgba(201,168,76,0.30); }
.jp-map-boundaries path { fill: none; stroke: var(--gray-300); stroke-width: 1; transition: stroke 0.25s ease, stroke-width 0.25s ease; }
.jp-map-boundaries path.has-agents { stroke: rgba(201,168,76,0.55); }
.jp-map-boundaries path.active { stroke: var(--gold-500); stroke-width: 1.5; }

/* State labels — small, muted, non-dominant. A handful of states in the
   crowded central cluster (Selangor/KL/Putrajaya) get a thin leader line
   from a hand-placed label position back to their real marker point,
   instead of stacking labels on top of each other. Text content always
   comes from JomPlanMapData (nameEn/nameZh) — this file only supplies the
   generic look. */
.jp-map-label { font-size: 7.5px; font-weight: 600; fill: var(--gray-500); text-anchor: middle; pointer-events: none; }
.jp-map-label.has-agents { fill: var(--navy-700); font-weight: 700; }
.jp-map-label.active { fill: var(--navy-900); }
.jp-map-leader { stroke: var(--gray-300); stroke-width: 0.6; pointer-events: none; }
.jp-map-leader.has-agents { stroke: rgba(201,168,76,0.55); }
.jp-map-leader.active { stroke: var(--gold-500); }

/* Advisor markers — shown only for states with a live agent; no dot at all
   for empty states, so the map never implies coverage that doesn't exist.
   A larger transparent hit-area keeps the click/tap target comfortable
   without the visible marker itself needing to be a giant bubble. */
.jp-map-marker { cursor: pointer; }
.jp-map-marker-hit { fill: transparent; }
.jp-map-marker-halo { fill: none; stroke: rgba(201,168,76,0.35); stroke-width: 1; transition: stroke 0.2s ease, stroke-width 0.2s ease; }
.jp-map-marker-dot { fill: var(--gold-400); filter: drop-shadow(0 0 3px rgba(201,168,76,0.5)); transition: fill 0.2s ease; }
.jp-map-marker-count { fill: var(--navy-900); font-size: 8.5px; font-weight: 800; text-anchor: middle; dominant-baseline: central; pointer-events: none; }
.jp-map-marker:hover .jp-map-marker-dot,
.jp-map-marker:focus-visible .jp-map-marker-dot { fill: var(--gold-300); }
.jp-map-marker:hover .jp-map-marker-halo { stroke: var(--gold-500); stroke-width: 1.5; }
.jp-map-marker.active .jp-map-marker-halo { stroke: var(--gold-600); stroke-width: 2; }
.jp-map-marker:focus-visible { outline: none; }
.jp-map-marker:focus-visible .jp-map-marker-halo { stroke: var(--navy-700); stroke-width: 2; }

.jp-map-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; font-size: 0.72rem; color: var(--gray-500); margin-top: 14px; }
.jp-map-legend-item { display: flex; align-items: center; gap: 6px; }
.jp-map-legend-dot-gold { width: 9px; height: 9px; border-radius: 50%; background: var(--gold-400); flex-shrink: 0; box-shadow: 0 0 0 1px rgba(201,168,76,0.3); }
.jp-map-legend-dot-outline { width: 9px; height: 9px; border-radius: 50%; background: var(--gray-100); border: 1px solid var(--gray-300); flex-shrink: 0; }
.jp-map-empty { font-size: 0.82rem; color: var(--gray-400); text-align: center; padding: 32px 12px; }

.jp-directory-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.jp-filter-chip {
  border: 1.5px solid var(--gray-200); background: var(--white); color: var(--gray-600);
  font-size: 0.78rem; font-weight: 600; padding: 7px 16px; border-radius: var(--r-full);
  cursor: pointer; transition: all 0.15s ease;
}
.jp-filter-chip:hover { border-color: var(--navy-300); }
.jp-filter-chip.active { background: var(--navy-700); border-color: var(--navy-700); color: var(--white); }

.jp-agent-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 20px; }
.jp-directory-count { font-size: 0.85rem; color: var(--gray-500); margin-bottom: 16px; }
.jp-directory-state { text-align: center; padding: 64px 16px; color: var(--gray-400); font-size: 0.9rem; }

/* ── Individual agent page ── */
/* JOMPLAN AGENT PROFILE — PHASE 1 (2026-09-23): premium micro-site visual
   pass. Every selector below is scoped with the .jp-agent-page-* / .jp-agent-
   bio / .jp-agent-details* / .jp-agent-specialties* / .jp-agent-services /
   .jp-contact-* prefixes already used by the individual profile page only --
   nothing under "Agent card" / "Directory page layout" / "Homepage" above is
   touched, so the Agents Directory, homepage featured strip and coverage
   section keep their exact current appearance. See
   JOMPLAN_AGENT_PROFILE_PHASE1_IMPLEMENTATION_REPORT.md for the full
   before/after summary. */
/* JOMPLAN AGENT PROFILE — PHASE 1B (2026-09-23), OPTION A — OVERLAPPING
   PORTRAIT. Replaces Phase 1's square/circular-feeling left-aligned photo
   with a rectangular/vertical portrait pinned to the right of the hero on
   tablet+ that physically overlaps the navy/white boundary. The overlap is
   pure CSS: the photo stays in normal grid flow (so it still determines
   the hero's height, per the brief's §9) and is then visually shifted
   down with `transform: translateY(...)`, which does not affect layout,
   so the hero's own box is unaffected and the shifted pixels simply paint
   over the top of the content section below. `.jp-agent-page-body`'s
   padding-top is increased by the same amount (+ a breathing gap) so
   Advisor Snapshot / the contact card never sit under the portrait -- see
   that rule further below. No absolute positioning or negative margins
   are used, which keeps this overlap safe from horizontal-overflow and
   clipping issues (the brief's §5/§11 requirements) by construction. */
.jp-agent-page-hero {
  background: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-700) 100%);
  padding: clamp(40px, 6vw, 56px) 0 28px;
  overflow: visible;
}
.jp-agent-page-inner {
  display: grid; grid-template-columns: 1fr; gap: 28px; align-items: center; text-align: center;
}
@media (min-width: 760px) {
  .jp-agent-page-hero { padding-bottom: 0; }
  .jp-agent-page-inner { grid-template-columns: 1fr auto; gap: 40px; text-align: left; align-items: end; }
}
.jp-agent-page-heroinfo { display: flex; flex-direction: column; align-items: center; }
@media (min-width: 760px) { .jp-agent-page-heroinfo { align-items: flex-start; padding-bottom: 8px; } }

/* Portrait -- rectangular/vertical (NOT circular, per the brief's §6), with
   a restrained dark border, a thin gold accent ring and a soft shadow.
   Sized larger step by step (mobile → tablet → desktop) and shifted down
   with translateY only from the tablet breakpoint up, where it sits beside
   the text rather than below it -- see the comment above for why this
   creates the overlap without any layout-affecting positioning. */
.jp-agent-page-photo-wrap {
  display: inline-flex; margin: 0 auto; border-radius: 20px;
  border: 3px solid rgba(255,255,255,0.18);
  box-shadow: 0 0 0 1px rgba(201,168,76,0.35), var(--sh-2xl);
}
.jp-agent-page-photo {
  width: 220px; height: 280px; border-radius: 17px; object-fit: cover; object-position: top center;
  display: block;
}
.jp-agent-page-initials {
  width: 220px; height: 280px; border-radius: 17px;
  background: linear-gradient(135deg, var(--gold-400), var(--gold-300));
  color: var(--navy-900); display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 3.4rem;
}
/* Mobile keeps the photo below the text, in normal flow, with a small
   optional overlap into the content section (§13: "may still overlap
   slightly if it looks good, but it is NOT mandatory on mobile") -- kept
   modest specifically so it can never approach the fixed global nav. This
   base (mobile-first) rule MUST come before the ≥760px/≥1280px overrides
   below so the cascade's source-order tiebreak (equal selector specificity)
   resolves in their favor at wider widths, instead of this rule winning
   everywhere because it happened to be declared last. */
.jp-agent-page-hero .jp-agent-page-photo-wrap { transform: translateY(24px); }
@media (min-width: 760px) {
  .jp-agent-page-hero .jp-agent-page-photo-wrap { transform: translateY(48px); margin: 0; }
  .jp-agent-page-photo, .jp-agent-page-initials { width: 250px; height: 320px; }
}
@media (min-width: 1280px) {
  .jp-agent-page-hero .jp-agent-page-photo-wrap { transform: translateY(72px); }
  .jp-agent-page-photo, .jp-agent-page-initials { width: 290px; height: 370px; }
  .jp-agent-page-initials { font-size: 4.4rem; }
}

.jp-agent-page-name { color: var(--white); font-size: clamp(1.8rem, 1.3rem + 2vw, 2.9rem); font-weight: 800; letter-spacing: -0.03em; margin-bottom: 8px; }
.jp-agent-page-role { color: var(--gold-300); font-size: 1.05rem; font-weight: 700; margin-bottom: 6px; }
.jp-agent-page-location { color: rgba(255,255,255,0.6); font-size: 0.9rem; font-weight: 600; display: flex; align-items: center; gap: 6px; justify-content: center; }
@media (min-width: 760px) { .jp-agent-page-location { justify-content: flex-start; } }

/* JOMPLAN AGENT PROFILE — PHASE 2 (2026-09-23). Professional Headline —
   deliberately understated (smaller, lighter weight, muted opacity) so it
   reads as supporting positioning text beneath the name/role, never
   competing with them for visual weight in an already-dense hero (per the
   architecture audit §19's own flagged risk). Centered on mobile to match
   every other hero line at that width; left-aligned with the rest of the
   text column from the tablet breakpoint up. */
.jp-agent-page-headline {
  color: rgba(255,255,255,0.72); font-size: 0.92rem; font-weight: 500; line-height: 1.6;
  margin: 0 0 6px; max-width: 46ch;
}
/* JOMPLAN AGENT PROFILE — PHASE 6D-2 (2026-09-24). The headline block can
   now hold two stacked lines (English then Chinese) instead of one plain
   string, per the bilingual profile brief's simplest worked example -- no
   extra labels, no visual distinction between the two lines beyond the
   language itself. p{margin:0} avoids the block growing taller than the
   original single-line version by more than the second line itself. */
.jp-agent-page-headline p { margin: 0; }
.jp-agent-page-headline p + p { margin-top: 2px; }
@media (min-width: 760px) { .jp-agent-page-headline { max-width: 40ch; } }
.jp-agent-page-badge {
  display: inline-flex; align-items: center; gap: 6px; background: rgba(201,168,76,0.12);
  border: 1px solid rgba(201,168,76,0.3); color: var(--gold-300); font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; padding: 5px 14px; border-radius: var(--r-full);
  margin-bottom: 16px;
}

/* Hero primary CTA ("WhatsApp Me") -- shown only when the template emits
   it (agent.whatsappNumber present). Same WhatsApp green as the contact
   card's own WhatsApp button, for brand consistency, but a distinct class
   since it sits directly on the navy hero background rather than inside
   the white contact card. */
.jp-agent-page-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  background: #25D366; color: var(--white); font-size: 0.9rem; font-weight: 700;
  padding: 12px 24px; border-radius: var(--r-full); text-decoration: none; margin-top: 18px;
  box-shadow: 0 8px 20px rgba(37,211,102,0.35); transition: background 0.2s ease, transform 0.2s ease;
}
.jp-agent-page-cta:hover { background: #1EBE5A; transform: translateY(-1px); }
.jp-agent-page-cta:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 2px; }

/* JOMPLAN AGENT PROFILE -- PHASE 4E (2026-09-24). "Hear My Introduction" --
   compact voice-intro component in the hero identity column, between
   Location and the WhatsApp CTA (see agent-profile-template.js's render()).
   Reuses the exact gold-tinted-on-navy visual language already established
   by .jp-agent-page-badge above (rgba(201,168,76,...) tint + border, gold-
   300 text) rather than inventing a new color pairing, so this reads as
   belonging to the same hero rather than as a bolted-on widget. Deliberately
   NOT the white/--gray-50 card treatment used by .jp-agent-details/
   .jp-contact-card further down -- those belong to the white body section,
   this sits on the dark hero. Sized to stay compact/secondary next to the
   name and portrait: a small label, one line of muted supporting copy, and
   the browser's own native controls (no custom player chrome). Text-align
   is pinned to left explicitly because it sits inside
   .jp-agent-page-heroinfo, which centers its children on mobile and
   left-aligns them from 760px up (see that rule above) -- this component
   should never center its own internal label/sub/controls even while the
   surrounding column is itself centered on mobile. max-width keeps the
   native <audio> element (which otherwise stretches to fill available
   width) from ever growing as wide as the full hero text column. */
.jp-agent-voice-intro {
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  gap: 6px; width: 100%; max-width: 340px;
  background: rgba(201,168,76,0.10); border: 1px solid rgba(201,168,76,0.28);
  border-radius: var(--r-lg); padding: 14px 16px; margin: 4px 0 4px;
  box-sizing: border-box;
}
@media (min-width: 760px) { .jp-agent-voice-intro { max-width: 380px; } }
.jp-agent-voice-intro-label {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--gold-300); font-size: 0.82rem; font-weight: 700; letter-spacing: 0.01em;
}
.jp-agent-voice-intro-label svg { flex-shrink: 0; }
.jp-agent-voice-intro-sub {
  color: rgba(255,255,255,0.6); font-size: 0.78rem; line-height: 1.5; margin: 0;
}
.jp-agent-voice-intro-player {
  width: 100%; max-width: 100%; height: 36px; margin-top: 2px;
  border-radius: var(--r-full);
}

/* JOMPLAN AGENT PROFILE — PHASE 1B (2026-09-23). padding-top is explicitly
   larger than the base clamp at each breakpoint, sized to clear the hero
   portrait's translateY overlap (see the hero rules above) plus a small
   breathing gap -- e.g. at ≥1280px the portrait overlaps by 72px, so
   120px of clearance here keeps Advisor Snapshot (and the contact card)
   from ever sitting under it, per the brief's §10, without resorting to
   one large blank margin used at every width regardless of overlap size. */
.jp-agent-page-body { padding: clamp(40px, 6vw, 72px) 0; padding-top: 64px; }
@media (min-width: 760px) { .jp-agent-page-body { padding-top: 100px; } }
@media (min-width: 1280px) { .jp-agent-page-body { padding-top: 120px; } }
.jp-agent-page-grid { display: grid; grid-template-columns: 1fr; gap: 40px; }
@media (min-width: 860px) { .jp-agent-page-grid { grid-template-columns: 1.4fr 1fr; gap: 48px; } }

/* JOMPLAN AGENT PROFILE — PHASE 6D-2 (2026-09-24). Single, page-level,
   unobtrusive notice shown only when this agent has no Chinese profile
   content at all (agent.profileContent.zh === null in agent-profile-
   template.js) -- never one per bilingual section, to avoid clutter. Sits
   at the very top of the main content column, above Advisor Snapshot.
   Deliberately quiet: muted text, a light neutral card, no icon, no
   color-coded warning treatment -- this is informational, not an error,
   and the rest of the (English) profile below remains fully visible and
   unaffected. Visually related to but distinct from .jp-contact-note
   further down (same muted-gray-text convention) -- that one is centered
   and lives inside the sticky contact card; this one is left-aligned and
   lives in the main content column, so each reads correctly in its own
   context rather than sharing one class across two different layouts. */
.jp-agent-lang-notice {
  font-size: 0.82rem; color: var(--gray-500); line-height: 1.6;
  background: var(--gray-50); border: 1px solid var(--gray-200); border-radius: var(--r-lg);
  padding: 12px 16px; margin: 0 0 24px;
}

/* "About <Name>" -- restyled with a small gold accent rule beside the
   heading (a ::before bar, purely decorative) so it reads as a considered
   section rather than a plain <h2>. Markup/content unchanged. */
.jp-agent-bio { margin-bottom: 32px; }
.jp-agent-bio h2 {
  display: flex; align-items: center; gap: 10px;
  font-size: 1.3rem; font-weight: 800; color: var(--navy-800); margin-bottom: 14px; letter-spacing: -0.02em;
}
.jp-agent-bio h2::before { content: ''; display: block; width: 4px; height: 20px; border-radius: 2px; background: var(--gold-400); flex-shrink: 0; }
.jp-agent-bio p { color: var(--gray-600); line-height: 1.85; font-size: 0.98rem; }

/* JOMPLAN AGENT PROFILE — PHASE 1 (2026-09-23). "Advisor Snapshot"
   (Languages / Areas Served) -- restyled from a plain grey box into a
   labeled snapshot card with its own compact eyebrow-style heading, and
   Areas Served now rendered as pill/chip tags. See
   agent-profile-template.js's own Phase 1 comment for why Languages and
   Areas Served are consolidated into this one card rather than three
   separate sections. Omitted entirely by the template when both
   underlying fields are empty -- no empty-state styling needed here. */
.jp-agent-details {
  display: flex; flex-direction: column; gap: 16px;
  background: var(--gray-50); border: 1.5px solid var(--gray-200); border-radius: var(--r-lg);
  padding: 22px 24px; margin-bottom: 28px;
}
.jp-agent-details h2 {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--gold-600, var(--gold-500)); margin: 0;
}
.jp-agent-details-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.jp-agent-details-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gray-500); flex-shrink: 0; min-width: 108px;
}
.jp-agent-details-value { font-size: 0.92rem; font-weight: 600; color: var(--navy-800); }
.jp-agent-details-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.jp-agent-details-chip {
  display: inline-flex; align-items: center; font-size: 0.8rem; font-weight: 600; color: var(--navy-700);
  background: var(--white); border: 1.5px solid var(--gray-200); border-radius: var(--r-full); padding: 5px 14px;
}

/* JOMPLAN AGENT PROFILE — PHASE 2 (2026-09-23). "Who I Help" — a new
   section, between About and My Specialties in the DOM (see
   agent-profile-template.js). Heading reuses the exact same gold-accent-
   bar treatment as "About <Name>" (.jp-agent-bio h2) for a consistent
   section-heading language across the page; chips reuse Advisor
   Snapshot's own .jp-agent-details-chip visual (pill, white fill, thin
   gray border) rather than inventing a third chip style, per the audit
   §12's explicit "consistency, not a new style" recommendation. */
.jp-agent-who-i-help { margin-bottom: 32px; }
.jp-agent-who-i-help h2 {
  display: flex; align-items: center; gap: 10px;
  font-size: 1.3rem; font-weight: 800; color: var(--navy-800); margin-bottom: 14px; letter-spacing: -0.02em;
}
.jp-agent-who-i-help h2::before { content: ''; display: block; width: 4px; height: 20px; border-radius: 2px; background: var(--gold-400); flex-shrink: 0; }
.jp-agent-who-i-help-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.jp-agent-who-i-help-chip {
  display: inline-flex; align-items: center; font-size: 0.85rem; font-weight: 600; color: var(--navy-700);
  background: var(--white); border: 1.5px solid var(--gray-200); border-radius: var(--r-full); padding: 7px 16px;
}

/* "My Specialties" (agent.services -- this agent's own data) gets the
   premium treatment: each item is an elevated card with its check icon in
   a filled gold roundel, arranged in a responsive card grid rather than a
   plain stacked list. Markup is unchanged (still a plain <ul><li> per
   specialty from agent-profile-template.js) -- only this CSS changes. */
.jp-agent-specialties { margin-bottom: 32px; }
.jp-agent-specialties h2 { font-size: 1.3rem; font-weight: 800; color: var(--navy-800); margin-bottom: 14px; letter-spacing: -0.02em; }
/* JOMPLAN AGENT PROFILE — PHASE 1B (2026-09-23). Changed from
   `repeat(auto-fill, minmax(200px, 1fr))` to a fixed 2-column grid. The
   auto-fill version packed as many ≥200px columns as the container could
   fit, which at some in-between widths fit exactly 3 columns -- producing
   the uneven "3 cards then 1 alone" arrangement the brief called out.
   A fixed 2-column grid gives a clean 2×2 for the standard 4-item case at
   any width down to 480px, where it collapses to a single column so cards
   never get too narrow to read comfortably. Service data/names/count are
   unchanged -- this is a layout-only fix. */
.jp-agent-specialties ul {
  list-style: none; padding: 0; margin: 0; display: grid;
  grid-template-columns: repeat(2, 1fr); gap: 12px;
}
/* JOMPLAN AGENT PROFILE — PHASE 6D-2 (2026-09-24). "My Specialties" can now
   render two <ul> lists back to back (English then Chinese) when the agent
   has specialties in both languages -- this small top margin on the second
   list is the only thing separating them, since each <ul>'s own `margin: 0`
   above would otherwise butt them together with no gap. */
.jp-agent-specialties ul + ul { margin-top: 12px; }
@media (max-width: 480px) {
  .jp-agent-specialties ul { grid-template-columns: 1fr; }
}
.jp-agent-specialties li {
  display: flex; align-items: center; gap: 12px; font-size: 0.9rem; font-weight: 600; color: var(--navy-800);
  background: var(--white); border: 1.5px solid var(--gray-200); border-radius: var(--r-lg); padding: 16px;
  box-shadow: var(--sh-sm, 0 1px 2px rgba(16,24,40,0.05));
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.jp-agent-specialties li:hover { transform: translateY(-2px); box-shadow: var(--sh-md, 0 4px 12px rgba(16,24,40,0.08)); border-color: var(--gold-300); }
.jp-agent-specialties li svg {
  flex-shrink: 0; width: 30px; height: 30px; padding: 7px; box-sizing: border-box;
  border-radius: 50%; background: rgba(201,168,76,0.14); color: var(--gold-600, var(--gold-500));
}

/* "What JomPlan Agents Can Help With" (the generic, platform-wide list,
   NOT agent-specific) -- deliberately kept visually secondary/muted next
   to the premium "My Specialties" cards above, so the agent's own data
   stays the visual focus. Same <ul><li> markup shape as before; smaller
   type, a plain-outline icon instead of a filled roundel, and a quieter
   heading are what create the secondary feel. */
.jp-agent-services { margin-bottom: 8px; }
.jp-agent-services h2 {
  font-size: 0.85rem; font-weight: 700; color: var(--gray-500); margin-bottom: 12px;
  letter-spacing: 0.02em; text-transform: none;
}
.jp-agent-services ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.jp-agent-services li {
  display: flex; align-items: center; gap: 10px; font-size: 0.84rem; color: var(--gray-500);
  background: transparent; border-bottom: 1px solid var(--gray-100); padding: 9px 2px;
}
.jp-agent-services li:last-child { border-bottom: none; }
.jp-agent-services li svg { flex-shrink: 0; color: var(--gray-400); }

/* Contact card ("Let's Talk") -- same four conditional contact methods and
   fallback note as before this phase; visual treatment only: a gold top
   accent, larger heading, and icon-plus-label buttons for every method
   (Call/Email now match WhatsApp's existing icon treatment). */
.jp-contact-card {
  background: var(--white); border: 1.5px solid var(--gray-200); border-top: 3px solid var(--gold-400);
  border-radius: var(--r-xl); padding: 30px 28px; position: sticky; top: 24px; box-shadow: var(--sh-lg);
}
.jp-contact-card h3 { font-size: 1.15rem; font-weight: 800; color: var(--navy-800); margin-bottom: 20px; letter-spacing: -0.01em; }

/* JOMPLAN AGENT PROFILE — PHASE 2 (2026-09-23). Consultation Mode, folded
   into the top of this card per the architecture audit §7/§12 -- a small
   eyebrow label plus a row of badges, sitting between the "Let's Talk"
   heading and the actual contact buttons so the flow reads as "how you
   can reach me" (modes) then "reach me now" (buttons). Badges reuse a
   quieter outline treatment (thinner border, no shadow) than the premium
   .jp-agent-details-chip/.jp-agent-who-i-help-chip pills, since this is a
   secondary detail inside an already-prominent sticky card, not its own
   section. */
.jp-contact-consultation { margin-bottom: 20px; }
.jp-contact-consultation-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gray-500); margin-bottom: 8px;
}
.jp-contact-consultation-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.jp-contact-consultation-chip {
  display: inline-flex; align-items: center; font-size: 0.76rem; font-weight: 600; color: var(--navy-600);
  background: var(--gray-50); border: 1px solid var(--gray-200); border-radius: var(--r-full); padding: 4px 12px;
}
.jp-contact-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 13px 20px; border-radius: var(--r-full); font-size: 0.88rem; font-weight: 700;
  text-decoration: none; margin-bottom: 10px; transition: all 0.2s ease; box-sizing: border-box;
}
.jp-contact-btn-whatsapp { background: #25D366; color: var(--white); }
.jp-contact-btn-whatsapp:hover { background: #1EBE5A; transform: translateY(-1px); }
.jp-contact-btn-outline { border: 1.5px solid var(--gray-300); color: var(--navy-700); background: var(--white); }
.jp-contact-btn-outline:hover { border-color: var(--navy-400); background: var(--gray-50); transform: translateY(-1px); }
.jp-contact-btn svg { flex-shrink: 0; }

/* JOMPLAN AGENT PROFILE -- PHASE 4F (2026-09-24, WHATSAPP QR CODE). Sits
   inside the "Let's Talk" card, after the primary contact buttons and
   before the social-links row (see agent-profile-template.js's render()).
   Hidden below the same ~760px breakpoint already used elsewhere on this
   page (e.g. .jp-agent-page-inner above) -- the existing WhatsApp button
   remains visible and fully functional on mobile regardless; this block is
   a secondary, tablet/desktop-only convenience, never a replacement for
   it. Sized within the ~180-220px target agreed for this phase, with a
   light bordered-card treatment consistent with .jp-agent-details /
   .jp-contact-consultation elsewhere on this page rather than a new
   visual language. Whole block is only ever rendered by the template when
   the agent has a WhatsApp number (see qrBlockHtml in
   agent-profile-template.js) -- no separate "no WhatsApp" styling is
   needed here. */
.jp-whatsapp-qr {
  display: none;
  flex-direction: column; align-items: center; text-align: center;
  gap: 10px; margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--gray-100);
}
@media (min-width: 760px) {
  .jp-whatsapp-qr { display: flex; }
}
.jp-whatsapp-qr-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gray-500);
}
.jp-whatsapp-qr-canvas {
  width: 200px; height: 200px; max-width: 100%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--white); border: 1.5px solid var(--gray-200); border-radius: var(--r-lg);
  padding: 10px; box-sizing: border-box; overflow: hidden;
}
.jp-whatsapp-qr-link { display: block; width: 100%; height: 100%; line-height: 0; }
.jp-whatsapp-qr-link:focus-visible { outline: 2px solid var(--gold-500); outline-offset: 2px; }
.jp-whatsapp-qr-svg { width: 100%; height: 100%; display: block; }
.jp-whatsapp-qr-sub { font-size: 0.76rem; color: var(--gray-400); line-height: 1.5; margin: 0; max-width: 220px; }

/* JOMPLAN AGENT PROFILE -- PHASE 3 (2026-09-24). Social Media / Digital
   Presence. Small, restrained, secondary row of icon-only links, placed
   after the primary contact buttons and before the closing note -- the
   primary WhatsApp/Call/Email/Visit-Website buttons above remain the
   dominant CTA (Phase 3 architecture audit §10/§11). Whole row is only
   ever rendered when at least one social link exists (see
   agent-profile-template.js's socialLinksHtml()) -- no wrapper, heading
   or placeholder text otherwise, matching every other optional section
   on this page. flex-wrap keeps all seven icons usable and unclipped
   even in the narrowest supported layout (390px). */
.jp-social-row {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--gray-100);
}
.jp-social-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--r-full);
  background: var(--gray-50); border: 1px solid var(--gray-200); color: var(--gray-500);
  transition: all 0.2s ease; flex-shrink: 0;
}
.jp-social-icon:hover, .jp-social-icon:focus-visible {
  background: var(--gray-100); color: var(--navy-700); border-color: var(--navy-300); transform: translateY(-1px);
}
.jp-social-icon svg { flex-shrink: 0; }
.jp-contact-note { font-size: 0.75rem; color: var(--gray-400); text-align: center; margin-top: 12px; line-height: 1.6; }

.jp-notfound { min-height: 60vh; display: flex; align-items: center; justify-content: center; text-align: center; padding: 40px 20px; }
.jp-notfound h1 { font-size: 1.6rem; font-weight: 800; color: var(--navy-800); margin-bottom: 12px; }
.jp-notfound p { color: var(--gray-500); line-height: 1.7; max-width: 420px; margin: 0 auto 20px; }

/* ── Homepage: "Find Your JomPlan Agent" + featured agents + coverage ── */
.jp-featured-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.jp-coverage-stats { display: flex; flex-wrap: wrap; justify-content: center; gap: 32px; margin-top: 8px; }
.jp-coverage-stat { text-align: center; }
.jp-coverage-stat .num { font-size: 1.8rem; font-weight: 900; color: var(--gold-300); letter-spacing: -0.03em; display: block; }
.jp-coverage-stat .lbl { font-size: 0.72rem; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; }

@media (max-width: 600px) {
  .jp-agent-grid { grid-template-columns: 1fr; }
  .jp-map-panel { position: static; }
  .jp-contact-card { position: static; }
}
