/* ════════════════════════════════════════════════════════════════════════
 * scx-tile-overlap-fix.css · v18.10.2-b14
 *
 * Fixes text overlapping across tiles/cards site-wide.
 *
 * ROOT CAUSE
 *   Grid and flex children default to `min-width: auto` (and
 *   `min-height: auto`), which means they REFUSE to shrink below the
 *   intrinsic size of their content. When a tile contains a long
 *   unbroken string — a skill name, a job title, a URL, a long number —
 *   the child blows past its track and visually overlaps the neighbour.
 *
 *   The site has 16 rigid `repeat(N, 1fr)` grids but only 4 `min-width:0`
 *   declarations and no `overflow-wrap`, so most tile grids are exposed
 *   to this.
 *
 * WHAT THIS DOES
 *   1. Allows grid/flex tile children to shrink (min-width:0) so tracks
 *      are respected instead of overflowing.
 *   2. Lets long words wrap instead of spilling (overflow-wrap).
 *   3. Targets the specific tile/card class families used on the site,
 *      plus a safe generic rule for direct children of known grids.
 *
 * WHY IT'S SAFE
 *   - It only RELAXES min-width and ENABLES wrapping. It does not change
 *     colors, spacing, fonts, or grid definitions.
 *   - Worst case if a selector is too broad: a long word wraps onto two
 *     lines instead of overflowing — strictly better than overlap.
 *   - Loaded LAST so it wins specificity ties without !important where
 *     possible (a few high-traffic rules use !important to beat inline
 *     styles, which the tiles use heavily).
 *
 * ROLLBACK: remove the <link> to this file. No other file is modified.
 * ════════════════════════════════════════════════════════════════════════ */

/* 1 · Generic: any direct child of a grid/flex tile container can shrink.
   These class names are the tile/card containers actually used on the
   site (homepage features, result-page metrics, portal cards, etc.). */
.grid > *,
.cards > *,
.ind-grid > *,
.metric-grid > *,
.stat-grid > *,
.if-grid > *,
.ns-metric-grid > *,
.portal-usage > *,
.tile-grid > *,
.feature-grid > * {
  min-width: 0;
  min-height: 0;
}

/* 2 · Tile/card content: allow long tokens to wrap rather than overflow.
   overflow-wrap:anywhere breaks long unbroken strings (URLs, skill IDs);
   word-break:normal keeps normal words intact where possible. */
.tile,
.card,
.ind,
.metric,
.stat,
.ifc,
.if-card,
.ns-metric,
.ns-card,
.portal-usage-item,
.price-card,
.job-card,
.pillar,
.val,
.tcard {
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: normal;
}

/* 3 · Text elements inside tiles: the actual labels/values that overlap.
   Scope to tile contexts so we don't touch body copy elsewhere. */
.tile *,
.card *,
.ind *,
.metric *,
.stat *,
.ifc *,
.if-card *,
.ns-metric *,
.ns-card *,
.portal-usage-item *,
.tcard * {
  overflow-wrap: anywhere;
  min-width: 0;
}

/* 4 · Skill chips / pills: these are inline-flex and a long skill name
   can push siblings. Let them wrap and shrink. */
.skill-chip,
.skill-pill,
.ns-chip,
.chip,
[class*="chip"],
[class*="pill"] {
  min-width: 0;
  overflow-wrap: anywhere;
  max-width: 100%;
}

/* 5 · The 6-axis radar / skill-bar grids on the paid result view use
   a 4-column inline grid (24px 130px 1fr 75px). The 130px label column
   can overlap the bar if the skill name is long. Force ellipsis there. */
.ns-skillbar-label,
.ns-radar-legend-label,
[style*="grid-template-columns:24px"] > div:nth-child(2),
[style*="grid-template-columns: 24px"] > div:nth-child(2) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 6 · Defensive: known rigid grids get a min-0 on children even if the
   tile class above didn't match (covers inline-styled tiles generated
   by the northstar JS bundles). */
