/* ==========================================================================
   Public profile — approved desktop + mobile reference designs (spec §32)

   Sized by its own container, never the viewport: this column sits beside
   the app shell's rail, so a 1440 viewport gives the profile ~1150 and a
   viewport query would size it for space it does not have.

   One DOM, two presentations. The tab strip appears only at phone widths
   and filters sections that are all present in the markup; with no script
   every section stays visible and each tab is a real fragment link.
   ========================================================================== */

.pub {
  container: pub / inline-size;
  display: grid;
  gap: var(--space-5);
  --pub-radius: 16px;
  --pub-tile: #EEEDFD;
}

/* A grid item's min-width is auto, which is min-content — so one wide
   child expands its track past the container and the whole page gains a
   horizontal scrollbar. Every direct child of a grid here is allowed to
   be narrower than its contents; the contents wrap or clip instead. */
.pub > *,
.pub-hero > *,
.pub-banner > *,
.pub-banner__inner > *,
.pub-id > *,
.pub-stats > *,
.pub-stat > *,
.pub__main > *,
.pub__rail > *,
.pub-slot > *,
.pub-card > *,
.pub-card__head > *,
.pub-exp > *,
.pub-exp__panel > *,
.pub-meters > *,
.pub-meter > *,
.pub-timeline > *,
.pub-tl__card > *,
.pub-creds > *,
.pub-cred > *,
.pub-projects > *,
.pub-project > *,
.pub-counts > *,
.pub-communities > *,
.pub-community > * { min-width: 0; }

/* ==========================================================================
   1. Hero — banner, identity, statistics strip
   ========================================================================== */

.pub-hero {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--pub-radius);
  overflow: hidden;
}

/* ---- Banner ------------------------------------------------------------ */

.pub-banner {
  position: relative;
  min-height: clamp(9rem, 6rem + 11cqi, 13.5rem);
  padding: clamp(1.25rem, 0.75rem + 2cqi, 2.25rem);
  display: flex;
  align-items: center;
  color: #FFF;
  background:
    radial-gradient(120% 140% at 88% 20%, rgb(255 214 190 / 55%) 0%, rgb(255 214 190 / 0%) 45%),
    linear-gradient(104deg, #3F6FD8 0%, #6D5EF5 46%, #A78BE8 78%, #E9B9C8 100%);
  isolation: isolate;
}

.pub-banner__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  color: #FFF;
}

/* A member's own cover. The gradient stays underneath as the backstop
   for a slow or failed image, and the scrim keeps the banner's white
   text legible over a photograph of unknown brightness — white on an
   arbitrary image is a contrast failure waiting for the wrong upload. */
.pub-banner__photo {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.pub-banner__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(96deg, rgb(18 20 45 / 78%) 0%, rgb(18 20 45 / 52%) 48%, rgb(18 20 45 / 30%) 100%);
}

/* Drawn templates. The gradient comes from two custom properties the
   renderer sets, so a template is a pair of colours rather than a file
   to download — and the motif is the banner art already there. */
