/* ============================================================
   NPF Core — logged-in dashboard
   Ported from nonprofit/expert-dashboard.html. Scoped under
   .npf-dash; design class names are namespaced npf-* so they
   cannot collide with the theme's Semantic UI.

   The dynamic blocks keep the theme's own markup (job cards,
   category chips, recently-viewed list), so those selectors are
   re-skinned in place rather than replaced.
   ============================================================ */

.npf-dash {
  --npf-primary: #4f84c3;
  --npf-primary-dark: #3e6ea6;
  --npf-primary-soft: #e1eeff;
  --npf-primary-tint: #e1eeff;
  --npf-primary-light: #6ac9fc;
  --npf-ink: #020b18;
  --npf-hero-ink: #1e1e1e;
  --npf-muted: #677489;
  --npf-line-soft: #eef1f6;
  --npf-navy: #133660;
  --npf-bed: #f9fbff;
  --npf-shadow-panel: 0 4px 33.7px rgba(0, 0, 0, 0.01);
  --npf-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --npf-t: 0.28s var(--npf-ease);
  --npf-font-body: "Inter", system-ui, -apple-system, sans-serif;
  --npf-font-headline: "Roboto", "Inter", system-ui, sans-serif;

  /* .dash — background var(--auth-bed); padding-top 100px */
  background: var(--npf-bed);
  padding-top: 100px;
  font-family: var(--npf-font-body);

  /* Full-bleed out of .wpj-page-content's site-width cap. */
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  box-sizing: border-box;
}

/* ---- Nothing on these pages may cross the sticky header ----

   Reported on both dashboards and on the profile page: on scroll the theme's
   "Load More" control and the badge over the profile avatar drew straight
   through the header. Both are the theme's own markup, and both carry
   stacking of their own — the badge is `z-index: 102` in front.min.css, above
   the 100 the header used to hold.

   Raising the header (npf-skin.css) answers the values that exist today.
   These two rules answer the ones that do not: `z-index: 0` on the page
   wrapper puts everything inside it into a single stacking context that is
   itself painted below the header, so no descendant can reach past it however
   large its own z-index is. The order inside each page is unchanged — the
   context is shared, so the cards, chips and dropdowns still stack against
   each other exactly as before.

   Scoped to these two templates on purpose. Screens that legitimately need
   content over the header — the account drawers, the chat panel, Semantic's
   modals, all of which are attached outside this wrapper — are untouched. */
main.npf-dash,
body.npf-profile .profile-page-wrapper {
  position: relative;
  z-index: 0;
}

.npf-dash__container {
  width: 100%;
  max-width: 1248px;
  margin-inline: auto;
  padding-inline: 24px;
  box-sizing: border-box;
}

/* .dash-layout — 308px sidebar + main, 31px gap */
.npf-dash__layout {
  display: grid;
  grid-template-columns: 308px minmax(0, 1fr);
  grid-template-areas:
    "side welcome"
    "side main";
  column-gap: 31px;
  align-items: start;
  padding-bottom: 100px;
}

/* minmax(0,1fr) + min-width:0 stop the cards sizing to their content and
   spilling out of the 308px column, where the main panel then overlapped them. */
.npf-dash__side {
  grid-area: side;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 30px;
  align-content: start;
  min-width: 0;
}

.npf-dash__side > * { min-width: 0; max-width: 100%; }
.npf-dash__welcome { grid-area: welcome; text-align: center; margin-bottom: 75px; }
.npf-dash__main { grid-area: main; display: grid; gap: 30px; }

/* ---------- Profile card (308x288 navy) ---------- */

.npf-profile-card {
  background: var(--npf-navy);
  border-radius: 7px;
  padding: 42px 41px;
  text-align: center;
  color: #fff;
}

.npf-profile-card__avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  margin: 0 auto 16px;
}

.npf-profile-card__name {
  font-family: var(--npf-font-body);
  font-weight: 500;
  font-size: 16px;
  line-height: 20px;
  color: #fff;
  margin: 0;
}

.npf-profile-card__balance {
  font-size: 16px;
  line-height: 26px;
  color: #9d9d9d;
  margin: 0 0 16px;
}

.npf-profile-card .npf-btn { width: 100%; }
.npf-profile-card .npf-btn + .npf-btn { margin-top: 10px; }

/* ---------- Buttons ---------- */

.npf-dash .npf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 54px;
  padding: 0 24px;
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
  color: #fff;
  background: var(--npf-primary);
  border: 0;
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--npf-t), transform var(--npf-t);
}

.npf-dash .npf-btn:hover {
  background: var(--npf-primary-dark);
  color: #fff;
  transform: translateY(-2px);
}

.npf-dash .npf-btn--block { width: 100%; }

.npf-dash .npf-btn--ghost {
  background: transparent;
  border: 1.5px solid rgba(255, 255, 255, 0.45);
}
.npf-dash .npf-btn--ghost:hover { background: rgba(255, 255, 255, 0.12); }

/* ---------- Side cards ---------- */

.npf-side-card {
  background: #fff;
  border: 1px solid var(--npf-primary);
  border-radius: 7px;
  padding: 26px;
  box-shadow: var(--npf-shadow-panel);
}

.npf-side-card--action {
  display: grid;
  justify-items: center;
  padding: 30px 40px;
}

.npf-side-card--action .npf-btn { width: 100%; max-width: 226px; }

.npf-side-card__title {
  font-family: var(--npf-font-headline);
  font-weight: 400;
  font-size: 24px;
  line-height: 30px;
  color: var(--npf-ink);
  margin: 0 0 13px;
}

/* ---------- Top skills — theme's [popular_categories] output ----------
   Markup: .ui.segment > .most-popular-terms > h4 + a* */

.npf-skills .ui.segment,
.npf-skills .most-popular-terms {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}

/* The shortcode prints its own "Popular categories" heading; the card
   already has the design's "Top skills" title above it. */
.npf-skills h4 { display: none; }