[style*="grid-template-columns:repeat"] > *,
[style*="grid-template-columns: repeat"] > *,
[style*="display:grid"] > *,
[style*="display: grid"] > * {
  min-width: 0;
}

/* ════════════════════════════════════════════════════════════════════════
 * b15 ADDITIONS · resume-intelligence report alignment + width fixes
 *
 * Symptom (from user screenshots): the resume-intelligence report renders
 * shifted left at the top and shifted right lower down, not using the full
 * column width.
 *
 * ROOT CAUSE: a CSS class-name COLLISION on `.ls-grid`.
 *   - styles.css defines `.ls-grid { position:absolute; inset:0; ... }`
 *     as a DECORATIVE animated background-grid overlay.
 *   - scx-output-landscape.js injects `.ls-grid { display:grid;
 *     grid-template-columns:repeat(12,1fr); ... }` as the STRUCTURAL card
 *     grid that holds the report cards.
 *   Both are global/unscoped, so the report's real card grid can inherit
 *   `position:absolute; inset:0`, ripping it out of normal flow and
 *   misaligning everything.
 *
 * FIX: scope the report's structural grid with `#ns-result .ls-grid`
 *   (higher specificity than either global rule) and force it back into
 *   normal flow with full column width. Also pin the report wrapper to
 *   the centered column so it can't drift.
 *
 * SAFE: scoped to #ns-result only; the decorative .ls-grid elsewhere on
 *   the site is untouched. Rollback = delete this block.
 * ════════════════════════════════════════════════════════════════════════ */

/* 1 · Force the report's structural card grid back into normal flow.
   Neutralises the decorative position:absolute/inset:0 collision. */
#ns-result .ls-grid {
  position: static !important;
  inset: auto !important;
  display: grid !important;
  grid-template-columns: repeat(12, 1fr) !important;
  gap: 1rem;
  background-image: none !important;   /* kill the decorative grid lines */
  animation: none !important;          /* kill gridShift on the card grid */
  width: 100% !important;
  opacity: 1 !important;
}

/* 2 · Report wrapper + every report section uses the full column width
   and stays left-aligned within the centered 880px .nx-n column. */
#ns-result,
#ns-result > div,
#ns-result section,
#ns-result .scx-apple-section,
#ns-result .scx-hero-strip,
#ns-result #ns-rw-mount,
#ns-result #ns-rw-mount > *,
#ns-result .ns-rw-status,
#ns-result [class*="ns-rw"],
#ns-result [id*="ns-rw"] {
  width: 100% !important;
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  float: none !important;
  transform: none !important;
  left: auto !important;
  right: auto !important;
  box-sizing: border-box;
}

/* 3 · The apple-section left accent bar is absolutely positioned at
   left:-2rem. If the section has no left padding / the parent clips
   overflow, the bar (and the offset it implies) can misalign content.
   Give the sections a small left padding so the bar sits in the gutter
   instead of pushing/▒overlapping content, and ensure positioning ctx. */
#ns-result .scx-apple-section {
  position: relative !important;
  padding-left: 0 !important;
  margin-left: 0 !important;
}
#ns-result .scx-apple-section > div[style*="left:-2rem"],
#ns-result .scx-apple-section > div[style*="left: -2rem"] {
  left: 0 !important;   /* keep the accent bar inside the card, not in negative space */
}

/* 4 · Overview / metric card strips: ensure the flex/grid row fills width
   and wraps instead of overflowing to the right (the "lower half shifted
   right" symptom). */
#ns-result [style*="display:flex"][style*="justify-content:space-between"],
#ns-result [style*="display: flex"][style*="justify-content: space-between"] {
  width: 100% !important;
  flex-wrap: wrap;
}