.pub-banner--tpl {
  background: linear-gradient(104deg, var(--pp-from, #3F6FD8) 0%, var(--pp-to, #A78BE8) 100%);
}

.pub-banner--tpl-minimal { color: #2A3356; }
.pub-banner--tpl-minimal .pub-banner__title,
.pub-banner--tpl-minimal .pub-banner__verbs,
.pub-banner--tpl-minimal .pub-banner__quote,
.pub-banner--tpl-minimal .pub-banner__place { color: #1B2340; }

/* Motifs: the skyline is the default art; the others hide or soften it
   so a "minimal" template is actually minimal. */
.pub-banner--tpl-minimal .pub-banner__skyline,
.pub-banner--tpl-gradient .pub-banner__skyline { display: none; }
.pub-banner--tpl-tech .pub-banner__skyline { opacity: .08; }
.pub-banner--tpl-tech .pub-banner__nodes circle,
.pub-banner--tpl-tech .pub-banner__nodes path { opacity: .5; }
.pub-banner--tpl-nature .pub-banner__skyline { opacity: .1; }

.pub-banner__skyline { fill: currentColor; opacity: .18; }
.pub-banner__nodes circle { fill: currentColor; opacity: .35; }
.pub-banner__nodes path { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: .22; }

.pub-banner__inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: clamp(1rem, 0.5rem + 2cqi, 2.5rem);
  width: 100%;
}

.pub-banner__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(1.1rem, 0.75rem + 1.25cqi, 1.65rem);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  text-wrap: balance;
  /* A tagline is a sentence, not the three-word label the reference
     draws, so it is capped rather than allowed to fill the banner. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pub-banner__verbs {
  margin: var(--space-2) 0 0;
  font-size: clamp(0.8rem, 0.72rem + 0.3cqi, 0.95rem);
  font-weight: var(--fw-medium);
  letter-spacing: .04em;
  opacity: .92;
}

.pub-banner__quote {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(0.85rem, 0.75rem + 0.4cqi, 1.05rem);
  font-style: italic;
  line-height: 1.5;
  position: relative;
}

.pub-quote__mark {
  font-family: var(--font-heading);
  font-size: 1.9em;
  line-height: 0;
  vertical-align: -0.35em;
  opacity: .55;
}

.pub-quote__mark--end { vertical-align: -0.5em; }

/* Owner-only background control. Sits top-right of the banner on a
   solid chip rather than plain white text, because it has to stay
   readable over whatever image the member uploaded. */
.pub-banner__edit {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  background: rgb(255 255 255 / 92%);
  color: var(--color-ink);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  border: 1px solid rgb(255 255 255 / 60%);
}

.pub-banner__edit:hover,
.pub-banner__edit:focus-visible { background: #FFF; color: var(--color-primary-text); }

/* The banner's content is vertically centred, so an absolutely
   positioned control in the corner lands on top of it. Only the owner
   sees the control, so only the owner's banner reserves the room. */
.pub-banner--owner .pub-banner__inner { padding-top: 2.25rem; }

.pub-banner__place {
  margin: 0;
  display: grid;
  gap: 2px;
  padding-left: clamp(0.75rem, 2cqi, 1.25rem);
  border-left: 2px solid rgb(255 255 255 / 45%);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: .08em;
  text-transform: uppercase;
  opacity: .9;
}

/* ---- Identity ---------------------------------------------------------- */

.pub-id {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: clamp(1rem, 0.5rem + 1.5cqi, 2rem);
  align-items: start;
  padding: 0 clamp(1rem, 0.6rem + 1.6cqi, 2rem) clamp(1rem, 0.6rem + 1.4cqi, 1.75rem);
}

.pub-id__avatar {
  position: relative;
  width: clamp(5.5rem, 3.5rem + 8cqi, 11rem);
  aspect-ratio: 1;
  margin-top: clamp(-4.25rem, -2.5rem - 5cqi, -2rem);
  border-radius: 50%;
  border: 5px solid var(--color-bg);
  background: var(--color-surface);
  overflow: hidden;
  box-shadow: 0 10px 30px rgb(20 21 43 / 16%);
}

.pub-id__img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pub-id__camera {
  position: absolute;
  right: 4%;
  bottom: 6%;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--color-ink);
  color: #FFF;
  border: 2px solid var(--color-bg);
}

.pub-id__camera .icon { width: 55%; height: 55%; }

.pub-id__main { min-width: 0; padding-top: var(--space-3); }

.pub-badge-pro {
  display: inline-flex;
  width: fit-content;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--space-2);
  padding: 4px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: #FFF;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: .05em;
  text-transform: uppercase;
}

.pub-badge-pro .icon { width: 0.9em; height: 0.9em; }

.pub-id__name {
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 1rem + 1.9cqi, 2.15rem);
  font-weight: var(--fw-bold);
  line-height: 1.15;
  color: var(--color-ink-heading);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.pub-tick {
  display: inline-grid;
  place-items: center;
  width: 0.72em;
  height: 0.72em;
  border-radius: 50%;
  background: var(--color-primary);
  color: #FFF;
  flex: 0 0 auto;
}

.pub-tick .icon { width: 62%; height: 62%; }

.pub-id__roles {
  margin: var(--space-2) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-2);
  font-size: clamp(0.85rem, 0.8rem + 0.25cqi, 1rem);
  color: var(--color-text-muted);
}

.pub-id__roles i { color: var(--color-border); font-style: normal; }

.pub-id__meta {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.pub-id__meta li { display: inline-flex; align-items: center; gap: 6px; }
.pub-id__meta .icon { color: var(--color-primary); flex: 0 0 auto; }

.pub-id__summary {
  margin: var(--space-3) 0 0;
  max-width: 62ch;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--color-ink-soft);
}

/* ---- Actions + social -------------------------------------------------- */

.pub-id__side {
  display: grid;
  justify-items: end;
  gap: var(--space-3);
  padding-top: var(--space-3);
}

.pub-id__actions {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
}

.pub-id__actions .btn { white-space: nowrap; }

.pub-more { display: inline-flex; align-items: center; gap: 4px; }
.pub-more .icon { transition: transform .18s ease; }
.pub-more[aria-expanded="true"] .icon { transform: rotate(90deg); }

.pub-more__menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
  min-width: 13rem;
  display: grid;
  padding: var(--space-2);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px rgb(20 21 43 / 14%);
}