.npf-skills .most-popular-terms {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.npf-skills ul,
.npf-skills .ui.list,
.npf-skills .categories {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 13px;
  padding: 0;
  list-style: none;
}

.npf-skills li { margin: 0; padding: 0; list-style: none; }

.npf-skills a,
.npf-skills .ui.label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  font-family: var(--npf-font-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 26px;
  color: var(--npf-ink);
  background: #fff;
  border: 1px solid var(--npf-primary-tint);
  border-radius: 4px;
  padding: 0 10px;
  margin: 0;
  text-decoration: none;
  transition: background var(--npf-t), border-color var(--npf-t), color var(--npf-t);
}

.npf-skills a:hover,
.npf-skills .ui.label:hover {
  border-color: var(--npf-primary);
  color: var(--npf-primary);
  background: #fff;
}

/* ---------- Recently viewed — theme's [recently_viewed_jobs] output ----------
   Real markup is: .ui > .last-viewed-posts > h4 + .recently-v-box*
   where each box is .image > a > img, plus h5 > a for the title. */

.npf-recent .ui,
.npf-recent .last-viewed-posts {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}

/* The shortcode's own heading becomes the card title. */
.npf-recent h4 {
  font-family: var(--npf-font-headline);
  font-weight: 400;
  font-size: 24px;
  line-height: 30px;
  color: var(--npf-ink);
  margin: 0 0 13px;
  padding: 0;
  border: 0;
}

.npf-recent .recently-v-box {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 0 17px;
  margin: 0 0 17px;
  border-bottom: 1px solid var(--npf-line-soft);
}

.npf-recent .recently-v-box:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

.npf-recent .recently-v-box .image {
  flex: none;
  width: 64px;
  height: 64px;
  margin: 0;
}

.npf-recent img {
  width: 64px;
  height: 64px;
  border-radius: 10px;
  object-fit: cover;
  display: block;
}

.npf-recent h5 {
  margin: 0;
  font-family: var(--npf-font-body);
  font-weight: 400;
  font-size: 15px;
  line-height: 22px;
}

.npf-recent h5 a,
.npf-recent a {
  font-family: var(--npf-font-body);
  font-weight: 400;
  font-size: 15px;
  line-height: 22px;
  color: var(--npf-ink);
  text-decoration: none;
  transition: color var(--npf-t);
}

.npf-recent h5 a:hover,
.npf-recent a:hover { color: var(--npf-primary); }

/* ---------- Welcome ---------- */

.npf-dash__welcome h1 {
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: 40px;
  line-height: 46px;
  letter-spacing: -1.67px;
  color: var(--npf-hero-ink);
  text-transform: capitalize;
  width: 693px;
  max-width: 100%;
  margin: 0 auto;
}

.npf-text-primary { color: var(--npf-primary); }

/* ---------- Buyer search ----------
   Sits under the greeting for nonprofits, in place of the freelancer's
   "List your Service" callout. Deliberately the homepage hero's search shape —
   pill field, filled button inside it, chips underneath — because it is the
   same search against the same page, and a signed-in nonprofit should not have
   to learn a second one. */

/* The block is sized for the chip row; the bar inside it is narrower, matching
   the heading above. */
.npf-dash-search {
  width: 820px;
  max-width: 100%;
  margin: 28px auto 0;
}

.npf-dash-search__bar {
  width: 693px;
  max-width: 100%;
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 10px;
  border: 1px solid var(--npf-line-soft);
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 10px 30px rgba(19, 24, 36, 0.06);
  transition: border-color var(--npf-t), box-shadow var(--npf-t);
}

.npf-dash-search__bar:focus-within {
  border-color: var(--npf-primary);
  box-shadow: 0 0 0 3px rgba(79, 132, 195, 0.16);
}

.npf-dash-search__bar input[type="search"] {
  flex: 1;
  min-width: 0;
  height: 44px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  font-family: var(--npf-font-body);
  font-size: 15px;
  color: var(--npf-ink);
  /* The theme skins bare inputs; these keep the field flat inside the pill. */
  box-shadow: none;
  outline: none;
}

.npf-dash-search__bar input[type="search"]::placeholder { color: var(--npf-muted); }

/* The theme prints a generated colour rule —
   `input:focus, select:focus, textarea:focus { border: 1px solid #003366
   !important; box-shadow: … !important }` — in an inline <style>. Inside the
   pill that drew a hard navy rectangle around the field on every click, which
   is what made the search look broken when focused. The focus cue belongs to
   the pill (`:focus-within` above), so the field itself stays flat.
   `!important` is the only thing that outranks an important declaration. */
.npf-dash-search__bar input[type="search"],
.npf-dash-search__bar input[type="search"]:focus {
  border: 0 !important;
  box-shadow: none !important;
  outline: none !important;
}

/* Clear button — revealed by npf-dashboard.js once the field has content. */
.npf-dash-search__clear {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--npf-muted);
  cursor: pointer;
  transition: background var(--npf-t), color var(--npf-t);
}

.npf-dash-search__clear:hover,
.npf-dash-search__clear:focus-visible {
  background: var(--npf-line-soft);
  color: var(--npf-ink);
}

.npf-dash-search__clear svg { width: 16px; height: 16px; }

.npf-dash-search__clear[hidden] { display: none; }

/* Safari draws its own clear affordance; ours replaces it. */
.npf-dash-search__bar input[type="search"]::-webkit-search-decoration,
.npf-dash-search__bar input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

/* Safari draws its own clear affordance inside the rounded field. */
.npf-dash-search__bar input[type="search"]::-webkit-search-decoration,
.npf-dash-search__bar input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.npf-dash-search__bar .npf-btn {
  flex: 0 0 auto;
  width: auto;
  min-width: 116px;
  height: 44px;
  padding: 0 26px;
  border-radius: 999px;
  font-size: 15px;
}

/* Uses the block's full width — wider than the bar — so the four measured
   category names usually sit on one line. It still wraps: the labels come from
   whichever categories have the most freelancers, so their length is not fixed. */
.npf-dash-search__tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 16px;
}

.npf-dash-search__tags .npf-chip {
  display: inline-flex;
  align-items: center;
  padding: 8px 18px;
  border: 1px solid var(--npf-line-soft);
  border-radius: 999px;
  background: #fff;
  font-family: var(--npf-font-body);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  color: var(--npf-ink);
  text-decoration: none;
  transition: border-color var(--npf-t), background var(--npf-t), color var(--npf-t);
}

.npf-dash-search__tags .npf-chip:hover,
.npf-dash-search__tags .npf-chip:focus-visible {
  border-color: var(--npf-primary);
  background: var(--npf-primary-soft);
  color: var(--npf-primary-dark);
  text-decoration: none;
}

@media (max-width: 560px) {
  .npf-dash-search__bar {
    padding: 8px;
  }

  .npf-dash-search__bar .npf-btn {
    min-width: 0;
    padding: 0 18px;
  }
}

/* list-your-services callout — 506px column.
   The design puts the 52px gap on the h1's margin-bottom; it lives here
   instead so the heading rule (whose size is deliberately reduced from the
   design's 72px) stays untouched. */
.npf-list-cta {
  text-align: center;
  width: 506px;
  max-width: 100%;
  margin: 52px auto 0;
}

.npf-list-cta__art {
  display: block;
  width: 242px;
  max-width: 100%;
  height: auto;
  margin: 0 auto 18px;
}