/* ════════════════════════════════════════════════════════════════════════
 * b16 ADDITIONS · badge overlap + go-to-top/chatbot collision
 *
 * SYMPTOM A (screenshots 2-6): the red "TOP SERVICE" / "MOST POPULAR" /
 *   "RECOMMENDED" badge pills overlap the card's category label instead of
 *   sitting in the top-right corner. E.g. "MOST ENGAGEMENTS▒ERVICES".
 *
 * ROOT CAUSE: the badge is `position:absolute; top:1.3rem; right:1.3rem`,
 *   but its parent card (.pillar / .price-card / .tier-card) does not
 *   reliably establish a positioning context (`position:relative`), so the
 *   badge escapes to a distant positioned ancestor and lands in the wrong
 *   place — on top of the eyebrow text.
 *
 * FIX: force `position:relative` on every card that contains a badge, so
 *   the absolute badge anchors to its own card's top-right corner.
 *   Also give the card enough top padding so a top-right badge never
 *   collides with the card's own kicker/eyebrow on narrow widths.
 * ════════════════════════════════════════════════════════════════════════ */

.pillar,
.price-card,
.tier-card,
.staffing-card,
.rec-tier,
[class*="-card"]:has(> [class*="-badge"]),
[class*="pillar"]:has(> [class*="badge"]) {
  position: relative !important;
}

/* Badge pills: pin to top-right, above content, and never stretch across
   the card (which is what makes them look like they overlap a label). */
.pillar-badge,
.price-badge,
.tier-badge,
.rec-badge,
[class*="-badge"] {
  position: absolute !important;
  top: 1.1rem !important;
  right: 1.1rem !important;
  left: auto !important;            /* never anchor left → no label overlap */
  width: auto !important;
  max-width: calc(100% - 2.2rem);
  z-index: 3 !important;
  white-space: nowrap;
}

/* Give badge-bearing cards room at the top so the kicker text starts
   below the badge zone, not under it. */
.pillar:has(.pillar-badge),
.price-card:has(.price-badge),
.price-card.featured {
  padding-top: 3.2rem !important;
}

/* ────────────────────────────────────────────────────────────────────────
 * SYMPTOM B (screenshots 1 & 8): the "go to top" ↑ arrow is hidden behind
 *   the chatbot launcher icon — they occupy the same bottom-right corner.
 *   Confirmed real IDs: back-to-top = #scx-btt (bottom:24px;right:24px;
 *   z-index:990); chatbot launcher = #chatbot-toggle (bottom:1.8rem;
 *   right:1.8rem). They sit on top of each other.
 *
 * FIX: lift #scx-btt above the chatbot bubble (chatbot is ~64px tall at
 *   ~1.8rem from bottom → clear it by stacking the arrow at ~104px) and
 *   raise its z-index above the chatbot.
 * ──────────────────────────────────────────────────────────────────────── */

#chatbot-toggle {
  z-index: 9000 !important;
}

#scx-btt {
  bottom: 104px !important;   /* stack above the chatbot launcher */
  right: 24px !important;
  z-index: 9100 !important;   /* above the chatbot */
}

/* ════════════════════════════════════════════════════════════════════════
 * b19 SAFETY NET · guarantee the resume result is never invisible
 *
 * The site uses a reveal-on-scroll system: any element with a `da=`
 * attribute starts at `opacity:0` (see styles.css `[da]{opacity:0}`) and
 * only becomes visible when JS adds the `.in` class via an
 * IntersectionObserver. If that observer fails to fire for the result
 * container — for ANY reason (timing, a thrown error in another script,
 * the container being re-rendered after the observer ran) — the entire
 * report stays present in the DOM but fully invisible. That presents as
 * "the tailored results are gone."
 *
 * This rule makes the result content immune to that failure mode: any
 * reveal-animated element INSIDE #ns-result is forced visible. The
 * scroll-reveal animation still works elsewhere on the site; we only
 * override it within the result region, where a hidden state is never
 * desirable (the user explicitly asked to see their analysis).
 *
 * This is defensive and has no downside: worst case, the report appears
 * immediately instead of fading in on scroll.
 * ════════════════════════════════════════════════════════════════════════ */
#ns-result [da],
#ns-result [da]:not(.in),
#ns-result .scx-apple-section,
#ns-result .ls-card,
#ns-result .ls-hero,
#ns-result section {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
  visibility: visible !important;
}