.pub-more__menu[hidden] { display: none; }

.pub-more__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
  min-height: 40px;
}

.pub-more__item:hover,
.pub-more__item:focus-visible { background: var(--color-surface); }
.pub-more__item .icon { color: var(--color-text-muted); flex: 0 0 auto; }

.pub-social {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--space-2);
}

.pub-social__link {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  color: var(--color-ink-soft);
  background: var(--color-bg);
  transition: border-color .15s ease, color .15s ease;
}

.pub-social__link:hover,
.pub-social__link:focus-visible {
  border-color: var(--color-primary);
  color: var(--color-primary-text);
}

/* ---- Statistics strip -------------------------------------------------- */

.pub-stats {
  list-style: none;
  margin: 0;
  padding: clamp(0.75rem, 0.5rem + 0.7cqi, 1.15rem) clamp(1rem, 0.6rem + 1.6cqi, 2rem);
  border-top: 1px solid var(--color-border);
  background: var(--color-bg);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: var(--space-3);
}

.pub-stat {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-left: var(--space-4);
  border-left: 1px solid var(--color-border);
}

.pub-stat:first-child { border-left: 0; padding-left: 0; }

.pub-stat__mark {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 12px;
  background: var(--pub-tile);
  color: var(--color-primary-text);
  flex: 0 0 auto;
}

.pub-stat__body { display: grid; min-width: 0; }
.pub-stat strong {
  font-family: var(--font-heading);
  font-size: clamp(1.05rem, 0.9rem + 0.5cqi, 1.4rem);
  line-height: 1.1;
  color: var(--color-ink-heading);
}
.pub-stat span { font-size: var(--fs-xs); color: var(--color-text-muted); }

/* ==========================================================================
   2. Body layout — main column + rail
   ========================================================================== */

.pub__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(17rem, 24cqi, 21rem);
  gap: var(--space-5);
  align-items: start;
}

.pub__main {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: start;
  min-width: 0;
}

.pub-slot { min-width: 0; display: grid; }
.pub-slot--full { grid-column: 1 / -1; }

.pub__rail { display: grid; gap: var(--space-4); min-width: 0; align-content: start; }

/* Nothing in the main column: the rail spreads rather than leaving the
   left two thirds of the page empty. */
.pub__body--rail-only { grid-template-columns: minmax(0, 1fr); }
.pub__body--rail-only .pub__main { display: none; }
.pub__body--rail-only .pub__rail {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

/* ==========================================================================
   3. Cards
   ========================================================================== */

.pub-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--pub-radius);
  padding: clamp(1rem, 0.75rem + 0.9cqi, 1.5rem);
}

.pub-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.pub-card__mark {
  display: grid;
  place-items: center;
  width: 2.15rem;
  height: 2.15rem;
  border-radius: 10px;
  background: var(--pub-tile);
  color: var(--color-primary-text);
  flex: 0 0 auto;
}

.pub-card__mark--brand { background: var(--color-primary); color: #FFF; }
.pub-card__mark--ok { background: var(--color-positive-soft); color: var(--color-positive); }

.pub-card__title {
  margin: 0;
  overflow-wrap: anywhere;
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-heading);
  font-size: clamp(0.98rem, 0.9rem + 0.35cqi, 1.15rem);
  font-weight: var(--fw-bold);
  color: var(--color-ink-heading);
  line-height: 1.25;
}

.pub-card__more,
.pub-card__edit {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-primary-text);
  white-space: nowrap;
}

.pub-card__edit {
  width: 2rem;
  height: 2rem;
  justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  color: var(--color-text-muted);
}

.pub-card__cta { margin-top: var(--space-4); width: 100%; justify-content: center; }

.pub-card--prompt { border-style: dashed; background: var(--color-surface); text-align: center; }
.pub-card--prompt .pub-card__title { justify-content: center; }
.pub-card--prompt .btn { margin-top: var(--space-3); }