/* M3 display/small-emphasized: 36/44 */
.npf-list-cta__title {
  font-family: var(--npf-font-headline);
  font-weight: 500;
  font-size: 36px;
  line-height: 44px;
  color: var(--npf-ink);
  margin: 0 0 10px;
}

.npf-list-cta__text {
  color: var(--npf-muted);
  font-size: 14px;
  line-height: 23px;
  margin: 0 auto 26px;
}

.npf-dash .npf-list-cta .npf-btn { width: 226px; max-width: 100%; }

/* ---------- Panels ---------- */

.npf-panel {
  background: #fff;
  border: 1px solid var(--npf-primary);
  border-radius: 7px;
  padding: 26px 38px;
  box-shadow: var(--npf-shadow-panel);
}

.npf-panel--grid { padding-inline: 22px; }

.npf-panel__title {
  font-family: var(--npf-font-headline);
  font-weight: 400;
  font-size: 24px;
  line-height: 30px;
  color: var(--npf-ink);
  margin: 0 0 32px;
}

/* ---------- Recommended grid — theme's [job_listings_3] cards ---------- */

/* The theme renders: ul.listing-job > li.layout_jobs > div.row.ui.three
   > div.ui.card — not a .ui.grid. Semantic's column sizing does not apply
   outside a .ui.grid parent, so the cards were each taking the full row
   width and pushing the panel 200px past the viewport. */

.npf-panel { min-width: 0; }

.npf-recommend,
.npf-recommend > * { max-width: 100%; }

.npf-recommend ul.listing-job {
  margin: 0;
  padding: 0;
  list-style: none;
}

.npf-recommend li.layout_jobs {
  margin: 0;
  padding: 0;
  list-style: none;
}

.npf-recommend .row.ui,
.npf-recommend .wpj-load-more-target {
  display: grid !important;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 14.6px;
  row-gap: 35px;
  margin: 0 !important;
  padding: 0 !important;
  width: 100% !important;
}

/* ---------- Expert card ----------
   The theme's card markup is reshaped into the design's .expert-card:

     div.image                      -> media box (fills the card top)
       div.wpj-carousel                 the service image slider
     div.content.flex-parent        -> small author row under the image
       img.iscu_listings_user_badge -> tier badge, moved onto the image
     div.iscu_listings_user_points  -> star rating, moved onto the image
     div.cards-title
       a.list-header                -> the bold title
       div.desc                     -> the muted sub-line

   Nothing is added or removed - only repositioned and restyled. */

.npf-recommend .ui.card,
.npf-recommend .job-card {
  position: relative;
  width: 100% !important;
  min-width: 0 !important;
  margin: 0 !important;
  border: 1px solid #e4e4e4 !important;
  border-radius: 14.6px !important;
  padding: 4.561px !important;
  box-shadow: none !important;
  background: #fff !important;
  overflow: hidden;
  transition: background var(--npf-t), border-color var(--npf-t);
}

/* Hover = the design's highlighted card (.expert-card.is-active): the body
   turns primary-light. No movement — the design also lifts the card 6px, but
   that shift is deliberately not carried over.

   What does NOT change on hover follows the design's own cascade, where
   .recommend-grid's rules outrank .is-active's:
     .recommend-grid .expert-card.is-active { border-color:#e4e4e4 }  -> neutral border
     .recommend-grid .expert-card h3        (0,3,1) beats
     .expert-card.is-active h3              (0,2,1)  -> title stays ink
     .recommend-grid .expert-card.is-active .tag { background: primary-soft }
   Only the sub-line flips, because there .is-active is the more specific of
   the two. */
.npf-recommend .ui.card:hover,
.npf-recommend .job-card:hover {
  background: var(--npf-primary-light) !important;
  border-color: #e4e4e4 !important;
}

.npf-recommend .ui.card:hover .iscu_listings_years_of_experience {
  color: rgba(255, 255, 255, 0.9);
}

/* Media - square-ish, rounded, image fills it.
   The theme positions .image absolutely, which laid it over the title and
   sub-line flowing underneath. It has to sit in normal flow here, and the
   rule that sets it is ID-scoped, so this one is too. */