.pub-sub {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.pub-sub:first-of-type { margin-top: 0; }
.pub-muted { color: var(--color-text-muted); font-size: var(--fs-sm); line-height: 1.55; margin: 0; }

/* ==========================================================================
   4. About
   ========================================================================== */

.pub-prose { line-height: 1.65; font-size: var(--fs-sm); color: var(--color-ink-soft); }
.pub-prose p { margin: 0 0 var(--space-3); }
.pub-prose p:last-child { margin-bottom: 0; }

.pub-prose.is-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pub-readmore {
  margin-top: var(--space-2);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-primary-text);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
}

.pub-readmore .icon { transition: transform .18s ease; }
.pub-readmore[aria-expanded="true"] .icon { transform: rotate(-90deg); }

.pub-facts {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--color-border);
  display: grid;
  gap: var(--space-3);
  font-size: var(--fs-sm);
}

.pub-facts li { display: flex; align-items: center; gap: var(--space-3); color: var(--color-ink-soft); }
.pub-facts .icon { color: var(--color-text-muted); flex: 0 0 auto; }
.pub-facts .is-open,
.pub-facts li.is-open { color: var(--color-positive); font-weight: var(--fw-semibold); }

.pub-facts__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-success);
  flex: 0 0 auto;
  margin: 0 3px;
}

/* ==========================================================================
   5. Expertise — meters + ecosystem map
   ========================================================================== */

.pub-exp__tabs {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}

.pub-exp__tabs::-webkit-scrollbar { display: none; }

.pub-exp__tab {
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
  cursor: pointer;
  white-space: nowrap;
  min-height: 40px;
}

.pub-exp__tab.is-active {
  color: var(--color-primary-text);
  border-bottom-color: var(--color-primary);
  font-weight: var(--fw-semibold);
}

.pub-meters { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }

.pub-meter {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "mark name level" "mark track track";
  align-items: center;
  gap: 4px var(--space-3);
}

/* With a stated percentage the figure sits at the end of the bar, as
   the wireframe draws it. Without one the row keeps its two-column
   shape and no space is reserved for a number that is not there. */
.pub-meter--rated {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "mark name level" "mark track pct";
}

.pub-meter__pct {
  grid-area: pct;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 3ch;
  text-align: right;
}

.pub-meter__mark {
  grid-area: mark;
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 8px;
  background: var(--pub-tile);
  color: var(--color-primary-text);
}

.pub-meter__name {
  grid-area: name;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-ink);
  overflow-wrap: anywhere;
}

.pub-level {
  grid-area: level;
  font-style: normal;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.pub-level--expert { background: var(--color-positive-soft); color: var(--color-positive); }
.pub-level--advanced { background: var(--pub-tile); color: var(--color-primary-text); }
.pub-level--intermediate { background: #E4EEFE; color: #1D4ED8; }
.pub-level--beginner { background: var(--color-surface); color: var(--color-text-muted); }
.pub-level:empty { display: none; }

.pub-meter__track {
  grid-area: track;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--color-surface);
  overflow: hidden;
}

.pub-meter__fill {
  display: block;
  height: 100%;
  width: var(--pub-fill, 0%);
  border-radius: inherit;
  background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-brand-blue) 100%);
}

.pub-meter__fill--expert { background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-brand-violet) 100%); }

/* A row with no stored level (industries, roles) shows no track at all.
   This was a substring match on "0%" and therefore also matched "100%",
   so the strongest skill on the page was the one with no bar. The rule
   keys off a class the renderer sets instead. */
.pub-meter--unlevelled .pub-meter__track { display: none; }

/* The map is supplemental (spec §13): the list above is always usable. */
.pub-map { margin: var(--space-5) 0 0; text-align: center; }

.pub-map figcaption {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.pub-map svg { width: 100%; max-width: 20rem; height: auto; }
.pub-map__spokes line { stroke: var(--color-border); stroke-width: 1.5; }
.pub-map__hub { fill: var(--color-bg); stroke: var(--color-border); stroke-width: 1.5; }

.pub-map__hublabel {
  font-family: var(--font-heading);
  font-size: 10.5px;
  font-weight: 600;
  fill: var(--color-ink-heading);
}

.pub-map__node circle { fill: hsl(var(--pub-hue, 250) 68% 52%); }
.pub-map__node text { font-size: 10px; font-weight: 600; fill: var(--color-ink-soft); }

/* ==========================================================================
   6. Experience timeline
   ========================================================================== */

.pub-timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }

.pub-tl { position: relative; padding-left: var(--space-5); }

.pub-tl::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 1.4rem;
  bottom: calc(var(--space-4) * -1);
  width: 2px;
  background: var(--color-border);
}

.pub-tl:last-child::before { display: none; }

.pub-tl__dot {
  position: absolute;
  left: 0;
  top: 0.55rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-primary);
  box-shadow: 0 0 0 3px var(--pub-tile);
}

.pub-tl__card { display: flex; gap: var(--space-3); align-items: flex-start; }
.pub-tl__body { min-width: 0; flex: 1 1 auto; }

.pub-tl__org {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--color-ink-heading);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.pub-tl__role { margin: 2px 0 0; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--color-primary-text); }
.pub-tl__meta { margin: 4px 0 0; font-size: var(--fs-xs); color: var(--color-text-muted); }
.pub-tl__where { margin: 3px 0 0; font-size: var(--fs-xs); color: var(--color-text-muted); display: flex; align-items: center; gap: 4px; }
.pub-tl__desc { margin: var(--space-2) 0 0; font-size: var(--fs-sm); line-height: 1.55; color: var(--color-ink-soft); }

/* A stated outcome. Marked with its own tint so it reads as a result
   rather than another line of description — and never with a tick,
   because the member typed it and nothing has checked it. */
.pub-impact {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--color-success);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--color-positive-soft);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-positive);
}

.pub-impact .icon { flex: 0 0 auto; margin-top: 2px; }
.pub-impact--sm { font-size: var(--fs-xs); padding: 6px var(--space-2); margin-top: 0; }

/* Industry and business functions: context for the role, set apart
   from the technology tags below them. */
.pub-facets {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.pub-facets li {
  padding: 2px var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

/* ---- Organisation monogram tile ---------------------------------------- */

.pub-logo {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  flex: 0 0 auto;
  border-radius: 10px;
  background: hsl(var(--pub-hue, 250) 70% 96%);
  /* 38% lightness measured 3.19:1 at the teal hue and 4.49:1 at the
     amber — under AA. The ink is darkened until every hue in the set
     clears 4.5:1 on its own tint, rather than only the indigo I looked
     at while drawing it. */
  color: hsl(var(--pub-hue, 250) 58% 27%);
  border: 1px solid hsl(var(--pub-hue, 250) 55% 88%);
  font-family: var(--font-heading);
  font-size: 0.9rem;
  font-weight: var(--fw-bold);
  letter-spacing: .02em;
}

.pub-logo--sm { width: 2.25rem; height: 2.25rem; font-size: 0.75rem; border-radius: 8px; }

/* ==========================================================================
   7. Education + certifications
   ========================================================================== */

.pub-creds { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }

.pub-cred {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.pub-cred__body { display: grid; gap: 2px; min-width: 0; }
.pub-cred__body strong { font-size: var(--fs-sm); color: var(--color-ink-heading); line-height: 1.35; }
.pub-cred__sub { font-size: var(--fs-xs); color: var(--color-text-muted); }
.pub-cred__meta { font-size: var(--fs-xs); color: var(--color-text-muted); }

.pub-state {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: fit-content;
  margin-top: 4px;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.pub-state .icon { width: 0.85em; height: 0.85em; }
.pub-state--ok { background: var(--color-positive-soft); color: var(--color-positive); }
.pub-state--bad { background: var(--color-danger-soft); color: var(--color-danger); }
.pub-state--wip { background: var(--color-warning-soft); color: var(--color-warning); }
.pub-state--self { background: var(--color-surface); color: var(--color-text-muted); }

/* ==========================================================================
   8. Projects
   ========================================================================== */

.pub-projects {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: var(--space-4);
}

.pub-project {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-bg);
}

.pub-project__cover {
  position: relative;
  aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, hsl(var(--pub-hue, 250) 58% 46%) 0%, hsl(calc(var(--pub-hue, 250) + 26) 62% 30%) 100%);
  overflow: hidden;
}

.pub-project__img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pub-project__art {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 78% 26%, rgb(255 255 255 / 26%) 0 18%, transparent 19%),
    repeating-linear-gradient(58deg, rgb(255 255 255 / 9%) 0 2px, transparent 2px 15px);
}

.pub-project__tag {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: rgb(20 21 43 / 72%);
  color: #FFF;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.pub-project__body { padding: var(--space-3); display: grid; gap: var(--space-2); align-content: start; flex: 1 1 auto; }
.pub-project__title { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--color-ink-heading); line-height: 1.35; }
.pub-project__desc { margin: 0; font-size: var(--fs-xs); line-height: 1.55; color: var(--color-text-muted); }

.pub-project__cta {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-primary-text);
  min-height: 32px;
}