.npf-dash #job_listings .ui.card > .image,
#job_listings .npf-recommend .ui.card > .image,
#npf-profile-jobs.npf-recommend .ui.card > .image,
.npf-recommend .ui.card > .image {
  position: relative !important;
  top: auto !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  aspect-ratio: 1.03 / 1;
  overflow: hidden;
  border-radius: 14.6px !important;

  /* The same backdrop the Top Rated Experts cards use.
     These photos are remove.bg cut-outs and are sized `contain`, so the box
     shows through around and behind every subject — it *is* the photo's
     background. It used to be left as the card's white, which is why a cut-out
     here read as floating in nothing while the same person on the home page sat
     on the brand tint. `--npf-primary-soft` is the dashboard's own token for
     that colour, and it matches `--primary-soft` on the expert cards.

     This is the canonical job-card treatment: npf-search.css mirrors it so the
     listing pages render the same card. */
  background: var(--npf-primary-soft, #e1eeff);
}

/* The card is a flex container in the theme; stack its rows. */
.npf-dash #job_listings .ui.card,
.npf-recommend .ui.card {
  display: flex !important;
  flex-direction: column;
  height: auto !important;
}

.npf-recommend .ui.card > .image .wpj-carousel,
.npf-recommend .ui.card > .image .owl-stage-outer,
.npf-recommend .ui.card > .image .owl-stage,
.npf-recommend .ui.card > .image .owl-item,
.npf-recommend .ui.card > .image .owl-item > * {
  height: 100% !important;
}

/* The slider track carries the white behind the photo. It sits inside .image
   and outside the card's own background, so the cut-out portraits keep a white
   backdrop even while the card body turns primary-light on hover. */
.npf-recommend .ui.card > .image .owl-stage-outer {
  background: #fff;
}

/* The image sits behind an ID rule (iscu-public.css:235):
     #job_listings .ui.card > .image img {
       width:145px!important; height:145px!important; border-radius:75%!important;
       left:50%!important; translate:-50%; border:1px solid …; background-color:#acbdc5;
     }
   which renders it as a circular avatar on a slate wash. An ID beats any class
   selector even when both are !important, so these selectors carry an ID of
   their own — and every one of those declarations has to be answered, not just
   the size. The #acbdc5 read as a thin rim around the 145px circle; across a
   full-bleed media box it floods the card behind any logo with transparency,
   which is the "extra background colour" on the photo. */
.npf-dash #job_listings .ui.card > .image img:not(.iscu_listings_user_badge),
#job_listings .npf-recommend .ui.card > .image img:not(.iscu_listings_user_badge),
#npf-profile-jobs.npf-recommend .ui.card > .image img:not(.iscu_listings_user_badge),
.npf-recommend .ui.card > .image img:not(.iscu_listings_user_badge) {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  object-fit: cover;
  border: 0 !important;
  border-radius: 0 !important;
  left: auto !important;
  translate: none;
  /* The ID rule's `background-color: #acbdc5` is deliberately NOT answered: it
     is the slate wash the cut-outs stand on, and it is part of this card's
     look. npf-search.css sets the same colour explicitly, because that ID rule
     does not reach the listing pages. */
  /* background-color: transparent !important; */
  transition: none;

  /* These <img> elements carry NO src — the theme paints the photo through an
     inline background-image, and that inline style also picks the fit:
     `contain` when the source is taller than it is wide, `cover` otherwise,
     anchored to `bottom`. `cover` is what cropped the heads: a wide source
     scaled to fill a 1.03:1 box overflows vertically, and anchoring the
     overflow to the bottom throws away the top — where the face is.
     `contain` fits the whole source every time, so nothing is ever cut off.
     Position is left to the inline style, which stands the subject on the
     bottom edge. Most of these photos are cut-outs on transparency, so the
     letterboxing `contain` leaves is invisible. */
  background-size: contain !important;
  font-size: 0;
  color: transparent;
  text-indent: -9999px;
}

/* …but font-size/text-indent only suppress the ALT TEXT. The theme emits
   `<img src="" style="background-image:url(…)">` (functions-single-job.php —
   the src/data-src echoes are commented out), and Chrome paints its own
   broken-image raster for an empty src, which is the grey glyph that showed
   in the corner of every card. That raster is the element's replaced content,
   so the only way to drop it is to replace the content itself — a transparent
   1x1 GIF. Scoped to [src=""] so the slides that DO carry a real src (the
   review-work-sample branch, and the placeholder) are left alone. */
.npf-dash #job_listings .ui.card > .image img[src=""],
#job_listings .npf-recommend .ui.card > .image img[src=""],
#npf-profile-jobs.npf-recommend .ui.card > .image img[src=""],
.npf-recommend .ui.card > .image img[src=""] {
  content: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}

/* Owl wraps the image in <a><div>; both need full height for object-fit. */
.npf-recommend .ui.card > .image .owl-item > a,
.npf-recommend .ui.card > .image .owl-item > a > div,
.npf-recommend .ui.card > .image .owl-item a,
.npf-recommend .ui.card > .image .owl-item a > div {
  display: block;
  width: 100%;
  height: 100%;
}

/* Tier badge — npf-dashboard.js moves it out of the author row into .image, so
   it falls under the same ID rule as the photo (iscu-public.css:235) and needs
   every one of that rule's declarations answered. `left: 50% !important` plus
   `translate: -50%` is what pinned the badge to the TOP CENTRE of the card;
   `right` alone cannot win against an !important `left`, so `left` is reset
   here and the translate cleared. The 145px box, the 75% radius, the border
   and the #acbdc5 fill are undone for the same reason.

   Semantic UI adds a SECOND centring pass on top of that one — front.min.css
   carries `.ui.card > .image img { top: 50%; transform: translateY(-50%) }`.
   Overriding `top` does not disable the transform, so the badge was still
   being pulled up half its own height (29.7px) and the media box's
   overflow:hidden sliced its laurels off. Hence `transform: none`.
   Design values: 50x60 at top 14.6 / right 15 (.recommend-grid .expert-card__badge). */
/* The tier shield is no longer shown on cards at all — it ranked freelancers by
   a level the platform assigns, in the corner of a card a nonprofit reads as a
   quality mark. Hidden rather than unhooked from the markup: the badge is
   printed by the child theme's job-card template and moved here by
   npf-dashboard.js, so hiding it in the one place both of those converge keeps
   this to a single rule and leaves the third-party template alone.

   The positioning below is kept, commented-in, so restoring the badge is a
   matter of deleting the display rule. */
.npf-dash #job_listings .ui.card .iscu_listings_user_badge,
#job_listings .npf-recommend .ui.card .iscu_listings_user_badge,
#npf-profile-jobs.npf-recommend .ui.card .iscu_listings_user_badge,
.npf-recommend .iscu_listings_user_badge {
  display: none !important;
}

.npf-dash #job_listings .ui.card > .image img.iscu_listings_user_badge,
#job_listings .npf-recommend .ui.card > .image img.iscu_listings_user_badge,
#npf-profile-jobs.npf-recommend .ui.card > .image img.iscu_listings_user_badge,
.npf-recommend .iscu_listings_user_badge {
  position: absolute;
  top: 14.6px;
  right: 15px;
  left: auto !important;
  bottom: auto !important;
  translate: none;
  transform: none !important;
  z-index: 3;
  width: 50px !important;
  height: auto !important;
  max-width: none !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  object-fit: contain;
  pointer-events: none;
}

/* Star rating - white chip on the image. npf-dashboard.js reparents this node
   into .image first; absolute positioning then resolves against the media box.
   Geometry from .recommend-grid .expert-card__rating: 34.7px tall, 7.3px
   radius, bottom/right 11. */
.npf-recommend .image .iscu_listings_user_points,
.npf-recommend .iscu_listings_user_points {
  position: absolute;
  bottom: 11px;
  right: 11px;
  z-index: 3;
  display: flex;
  align-items: center;
  height: 34.7px;
  width: auto !important;
  margin: 0 !important;
  padding: 0 10px !important;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(19, 24, 36, 0.12);
  line-height: 1;

  /* iscu_get_points_html() used to return the stars followed by a bare
     " Verified" text node, which had no element to hide — hence the zeroed
     font-size, with the star row below restoring one. NPF_Claims now rewrites
     that whole node into `.npf-explevel`, so the loose text is gone and the
     label sets its own size; this stays as the guard for any other stray text
     the plugin might append. */
  font-size: 0;

  /* The chip carries a label now, so it has to be allowed to grow — and to stop
     growing before it runs off the card. */
  max-width: calc(100% - 22px);
  flex-wrap: wrap;
  height: auto;
  min-height: 34.7px;
  padding: 5px 10px !important;
  gap: 4px;
}

.npf-recommend .iscu_listings_user_points .npf-explevel__label { font-size: 12.5px; }
.npf-recommend .iscu_listings_user_points .npf-explevel { gap: 4px; }

.npf-recommend .iscu_listings_user_points .wpj-star-rating-static {
  margin: 0;
  font-size: 15px;
  white-space: nowrap;
}

.npf-recommend .iscu_listings_user_points i.star { font-size: 15px; margin: 0 1px; }

.npf-recommend .card-image-icons { position: absolute; bottom: 10px; left: 12px; z-index: 3; }

/* Author row (avatar + seller name + level) — and, sharing the same class,
   the "Rating & Featured" and "Favorites & Price" rows.
   The design's card body is tags -> title -> sub-line with none of them, so
   they are hidden rather than restyled — same treatment as .description above.
   All three are still in the markup and come straight back if this rule is
   deleted. npf-dashboard.js lifts the tier badge and the favourite heart out
   first, so nothing that is wanted goes down with them. */
.npf-recommend .ui.card > .content.flex-parent { display: none !important; }

/* The theme indents the title and description by .75em inside .cards-title
   (cards.css:139 `margin: 0 .75em`), which the design does not. */
.wpj-card-style-3.ui.card .cards-title.list-70-right .description,
.wpj-card-style-3.ui.card .cards-title.list-70-right .list-header {
  margin-left: 0px;
}

/* Body — .cards-title carries the JS-built tag row and the title, and the
   experience line follows it as a sibling. Together they are the design's
   .expert-card__body: 27.4px 6px 31.9px. */
.npf-recommend .ui.card .cards-title {
  width: 100% !important;
  padding: 27.4px 6px 0 !important;
  margin: 0 !important;
  border: 0 !important;
}

/* One line, truncated. Service titles are the seller's own words and run to any
   length — "Mini Fundraising Audit: Fastest-Win Relationship Edition" takes
   two — and the theme reserves two lines for every card whether or not they are
   used: cards.css:139 gives this element `height: 42px; overflow: hidden`, a
   fixed two-line box at its 20px line-height. So `nowrap` alone would leave a
   blank second line under every title. `height: auto` releases the box; the
   ellipsis then says the title continues, and the full text is one click away
   on the service page.

   The theme's selector is five classes and this one matches it, so the
   `height` is decided by source order — hence !important, which states the
   intent rather than relying on which stylesheet the site happens to print
   last. */
/* The `.wpj-card-style-3` selector is carried alongside the plain one because
   the theme sets the title from
   `.wpj-card-style-3.ui.card .cards-title.list-70-right .list-header`
   (cards.css) — five classes to this rule's four, so the design's 18.243px/600
   navy lost to the theme's 16px/400 grey and "Recommended for you" ended up
   with a lighter title than the identical card on /search-jobs/, where
   npf-search.css happens to match that count. */
.npf-recommend .ui.card .cards-title .list-header,
.npf-recommend .wpj-card-style-3.ui.card .cards-title.list-70-right .list-header {
  display: block;
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: 16px;
  line-height: 22px;
  color: var(--npf-ink);
  height: auto !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.npf-recommend .ui.card .cards-title .list-header:hover { color: var(--npf-primary); }

/* The muted sub-line is .iscu_listings_years_of_experience, not .desc. It is a
   SIBLING of .cards-title, so it carries the body's side and bottom padding. */
.npf-recommend .ui.card .iscu_listings_years_of_experience,
.npf-recommend .ui.card .cards-title .desc {
  color: var(--npf-muted);
  font-size: 14px;
  line-height: 23px;
  margin-top: 10.9px;
}

/* Experience line + favourite heart share this row: text left, heart right.
   npf-dashboard.js moves .upb_add_remove_links in here out of the card's
   hidden "Favorites & Price" row. */
.npf-recommend .ui.card > .iscu_listings_years_of_experience {
  /* 6px matches .cards-title's own padding, so the text lines up with the
     title above it and the heart sits 6px off the card's inner edge. */
  padding: 0px 6px;
  /* Padding alone still left the row inset — the theme gives this div
     `margin: … 18px …`, which is what was actually pushing it in. */
  margin-left: 0;
  margin-right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.npf-recommend .upb_add_remove_links {
  flex: none;
  margin: 0;
  line-height: 1;
}

.npf-recommend .upb_add_remove_links a {
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

.npf-recommend .upb_add_remove_links i.heart.icon {
  font-size: 18px;
  width: auto;
  margin: 0;
}

/* The <a> wraps both a themed .full-heart/.empty-heart div and the <i> glyph
   this card was asked for; only the glyph is wanted, so the div is dropped
   rather than risking two hearts stacked. */
.npf-recommend .upb_add_remove_links .full-heart,
.npf-recommend .upb_add_remove_links .empty-heart { display: none; }

/* The long service description has no slot in the design's card, which shows
   only tags, a title and one muted line. Hidden, not removed — it is still in
   the markup and returns the moment the plugin is deactivated.
   `!important` is required: the theme's view-switch rule
   `.list-grid .visible-on-list { display: block }` is itself !important. */
.npf-recommend .ui.card .description,
.npf-recommend .ui.card .description.visible-on-list { display: none !important; }

/* No list-view exception: the theme ships this listing with `.list-grid`
   already on the wrapper, so an exception scoped to it simply undid the hide.
   The design defines one card layout, so the description stays hidden in both
   states. See the note about the grid/list switch below. */

/* Tag row above the title, built by npf-dashboard.js from the card's own
   service permalink. Matches the design's .expert-card__tags / .tag. */
.npf-recommend .npf-card-tags {
  display: flex;
  gap: 5.5px;
  flex-wrap: wrap;
  margin-bottom: 10.9px;
}

.npf-recommend .npf-tag {
  display: inline-flex;
  align-items: center;
  height: 23.7px;
  padding: 0 9.1px;
  border-radius: 999px;
  background: var(--npf-primary-soft);
  color: var(--npf-muted);
  font-family: var(--npf-font-body);
  font-weight: 500;
  font-size: 12px;
  line-height: 18px;
  white-space: nowrap;
}

/* Grid / list view switch — the design has one card layout, so the toggle has
   nothing to toggle between (the list view's only extra, .description, is
   hidden in both states further up). Hidden rather than unhooked from the
   template: load-more.js:7 tests
   `$('.load-more-button.wpj-load-more').parent().siblings().hasClass('grid-switch-absolute')`
   to decide where to append the next page, so the node has to stay in the DOM
   or Load More stops working. */
.npf-recommend .grid-switch-absolute { display: none !important; }

.npf-recommend img { border-radius: 14.6px; }

/* Load More — the theme's own control, restyled to the page's .npf-btn
   (the "Ask a Question" / "My Profile" pill): same 54px height, 0 24px
   padding, 226px width, 16px/20px Inter 600, sentence case, 6px radius.

   The theme takes it OUT OF FLOW — `position:absolute; left:0; right:0;
   bottom:0` with `margin-bottom:-115px` — so it hangs 115px below the card
   grid and the panel never grows to hold it. The panel only appeared to
   contain it because .mb75 happens to reserve 75px underneath; at a narrower
   width that coincidence breaks and the button escapes the panel. Put back in
   flow so it simply follows the last row of cards.

   `relative`, not `static`: the "there is more…" artwork is a ::before on this
   element, and dropping to static would hand it a different containing block
   and fling it across the panel. */
.npf-recommend .load-more-button,
.npf-recommend .wpj-load-more,
.npf-recommend .load-more {
  position: relative;
  inset: auto;
  /* 226px is the width .npf-side-card--action .npf-btn resolves to, and it
     leaves the auto margins something to centre. No box-sizing here on
     purpose: .npf-btn does not set one either, so both pills measure their
     padding the same way whatever the page's default turns out to be. */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 226px;
  min-width: 0;
  max-width: 100%;
  height: 54px;
  padding: 0 22px;
  margin: 32px auto 0;
  /* front.min.css: `.load-more-button { margin-bottom: -115px !important }`.
     Even in flow that negative margin shrinks the space the button occupies,
     so its parent still ends 115px above it and it spills out of the panel.
     Nothing but !important can answer it. */
  margin-bottom: 0 !important;
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
  white-space: nowrap;
  text-transform: none;
  letter-spacing: normal;
  color: #fff;
  background: var(--npf-primary);
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  transition: background var(--npf-t), transform var(--npf-t);
}

.npf-recommend .load-more-button:hover,
.npf-recommend .wpj-load-more:hover,
.npf-recommend .load-more:hover {
  background: var(--npf-primary-dark);
  transform: translateY(-2px);
}

/* Loading state.

   The theme's spinner is a background-image (notifications-loading.gif) that
   .loading slides from `-200px center` into view, while the label is pushed
   away by `text-indent: -999999px`. The `background` shorthand above drops
   that image — which is why a click used to leave an empty blue rectangle —
   and a dark GIF on a blue fill would barely read anyway.

   So the state is rebuilt here: the label is hidden with a transparent colour
   (text-indent reset, or it drags the ::after a million pixels sideways) and a
   white ring is drawn in ::after. Absolutely positioned, so it centres itself
   without the padding shim the old rule used. */
.npf-recommend .load-more-button.loading,
.npf-recommend .wpj-load-more.loading {
  color: transparent;
  text-indent: 0;
  transform: none;
}

.npf-recommend .load-more-button.loading::after,
.npf-recommend .wpj-load-more.loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  box-sizing: border-box;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: npf-load-more-spin 0.7s linear infinite;
}

@keyframes npf-load-more-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .npf-recommend .load-more-button.loading::after,
  .npf-recommend .wpj-load-more.loading::after { animation-duration: 2.4s; }
}

/* .mb75 reserved 75px under the grid for the out-of-flow button. The button
   now takes its own space, so that is just a second gap — 75px of dead room
   between it and the panel's 42px padding. !important because the theme's
   utility class declares it that way. */
.npf-recommend .mb75 { margin-bottom: 0 !important; }

/* ---------- CTA banner ---------- */

/* .cta — padding-block 96/72, background var(--primary), decorative circles */
.npf-cta {
  position: relative;
  padding-block: 96px 72px;
  background: var(--npf-primary);
  color: #fff;
  overflow: hidden;
  text-align: center;
}

.npf-cta::before,
.npf-cta::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.npf-cta::before {
  width: 340px;
  height: 340px;
  top: -258px;
  right: -96px;
  background: var(--npf-primary-light);
}

.npf-cta::after {
  width: 470px;
  height: 470px;
  bottom: -300px;
  left: -215px;
  background: var(--npf-primary-light);
}

.npf-cta__ring {
  position: absolute;
  width: 470px;
  height: 470px;
  top: -318px;
  right: -156px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.28);
  pointer-events: none;
}

.npf-cta__ring--bl {
  top: auto;
  right: auto;
  width: 620px;
  height: 620px;
  bottom: -378px;
  left: -290px;
}

.npf-cta__inner { position: relative; z-index: 1; }

.npf-cta h2 {
  color: #fff;
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: clamp(2.2rem, 4.6vw, 3.4rem);
  line-height: 1.16;
  letter-spacing: -0.025em;
  max-width: 780px;
  margin: 0 auto;
}

.npf-cta p {
  color: rgba(255, 255, 255, 0.9);
  margin: 18px auto 0;
  max-width: 600px;
  font-size: 1rem;
  line-height: 26px;
}

/* .ask-bar */
.npf-ask-bar {
  display: flex;
  gap: 10px;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 10px;
  padding: 2px;
  max-width: 522px;
  margin: 24px auto 0;
  transition: border-color var(--npf-t), background var(--npf-t);
}

.npf-ask-bar:focus-within {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.22);
}

.npf-ask-bar input {
  flex: 1;
  min-width: 0;
  height: auto;
  border: none;
  outline: none;
  background: transparent;
  color: #fff;
  font-family: var(--npf-font-body);
  font-size: 1rem;
  padding: 12px 18px;
  box-shadow: none;
}

.npf-ask-bar input::placeholder { color: rgba(255, 255, 255, 0.75); }

.npf-dash .npf-ask-bar .npf-btn {
  background: #fff;
  color: var(--npf-primary-dark);
  height: auto;
  padding: 14px 22px;
  border-radius: 8px;
  white-space: nowrap;
}

.npf-dash .npf-ask-bar .npf-btn:hover {
  background: #f0f4fa;
  color: var(--npf-primary-dark);
  box-shadow: none;
  transform: none;
}

/* The band's own button, now that the ask input it used to sit inside is gone.
   Same declarations as the ask bar gave it, so the colour, padding and radius
   are unchanged — only what it sits next to. */
.npf-dash .npf-cta__btn {
  background: #fff;
  color: var(--npf-primary-dark);
  height: auto;
  padding: 14px 22px;
  border-radius: 8px;
  white-space: nowrap;
  margin-top: 28px;
}

.npf-dash .npf-cta__btn:hover {
  background: #f0f4fa;
  color: var(--npf-primary-dark);
  box-shadow: none;
  transform: none;
}