/* ==========================================================================
   9. Contributions counters
   ========================================================================== */

.pub-counts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(4.75rem, 1fr));
  gap: var(--space-2);
}

.pub-count {
  display: grid;
  justify-items: center;
  gap: 2px;
  padding: var(--space-3) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  text-align: center;
}

.pub-count__mark {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 9px;
  background: var(--pub-tile);
  color: var(--color-primary-text);
  margin-bottom: 2px;
}

.pub-count strong { font-family: var(--font-heading); font-size: 1.25rem; line-height: 1; color: var(--color-ink-heading); }
.pub-count span { font-size: var(--fs-xs); color: var(--color-text-muted); line-height: 1.3; }

/* ==========================================================================
   10. Chips, tags, rail components
   ========================================================================== */

.pub-chips, .pub-tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }

.pub-chip {
  padding: 5px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  background: var(--color-bg);
  color: var(--color-ink-soft);
}

.pub-tags { margin-top: var(--space-2); }

.pub-tags li {
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--pub-tile);
  color: var(--color-primary-text);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
}

.pub-checks { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: grid; gap: var(--space-2); font-size: var(--fs-sm); }
.pub-checks li { display: flex; align-items: center; gap: var(--space-2); color: var(--color-positive); font-weight: var(--fw-medium); }
.pub-checks .icon { flex: 0 0 auto; }

.pub-card--passport { background: linear-gradient(160deg, var(--pub-tile) 0%, var(--color-bg) 58%); }
.pub-card--open { background: linear-gradient(160deg, var(--color-positive-soft) 0%, var(--color-bg) 58%); }
.pub-open__goals { margin: 0 0 var(--space-2); font-size: var(--fs-sm); line-height: 1.55; color: var(--color-ink-soft); }

.pub-actions { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }

.pub-action {
  display: grid;
  justify-items: center;
  gap: 6px;
  width: 100%;
  min-height: 4.5rem;
  padding: var(--space-3) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-ink-soft);
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  text-align: center;
  line-height: 1.25;
  cursor: pointer;
}

.pub-action .icon { color: var(--color-primary-text); }
.pub-action:hover, .pub-action:focus-visible { border-color: var(--color-primary); }

.pub-communities { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.pub-community { display: flex; align-items: center; gap: var(--space-3); }
.pub-community__body { display: grid; min-width: 0; flex: 1 1 auto; }
.pub-community__body strong { font-size: var(--fs-sm); color: var(--color-ink-heading); line-height: 1.3; overflow-wrap: anywhere; }
.pub-community__body span { font-size: var(--fs-xs); color: var(--color-text-muted); }

.pub-link { color: var(--color-primary-text); font-size: var(--fs-xs); font-weight: var(--fw-semibold); margin-top: 4px; }
.pub-pill { display: inline-block; padding: 1px var(--space-2); border-radius: var(--radius-full); font-size: var(--fs-xs); font-weight: var(--fw-semibold); }
.pub-pill--ok { background: var(--color-positive-soft); color: var(--color-positive); }

.pub-notice {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-md);
  background: var(--color-warning-soft);
  color: var(--color-warning);
  font-size: var(--fs-sm);
  margin-bottom: var(--space-4);
}

/* ==========================================================================
   11. Tab strip — phone only
   ========================================================================== */

.pub-tabs { display: none; }

.pub-tabs ul {
  list-style: none;
  margin: 0;
  padding: 0 var(--space-1);
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  scrollbar-width: none;
}

.pub-tabs ul::-webkit-scrollbar { display: none; }

.pub-tabs__link {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-3);
  min-height: 44px;
  border-bottom: 2px solid transparent;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.pub-tabs__link.is-active {
  color: var(--color-primary-text);
  border-bottom-color: var(--color-primary);
  font-weight: var(--fw-semibold);
}

/* ==========================================================================
   12. Responsive tiers — container, not viewport
   ========================================================================== */