/* .cta__features — gap 48, 46px white chips */
.npf-cta__features {
  display: flex;
  justify-content: center;
  gap: 48px;
  flex-wrap: wrap;
  margin-top: 44px;
}

.npf-cta__feature {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--npf-font-body);
  font-weight: 600;
  color: #fff;
}

.npf-cta__feature .npf-icon-chip {
  width: 46px;
  height: 46px;
  background: #fff;
  color: var(--npf-primary);
  border-radius: 12px;
}

.npf-icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

.npf-cta__feature .npf-icon-chip svg { width: 22px; height: 22px; }

/* ---------- Free resources ---------- */

.npf-dash__resources {
  background: #fff;
  padding-block: 80px;
}

/* [home_latest_blogs] renders a 1200px section inside the 1248px container,
   so it sat 48px off-centre against everything above it. */
.homepage-blog-preview {
  margin: 0 auto !important;
}

/* ---------- Responsive ---------- */

/* Breakpoints follow the reference sheet: 1024 / 860 / 560. */

/* The reference scales the welcome h1 DOWN from 72px desktop to 36px mobile.
   Here the desktop size is already 40px (deliberately reduced), so the old
   clamps — min 3rem at 1024, max 3rem at 860 — would have scaled it UP to
   48px on tablets. No font-size override until 560, where the reference's
   36px is genuinely smaller. */

@media (max-width: 1024px) {
  .npf-dash__layout { grid-template-columns: 300px minmax(0, 1fr); column-gap: 30px; }
  .npf-recommend .row.ui,
  .npf-recommend .wpj-load-more-target { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  .npf-dash { padding-top: 60px; }

  /* Mobile order is welcome -> sidebar cards -> panels -> Recently Viewed.
     Grid areas can't express that: the sidebar is one area, and Recently
     Viewed has to break out of it and land after the panels. So the layout
     becomes a flex column and the aside becomes `display: contents`, which
     dissolves it as a box and promotes its cards to flex items in their own
     right — only then can `order` move one of them past .npf-dash__main.
     The aside's own 30px gap goes with it, hence the gap here. */
  .npf-dash__layout {
    display: flex;
    flex-direction: column;
    gap: 30px;
    padding-bottom: 60px;
    /* The desktop rule's `align-items: start` is a BLOCK-axis alignment under
       grid, but the cross (horizontal) axis once this is a column flex — it
       would shrink every card to its content width. */
    align-items: stretch;
  }

  .npf-dash__side { display: contents; }

  .npf-dash__welcome { order: 1; }
  .npf-profile-card,
  .npf-side-card { order: 2; }
  .npf-dash__main { order: 3; }

  /* Recently Viewed (and the recently-bought card that shares its class)
     move below "Recommended for you". */
  .npf-side-card--recent { order: 4; }

  .npf-dash__welcome { margin-bottom: 0; }

  .npf-dash__welcome h1 {
    line-height: 1.15;
    letter-spacing: -1px;
    width: 100%;
  }

  .npf-list-cta { margin-top: 32px; }
  .npf-list-cta__art { width: 200px; }
  .npf-list-cta__title { font-size: 28px; line-height: 36px; }

  .npf-panel { padding: 32px 24px; }
  .npf-panel--grid { padding-inline: 12px; }
  .npf-panel__title { font-size: 24px; line-height: 32px; margin-bottom: 24px; }

  .npf-recent .recently-v-box { gap: 14px; }

  .npf-recommend .row.ui,
  .npf-recommend .wpj-load-more-target {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 9px;
    row-gap: 19px;
  }

  /* The "there is more…" artwork is a 210x86 ::before pinned 190px to the LEFT
     of the button. Centred in a phone-width panel that starts well outside the
     card, so it goes; the button keeps its own spacing. */
  .npf-recommend .load-more-button::before,
  .npf-recommend .wpj-load-more::before { display: none; }

  /* Same 226px cap the sidebar's .npf-btn keeps at this width, but allowed to
     shrink with a narrow panel. */
  .npf-recommend .load-more-button,
  .npf-recommend .wpj-load-more,
  .npf-recommend .load-more {
    width: 100%;
    max-width: 226px;
    margin-top: 24px;
  }

  .npf-cta { padding-block: 64px 56px; }
  .npf-cta::before { width: 190px; height: 190px; top: -142px; right: -52px; }
  .npf-cta::after { width: 260px; height: 260px; bottom: -166px; left: -118px; }
  .npf-cta__ring { width: 260px; height: 260px; top: -176px; right: -86px; }
  .npf-cta__ring--bl { width: 340px; height: 340px; bottom: -208px; left: -160px; }
  .npf-ask-bar input { padding: 12px 14px; }
  .npf-dash .npf-ask-bar .npf-btn { padding-inline: 20px; }

  /* Design stacks the features left-aligned in a centred column. */
  .npf-cta__features {
    flex-direction: column;
    align-items: flex-start;
    gap: 22px;
    max-width: 560px;
    margin-inline: auto;
  }
  .npf-dash__resources { padding-block: 48px; }
}

@media (max-width: 560px) {
  /* Reference mobile heading size. */
  .npf-dash__welcome h1 { font-size: 36px; }

  /* No profile-card / side-card overrides here. The reference carries none —
     .profile-card, .side-card and .side-card__title hold their desktop values
     at every width (avatar 72, name 16/20, balance 16/26, card padding 32/33,
     title 28/36), and the card is only ~309px wide even in a 375px frame. The
     22/30 title and squeezed paddings that used to sit here were this
     stylesheet's own invention, not the design's. */

  /* Recently viewed — smaller thumbnails. */
  .npf-recent .recently-v-box { gap: 12px; padding-bottom: 14px; margin-bottom: 14px; }
  .npf-recent .recently-v-box .image,
  .npf-recent img { width: 56px; height: 56px; }
  .npf-recent h5,
  .npf-recent h5 a,
  .npf-recent a { font-size: 0.92rem; line-height: 1.4; }

  /* ---- Expert cards stay 2-up at 375px, as in the reference ----
     The cards are only ~159px wide there, so the whole body steps down hard
     to keep each tag on one line. Sizes are the reference's, mapped onto the
     theme's own class names:
       .expert-card__body   -> .cards-title + .iscu_listings_years_of_experience
       .expert-card__tags   -> .npf-card-tags   .tag -> .npf-tag
       .expert-card h3      -> .cards-title .list-header
       .expert-card__role   -> .iscu_listings_years_of_experience
       .expert-card__rating -> .iscu_listings_user_points
       .expert-card__badge  -> .iscu_listings_user_badge
     Each one has to out-specify the desktop rule above it, hence the repeated
     .npf-recommend .ui.card prefix. */
  .npf-recommend .row.ui,
  .npf-recommend .wpj-load-more-target {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .npf-recommend .ui.card .cards-title { padding: 18px 7px 0 !important; }
  .npf-recommend .ui.card > .iscu_listings_years_of_experience { padding: 0 7px 14px; }

  .npf-recommend .npf-card-tags { gap: 5px; flex-wrap: nowrap; margin-bottom: 7px; }

  .npf-recommend .npf-tag {
    height: auto;
    font-size: 0.472rem;
    line-height: 1;
    padding: 3.4px 5.5px;
    white-space: nowrap;
  }

  /* Title to a single line with an ellipsis.
     In a ~150px column the theme's own sizing runs the title to three or four
     lines, and cards.css:153
       `.list-grid .wpj-card-style-3.ui.card .cards-title.list-70-right .list-header
        { height: 60px; line-height: 16px; margin-bottom: -20px }`
     then makes it collide with the experience row: the negative margin shortens
     the box by 20px while the text still occupies its full height, so the
     overflow lands straight on top of "10+ Years of Experience".
     `height: auto` + `margin-bottom: 0` undo that, and nowrap/ellipsis gives
     the single line. Everything is !important because that theme selector
     carries seven classes and out-specifies anything scoped to .npf-recommend
     — which is also why the plain 0.7rem here never took effect. */
  .npf-recommend .ui.card .cards-title .list-header {
    height: auto !important;
    margin-bottom: 0 !important;
    font-size: 0.7rem !important;
    line-height: 1.3 !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .npf-recommend .ui.card .iscu_listings_years_of_experience,
  .npf-recommend .ui.card .cards-title .desc {
    font-size: 0.55rem;
    line-height: 1.4;
    margin-top: 8px;
  }

  .npf-recommend .image .iscu_listings_user_points,
  .npf-recommend .iscu_listings_user_points {
    height: auto;
    padding: 4px 6px !important;
    bottom: 7px;
    right: 7px;
  }

  .npf-recommend .iscu_listings_user_points .wpj-star-rating-static,
  .npf-recommend .iscu_listings_user_points i.star { font-size: 0.72rem; }

  .npf-dash #job_listings .ui.card > .image img.iscu_listings_user_badge,
  #job_listings .npf-recommend .ui.card > .image img.iscu_listings_user_badge,
#npf-profile-jobs.npf-recommend .ui.card > .image img.iscu_listings_user_badge,
  .npf-recommend .iscu_listings_user_badge {
    width: 26px !important;
    top: 7px;
    right: 8px;
  }
}

/* ==================================================================
   FREE RESOURCES — brought onto the design system.

   `[home_latest_blogs]` (indiasan-customization) prints its own <style> block
   inside the section, hard-coding a palette from before this redesign: a
   #003063 heading, a #0073aa button at 5px radius, #0073aa card titles and a
   1px #ddd border. Next to the rest of the dashboard — #4f84c3 primary, 6px
   button radius, Roboto headings — it read as a different site.

   The shortcode is left completely alone. Its markup, its query and its inline
   style all still render; the rules below simply outrank them.

   Specificity is the whole trick here. That <style> lives in the BODY, after
   this stylesheet in the document, so at equal weight it wins on source order.
   Scoping every selector under `.npf-dash__resources` makes each rule one class
   heavier than the shortcode's, which settles it without !important.
   ================================================================== */

.npf-dash__resources .homepage-blog-preview {
  max-width: none;
  margin: 0;
  padding: 0;
}

/* ---------- Head: title + button ---------- */

.npf-dash__resources .resources-top-bar {
  margin-bottom: 32px;
}

/* Matched to .npf-panel__title, the heading used everywhere else on this
   page. The shortcode's `.fancy-underline` bar goes with it — no other
   heading here carries one. */
.npf-dash__resources .resources-heading {
  font-family: var(--npf-font-headline);
  font-weight: 400;
  font-size: 24px;
  line-height: 32px;
  color: var(--npf-ink);
  margin: 0;
}

.npf-dash__resources .resources-heading::after,
.npf-dash__resources .resources-heading::before {
  content: none;
}

/* Matched to .npf-dash .npf-btn. */
.npf-dash__resources .resources-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding: 0 22px;
  font-family: var(--npf-font-body);
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
  color: #fff;
  background: var(--npf-primary);
  border: 0;
  border-radius: 6px;
  text-decoration: none;
  transition: background var(--npf-t), transform var(--npf-t);
}

.npf-dash__resources .resources-button:hover {
  background: var(--npf-primary-dark);
  color: #fff;
  transform: translateY(-2px);
}

/* ---------- Cards ---------- */

/* `auto-fit`, not the shortcode's `auto-fill`. The shortcode always returns
   three posts, and auto-fill kept laying out a fourth, empty 282px track at
   this width — the row stopped 282px short of the container and the cards
   looked orphaned to the left. auto-fit collapses the empty track so the three
   stretch across, and the minmax still reflows them on narrow screens. */
.npf-dash__resources .home-blog-grid {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

.npf-dash__resources .home-blog-item {
  border: 1px solid var(--npf-line-soft);
  border-radius: 12px;
  box-shadow: none;
  transition: border-color var(--npf-t), box-shadow var(--npf-t), transform var(--npf-t);
}

.npf-dash__resources .home-blog-item:hover {
  border-color: var(--npf-primary-tint);
  box-shadow: var(--npf-shadow-panel);
  transform: translateY(-4px);
}

.npf-dash__resources .home-blog-img img {
  height: 208px;
}

/* The titles were link-blue (#0073aa) because the shortcode colours them as
   links. In the design a card title is ink, and only turns primary on hover —
   the same behaviour as every other card on this page. */
.npf-dash__resources .home-blog-item h3 {
  padding: 20px 20px 0;
  font-family: var(--npf-font-headline);
  font-weight: 600;
  font-size: 18px;
  line-height: 26px;
  color: var(--npf-ink);
  transition: color var(--npf-t);
}

.npf-dash__resources .home-blog-item a:hover h3 {
  color: var(--npf-primary);
}

.npf-dash__resources .home-blog-item .excerpt {
  padding: 10px 20px 22px;
  font-family: var(--npf-font-body);
  font-size: 15px;
  line-height: 24px;
  color: var(--npf-muted);
}

/* The whole card is one anchor; the theme underlines links globally. */
.npf-dash__resources .home-blog-item a {
  text-decoration: none;
}

/* ---------- Tier badges, removed ----------
   The bronze / silver / gold / diamond shield is gone from the site: the
   Experience Level stars say the same thing in one system rather than two, and
   a metal tier in the corner of a profile reads as a quality mark the platform
   does not stand behind. Both places it is printed are third-party templates
   (the child theme's job card and indiasan-customization's profile sidebar), so
   it is hidden here rather than cut out of markup that would come back on an
   update. The star rating beside it stays. */
.iscu_user_rating_badge > img,
.iscu_user_rating_badge img[src*="-new-1.png"] {
  display: none !important;
}