/* Tablet landscape: the rail folds beneath the main column. */
@container pub (max-width: 61.9375rem) {
  .pub__body { grid-template-columns: minmax(0, 1fr); }
  .pub__rail { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
}

/* Tablet portrait: one main column; halves stop being halves. */
@container pub (max-width: 47.9375rem) {
  .pub__main { grid-template-columns: minmax(0, 1fr); }

  .pub-banner__inner { grid-template-columns: minmax(0, 1fr) auto; }
  .pub-banner__quote { display: none; }

  .pub-id { grid-template-columns: auto minmax(0, 1fr); }
  .pub-id__side { grid-column: 1 / -1; justify-items: stretch; padding-top: 0; }
  .pub-id__actions { justify-content: stretch; }
  .pub-id__actions .btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }
  .pub-social { justify-content: flex-start; }
}

/* Phone: compact hero, tab strip on, single column throughout. */
@container pub (max-width: 34rem) {
  .pub { gap: var(--space-4); }

  /* The avatar overlaps the banner's lower edge, so the banner has to
     reserve that height or its own words end up behind a face. */
  .pub-banner { min-height: 9.5rem; padding-bottom: 3.25rem; align-items: flex-start; }
  .pub-banner__place { display: none; }
  /* 44px, not 34: the visible label is hidden here so this becomes an
     icon-only target, and an icon-only target is the one that most
     needs the full touch size rather than the least. */
  .pub-banner__edit { top: var(--space-2); right: var(--space-2); min-height: 44px; min-width: 44px; justify-content: center; padding: 0 var(--space-2); }
  .pub-banner__edit span { display: none; }
  .pub-card__edit { width: 44px; height: 44px; }
  .pub-banner__inner { grid-template-columns: minmax(0, 1fr); }
  .pub-banner__title { -webkit-line-clamp: 3; line-clamp: 3; }

  /* One column: beside a 5.5rem avatar the name had ~40% of a phone. */
  .pub-id { grid-template-columns: minmax(0, 1fr); padding-inline: var(--space-4); gap: var(--space-3); }
  .pub-id__avatar { margin-top: -3rem; }
  .pub-id__main { padding-top: 0; }
  .pub-id__meta { gap: var(--space-2) var(--space-4); }
  .pub-id__side { padding-top: 0; }

  /* Four across, as the reference draws them, by stacking the mark above
     the figure rather than beside it. */
  /* Three, not four: with five or six figures a four-column grid
     leaves one tile stranded on its own row, which reads as a bug
     rather than a layout. Three gives clean rows at both counts. */
  .pub-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); padding-inline: var(--space-4); }
  .pub-stat {
    padding-left: 0;
    border-left: 0;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
  }
  .pub-stat__mark { width: 2rem; height: 2rem; border-radius: 10px; }
  .pub-stat__body { justify-items: center; text-align: center; }
  .pub-stat strong { font-size: 1rem; }
  .pub-stat span { font-size: 0.68rem; line-height: 1.2; }

  /* Buttons stretch to the tallest sibling unless told otherwise. */
  .pub-id__actions { align-items: center; }
  .pub-id__actions .btn { min-height: 44px; max-height: 44px; padding-block: 0; }

  /* The strip is sticky so the section a reader is in stays named. */
  .pub-tabs {
    display: block;
    position: sticky;
    top: var(--jdev-header-h, 64px);
    z-index: 10;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    margin-inline: calc(var(--space-4) * -1);
    padding-inline: var(--space-4);
  }

  /* Filtering only ever happens with script; see public-profile.js. */
  .pub[data-pub-filter] .pub-slot[hidden] { display: none; }

  .pub-actions { grid-template-columns: repeat(3, 1fr); }
  .pub-action { min-height: 4.25rem; }

  /* A "View All" link beside a long title leaves the title a few
     characters. The link drops to its own row instead of squeezing it. */
  .pub-card__head { flex-wrap: wrap; }
  .pub-card__title { flex: 1 1 8rem; }
  .pub-card__more { flex: 0 0 100%; justify-content: flex-start; }
  .pub-card__edit { flex: 0 0 auto; }

  /* Every text-level action becomes a real target: 16px and 32px rows
     are readable with a mouse and unhittable with a thumb. */
  .pub-readmore,
  .pub-project__cta,
  .pub-card__more,
  .pub-link { min-height: 44px; display: inline-flex; align-items: center; }
  .pub-community .btn--sm { min-height: 44px; padding-inline: var(--space-4); }
  .pub-social__link { width: 2.75rem; height: 2.75rem; }
  .pub-projects { grid-template-columns: minmax(0, 1fr); }
  .pub-card--prompt .btn { min-height: 44px; }
  .pub-more__menu { right: auto; left: 0; }
}

/* Very narrow: fewer per row rather than clipped labels. */
@container pub (max-width: 20rem) {
  .pub-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pub-counts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pub-actions { grid-template-columns: repeat(2, 1fr); }
  .pub-stat span { font-size: 0.64rem; }
}

/* Reduced motion. Written at matching specificity and placed after every
   rule it has to beat, rather than reaching for !important: this file
   declares transitions in exactly three places and naming them costs one
   line while an !important costs every future rule that has to override
   it. The theme runs a shrink-only ratchet on the count for that reason. */
@media (prefers-reduced-motion: reduce) {
  .pub-more .icon,
  .pub-readmore .icon,
  .pub-social__link,
  .pub-action,
  .pub-card__more,
  .pub-exp__tab { transition: none; animation: none; }
}

/* Print: the map and banner art are decoration; the content is not. */
@media print {
  .pub-banner__art,
  .pub-tabs,
  .pub-id__actions,
  .pub-actions { display: none; }

  .pub__body { grid-template-columns: minmax(0, 1fr); }
  .pub-card { break-inside: avoid; }
}


/* ==========================================================================
   13. Fallback for browsers without container queries

   Container queries are the right tool here — this column sits beside
   the app shell rail, so its width is not the viewport's. But a browser
   that does not support them ignores every @container block above and
   renders the desktop layout at every size, which on a phone means a
   two-column grid inside 360px and a page that scrolls sideways.

   That is not hypothetical: it is iOS 15 and earlier, which is where
   older iPhones stop. The viewport breakpoints below are approximations
   of the container tiers — the rail is roughly 240px on a wide screen
   and absent on a phone — and they only ever apply where the real
   feature is missing.
   ========================================================================== */

@supports not (container-type: inline-size) {
  @media (max-width: 75rem) {
    .pub__body { grid-template-columns: minmax(0, 1fr); }
    .pub__rail { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
  }

  @media (max-width: 60rem) {
    .pub__main { grid-template-columns: minmax(0, 1fr); }
    .pub-banner__quote { display: none; }
    .pub-id { grid-template-columns: auto minmax(0, 1fr); }
    .pub-id__side { grid-column: 1 / -1; justify-items: stretch; padding-top: 0; }
    .pub-id__actions .btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }
  }

  @media (max-width: 40rem) {
    .pub-banner { min-height: 9.5rem; padding-bottom: 3.25rem; align-items: flex-start; }
    .pub-banner__place { display: none; }
    .pub-banner__inner { grid-template-columns: minmax(0, 1fr); }
    .pub-banner__edit { top: var(--space-2); right: var(--space-2); min-height: 44px; min-width: 44px; justify-content: center; padding: 0 var(--space-2); }
    .pub-banner__edit span { display: none; }
    .pub-card__edit { width: 44px; height: 44px; }

    .pub-id { grid-template-columns: minmax(0, 1fr); padding-inline: var(--space-4); }
    .pub-id__avatar { margin-top: -3rem; }
    .pub-id__main { padding-top: 0; }

    .pub-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); padding-inline: var(--space-4); }
    .pub-stat { padding-left: 0; border-left: 0; flex-direction: column; align-items: center; text-align: center; gap: 6px; }
    .pub-stat__body { justify-items: center; text-align: center; }
    .pub-stat strong { font-size: 1rem; }
    .pub-stat span { font-size: 0.68rem; line-height: 1.2; }

    .pub-tabs {
      display: block;
      position: sticky;
      top: var(--jdev-header-h, 64px);
      z-index: 10;
      background: var(--color-bg);
      border-bottom: 1px solid var(--color-border);
      margin-inline: calc(var(--space-4) * -1);
      padding-inline: var(--space-4);
    }

    .pub[data-pub-filter] .pub-slot[hidden] { display: none; }

    .pub-projects { grid-template-columns: minmax(0, 1fr); }
    .pub-readmore,
    .pub-project__cta,
    .pub-card__more,
    .pub-link { min-height: 44px; display: inline-flex; align-items: center; }
    .pub-card__head { flex-wrap: wrap; }
    .pub-card__more { flex: 0 0 100%; justify-content: flex-start; }
    .pub-community .btn--sm { min-height: 44px; padding-inline: var(--space-4); }
    .pub-social__link { width: 2.75rem; height: 2.75rem; }
    .pub-actions { grid-template-columns: repeat(3, 1fr); }
    .pub-action { min-height: 4.25rem; }
  }

  @media (max-width: 25rem) {
    .pub-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pub-counts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pub-actions { grid-template-columns: repeat(2, 1fr); }
  }
}
