/* ==========================================================================
   SPG Leaders — WordPress chrome
   --------------------------------------------------------------------------
   main.css is the design system, ported unchanged from the HTML template. This
   file adds only what WordPress needs on top of it: content styles for the
   editor's output, sidebars and widgets, comments, pagination, search, and the
   alignment classes core blocks emit.

   Everything here uses the same custom properties as main.css, so a Customizer
   colour change flows through automatically.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Accessibility helpers required by WordPress
   -------------------------------------------------------------------------- */

.screen-reader-text {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  word-wrap: normal !important;
}

.screen-reader-text:focus {
  background-color: var(--paper);
  border-radius: var(--r-xs);
  box-shadow: var(--shadow-md);
  clip-path: none;
  color: var(--accent);
  display: block;
  font-size: 0.9rem;
  font-weight: 700;
  height: auto;
  left: 1rem;
  line-height: normal;
  padding: 0.9rem 1.4rem;
  text-decoration: none;
  top: 1rem;
  width: auto;
  z-index: 100000;
}

/* --------------------------------------------------------------------------
   Layout: content beside an optional sidebar
   -------------------------------------------------------------------------- */

.layout {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
}

.layout--sidebar {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 900px) {
  .layout--sidebar {
    grid-template-columns: minmax(0, 1fr) 320px;
  }

  .sidebar-left .layout--sidebar {
    grid-template-columns: 320px minmax(0, 1fr);
  }

  .sidebar-left .layout--sidebar .layout__main {
    order: 2;
  }
}

.layout--narrow {
  max-width: 76ch;
  margin-inline: auto;
}

.layout__aside {
  display: grid;
  align-content: start;
  gap: clamp(1.5rem, 3vw, 2.25rem);
}

/* --------------------------------------------------------------------------
   Prose — the editor's output
   -------------------------------------------------------------------------- */

.prose {
  max-width: 74ch;
  margin-inline: auto;
  font-size: var(--step-0);
  color: var(--slate-700);
}

.prose--wide {
  max-width: none;
}

.prose > * + * {
  margin-top: 1.15em;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  color: var(--fg);
  font-family: var(--font-display);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: 2em;
  margin-bottom: 0.6em;
}

.prose h2 { font-size: var(--step-3); }
.prose h3 { font-size: var(--step-2); }
.prose h4 { font-size: var(--step-1); }

.prose > :first-child {
  margin-top: 0;
}

.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

.prose a:hover {
  text-decoration-thickness: 2px;
}

.prose ul,
.prose ol {
  padding-left: 1.4em;
}

/*
 * Restore the markers the global `li { list-style: none }` reset removes. That
 * reset exists for navigation and card lists, but it also reached anything an
 * editor writes: bulleted lists came out as plain indented lines, and numbered
 * lists lost their numbers altogether, which makes an ordered list meaningless.
 */
.prose ul > li { list-style: disc; }
.prose ol > li { list-style: decimal; }
.prose ul ul > li { list-style: circle; }
.prose ul ul ul > li { list-style: square; }
.prose li::marker { color: var(--slate-500); }

.prose li + li {
  margin-top: 0.45em;
}

.prose img,
.prose video,
.prose iframe {
  max-width: 100%;
  height: auto;
  border-radius: var(--r-md);
}

.prose figure {
  margin: 2em 0;
}

.prose figcaption,
.wp-caption-text {
  color: var(--fg-muted);
  font-size: var(--step--1);
  margin-top: 0.7em;
  text-align: center;
}

.prose blockquote {
  border-left: 3px solid var(--accent);
  color: var(--fg);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-style: italic;
  margin-inline: 0;
  padding: 0.4em 0 0.4em 1.4em;
}

.prose blockquote cite {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-style: normal;
  color: var(--fg-muted);
  margin-top: 0.7em;
}

.prose code,
.prose kbd {
  background: var(--sand);
  border-radius: var(--r-xs);
  font-size: 0.88em;
  padding: 0.15em 0.4em;
}

.prose pre {
  background: var(--ink-900);
  border-radius: var(--r-md);
  color: #e7ecf3;
  overflow-x: auto;
  padding: 1.2rem 1.4rem;
}

.prose pre code {
  background: none;
  color: inherit;
  padding: 0;
}

.prose hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 3em 0;
}

.prose table {
  border-collapse: collapse;
  display: block;
  overflow-x: auto;
  width: 100%;
}

.prose th,
.prose td {
  border-bottom: 1px solid var(--line);
  padding: 0.75rem 1rem;
  text-align: left;
}

.prose th {
  color: var(--fg);
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Core block alignments
   -------------------------------------------------------------------------- */

.alignleft {
  float: left;
  margin: 0.4em 1.6em 1.2em 0;
}

.alignright {
  float: right;
  margin: 0.4em 0 1.2em 1.6em;
}

.aligncenter {
  clear: both;
  display: block;
  margin-inline: auto;
}

.prose .alignwide {
  margin-inline: calc(50% - 50vw);
  max-width: 100vw;
  width: auto;
}

@media (min-width: 1240px) {
  .prose .alignwide {
    margin-inline: -8rem;
    max-width: none;
  }
}

.prose .alignfull {
  margin-inline: calc(50% - 50vw);
  max-width: 100vw;
  width: 100vw;
}

.wp-caption {
  max-width: 100%;
}

/* WordPress adds these to specific posts; theme review expects them styled. */
.sticky .post__title::after {
  content: "★";
  color: var(--amber-500);
  margin-left: 0.4em;
}

.bypostauthor > .comment-body .comment-author img {
  outline: 2px solid var(--accent);
}

.page-links {
  display: flex;
  gap: 0.5rem;
  margin-top: 2rem;
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   Pagination and post navigation
   -------------------------------------------------------------------------- */

.pagination,
.post-navigation {
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  justify-content: center;
}

.pagination .page-numbers {
  align-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  color: var(--fg);
  display: inline-flex;
  font-size: 0.92rem;
  font-weight: 600;
  justify-content: center;
  min-width: 2.6rem;
  padding: 0.55rem 0.8rem;
  text-decoration: none;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.pagination .page-numbers:hover,
.pagination .page-numbers.current {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--paper);
}

.pagination .page-numbers.dots:hover {
  background: none;
  border-color: var(--line);
  color: var(--fg);
}

/* --------------------------------------------------------------------------
   Infinite scroll (the Leaders Hub list)

   The numbered pagination is hidden by the script once it takes over; this is
   what sits under the list instead. It is empty, and so takes up no room beyond
   its margin, until something needs saying.
   -------------------------------------------------------------------------- */
.infinite__status {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  min-height: 1.6rem;
}

.infinite__status[hidden] { display: none; }

.infinite__spinner {
  display: none;
  width: 1.6rem;
  height: 1.6rem;
  border: 2px solid var(--line);
  border-top-color: var(--blue-500);
  border-radius: 50%;
  animation: infinite-spin 0.8s linear infinite;
}

.infinite.is-loading .infinite__spinner { display: block; }

.infinite__note {
  margin: 0;
  color: var(--slate-500);
  font-size: 0.92rem;
}

.infinite__note:empty { display: none; }

/* A hair of height, so it can enter the viewport; it draws nothing. */
.infinite__sentinel { height: 1px; }

@keyframes infinite-spin { to { transform: rotate(360deg); } }

.post-navigation .nav-links {
  border-top: 1px solid var(--line);
  display: grid;
  gap: 1.5rem;
  padding-top: 2rem;
}

@media (min-width: 700px) {
  .post-navigation .nav-links {
    grid-template-columns: 1fr 1fr;
  }

  .post-navigation .nav-next {
    text-align: right;
  }
}

.post-navigation a {
  color: var(--fg);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.25;
  text-decoration: none;
}

.post-navigation a:hover {
  color: var(--accent);
}

.post-navigation .nav-label {
  color: var(--fg-muted);
  display: block;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  margin-bottom: 0.4rem;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Widgets
   -------------------------------------------------------------------------- */

.widget {
  font-size: 0.95rem;
}

.widget__title {
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  margin: 0 0 1rem;
  text-transform: uppercase;
}

.widget ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.widget li + li {
  margin-top: 0.55rem;
}

/*
 * :not(.btn) matters. Without it this repaints button labels too, and a
 * .btn--primary inside a widget loses its white text against the blue fill —
 * 1.79:1, effectively unreadable.
 */
.widget a:not(.btn) {
  color: var(--slate-700);
  text-decoration: none;
}

.widget a:not(.btn):hover {
  color: var(--accent);
}

.widget select,
.widget input[type="search"] {
  width: 100%;
}

/*
 * Footer and widget list links are 16-18px tall as plain inline text, which
 * only clears WCAG 2.5.8 through the spacing exception and is fiddly to hit on
 * a phone. A little vertical padding takes each to 24px+ without disturbing the
 * visual rhythm.
 */
.footer__list a,
.footer__legal a,
.site-footer .widget li a,
.layout__aside .widget li a {
  display: inline-block;
  padding-block: 3px;
}

/* Footer widgets sit on the dark ground, so they invert. */
.site-footer .widget__title {
  color: var(--paper);
}

.site-footer .widget a:not(.btn) {
  color: rgba(255, 255, 255, 0.72);
}

.site-footer .widget a:not(.btn):hover {
  color: var(--paper);
}

/*
 * Muted text inside a widget inherits the light-theme muted colour, which is
 * only 3.4:1 against the dark footer. On that ground it has to come from the
 * other direction.
 */
.site-footer .brand__tag,
.site-footer .widget-events__meta,
.site-footer .widget-leaders__role,
.site-footer .widget-cta__text,
.site-footer .widget .muted {
  color: rgba(255, 255, 255, 0.66);
}

.widget-events__item + .widget-events__item {
  border-top: 1px solid var(--line-soft);
  margin-top: 0.85rem;
  padding-top: 0.85rem;
}

.widget-events__link {
  display: block;
  font-weight: 600;
  color: var(--fg);
}

.widget-events__meta {
  color: var(--fg-muted);
  display: block;
  font-size: 0.84rem;
  margin-top: 0.2rem;
}

.widget-leaders__item {
  align-items: center;
  display: flex;
  gap: 0.8rem;
}

.widget-leaders__avatar {
  flex-shrink: 0;
  height: 44px;
  width: 44px;
  font-size: 0.9rem;
}

.widget-leaders__avatar img {
  border-radius: var(--r-full);
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.widget-leaders__name {
  display: block;
  font-weight: 600;
  color: var(--fg);
}

.widget-leaders__role {
  color: var(--fg-muted);
  display: block;
  font-size: 0.82rem;
}

.widget-cta {
  background: var(--sand);
  border-radius: var(--r-md);
  padding: 1.5rem;
}

.widget-cta__text {
  color: var(--fg-muted);
  margin: 0 0 1.1rem;
}

/* --------------------------------------------------------------------------
   Search form
   -------------------------------------------------------------------------- */

.search-form__row {
  display: flex;
  gap: 0.5rem;
}

.search-form__input {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--fg);
  flex: 1;
  font: inherit;
  min-width: 0;
  padding: 0.8rem 1rem;
}

.search-form__input:focus-visible {
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.search-form__submit {
  flex-shrink: 0;
  padding-inline: 1rem;
}

.search-form__submit svg {
  height: 20px;
  width: 20px;
}

/* --------------------------------------------------------------------------
   No results
   -------------------------------------------------------------------------- */

.no-results {
  margin-inline: auto;
  max-width: 60ch;
  padding-block: clamp(2rem, 5vw, 4rem);
  text-align: center;
}

.no-results__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  margin: 0 0 0.7rem;
}

.no-results .search-form {
  margin-top: 1.6rem;
}

/* --------------------------------------------------------------------------
   Comments
   -------------------------------------------------------------------------- */

.comments {
  border-top: 1px solid var(--line);
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: clamp(2rem, 4vw, 3rem);
}

.comments__title,
.comments__reply-title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  letter-spacing: -0.02em;
  margin: 0 0 1.5rem;
}

.comments__list {
  list-style: none;
  margin: 0 0 3rem;
  padding: 0;
}

.comments__list .children {
  list-style: none;
  margin-top: 1.5rem;
  padding-left: clamp(1rem, 4vw, 2.5rem);
}

.comments__list .comment-body {
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 1.5rem;
  margin-bottom: 1.5rem;
}

.comments__list .comment-author {
  align-items: center;
  display: flex;
  gap: 0.7rem;
  font-weight: 600;
}

.comments__list .comment-author img {
  border-radius: var(--r-full);
}

.comments__list .comment-metadata {
  color: var(--fg-muted);
  font-size: 0.84rem;
  margin: 0.3rem 0 0.9rem;
}

.comments__list .comment-metadata a {
  color: inherit;
}

.comment-form label {
  display: block;
  font-size: 0.86rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font: inherit;
  padding: 0.75rem 0.9rem;
  width: 100%;
}

.comment-form p {
  margin-bottom: 1rem;
}

.comment-form .submit {
  background: var(--accent);
  border: 0;
  border-radius: var(--r-full);
  color: var(--paper);
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  padding: 0.8rem 1.6rem;
}

.comments__closed {
  color: var(--fg-muted);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   Small additions to design components
   -------------------------------------------------------------------------- */

.hero__note {
  font-size: 0.86rem;
}

.mission__grid,
.quote__grid,
.join__grid {
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}

/* The join row carries very different amounts on each side: a heading and two
   bullets against a twelve-field form. Measured at desktop they were 354px and
   940px tall in equal 536px columns, which left the left-hand side looking
   stranded in its own width.

   Splitting the width unevenly settles it. The form cannot be made shorter by
   widening it — its fields are already paired two to a row, so extra width goes
   into the inputs rather than removing rows — but taking width away from the
   short column stops it reading as a half-empty panel, and the form gets room
   its inputs can use.

   Only above the point where the grid is still two columns; below 1080px the
   .grid-2 rule stacks them and this must not interfere. */
@media (min-width: 1081px) {
  .join__grid {
    grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  }
}

.events__list {
  gap: 1rem;
}

.events__more,
.benefits__cta {
  margin-top: clamp(2rem, 4vw, 3rem);
}

.join__points {
  gap: 0.85rem;
  margin-top: 0.5rem;
  list-style: none;
  padding: 0;
}

.join__point {
  gap: 0.7rem;
  flex-wrap: nowrap;
}

.join__check {
  color: var(--accent);
  flex-shrink: 0;
  height: 20px;
  width: 20px;
}

.join__contact {
  gap: 1.5rem;
  margin-top: 0.5rem;
  font-size: 0.9rem;
}

.quote__avatar {
  flex-shrink: 0;
  height: 48px;
  width: 48px;
  font-size: 1rem;
}

.quote__avatar img {
  border-radius: var(--r-full);
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.quote__name {
  display: block;
  font-size: 0.98rem;
}

.quote__role {
  font-size: 0.85rem;
}

.quote {
  margin: 0;
}

.post__hero {
  border-radius: var(--r-lg);
  margin: 0 0 2.5rem;
  overflow: hidden;
}

/*
 * The event page pulls its featured image up over the bottom of the dark
 * hero band instead of starting clean below it. Negative margin, not
 * absolute positioning — it keeps the image in normal flow so the prose and
 * agenda beneath it space off its real bottom edge, and it needs the hero
 * section's own overflow:hidden to stay off since that only clips the
 * hero's own content, not a later sibling painting over it.
 */
.post__hero--overlap {
  margin-top: clamp(-6rem, -8vw, -3rem);
  box-shadow: var(--shadow-lg);
  position: relative;
  z-index: 1;
}

/* A virtual event's recording plays in the banner's place. 16:9 is the video's own
   shape, so it is held narrower than the banner would be (it is taller for its
   width) and centred; the iframe fills the .media box the way an image would. */
.event-video {
  max-width: 60rem;
  margin-inline: auto;
}

.event-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The hero needs more room at its own bottom than other heroes get, so the
   overlapping image doesn't crowd the facts row (or the Register button) it
   pulls up over — a past event with no button was measuring at a -2px gap,
   the image touching the venue text above it. */
.single-spg_event .page-hero { padding-bottom: clamp(6rem, 10vw, 8rem); }

.post__excerpt,
.event__excerpt {
  font-size: 0.93rem;
}

.post__tags {
  margin-top: 2rem;
}

.person__photo {
  aspect-ratio: 4 / 5;
  border-radius: var(--r-md);
  overflow: hidden;
}

.person__photo img {
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.person__name a {
  color: inherit;
  text-decoration: none;
}

.person__name a:hover {
  color: var(--accent);
}

/*
 * Two columns: portrait and name on the left; the quote card and highlights
 * stacked on the right. A leader with neither quote nor highlights collapses
 * to one column via .leader-profile__grid--single, so the intro isn't left
 * stranded beside a blank half.
 */
.leader-profile__grid {
  display: grid;
  grid-template-columns: minmax(220px, 320px) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.leader-profile__grid--single { grid-template-columns: minmax(0, 1fr); max-width: 420px; }

@media (max-width: 720px) {
  .leader-profile__grid { grid-template-columns: minmax(0, 1fr); }
  .leader-profile__intro { max-width: 320px; }
}

.leader-profile__intro { display: grid; gap: 0; }

/* Scoped to this template: the hero here holds only the breadcrumb and the
   group label, so it doesn't need the taller band other heroes get for a
   title underneath. */
.single-spg_leader .page-hero { padding-block: clamp(2rem, 4vw, 2.8rem); }

/* Matches the registered spg-portrait crop (640x800) used on the archive
   tile, so the profile page shows the same frame the editor chose. */
.leader-profile__photo {
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--sand);
  box-shadow: var(--shadow-sm);
  margin-bottom: 1.6rem;
}

.leader-profile__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Stands in for a portrait at full frame size — matches the archive tile's
   fallback treatment so the same leader reads consistently in both places. */
.leader-profile__photo--fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 5vw, 3rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #fff;
  background: linear-gradient(140deg, var(--blue-500), var(--blue-700));
}

.leader-profile__name {
  margin: 0 0 0.9rem;
  font-size: clamp(1.7rem, 3.2vw, 2.2rem);
}

/* A short accent bar anchors the name the way an underline would, without a
   rule running under letterforms with descenders. */
.leader-profile__name::after {
  content: "";
  display: block;
  width: 42px;
  height: 3px;
  margin-top: 0.75rem;
  border-radius: 2px;
  background: var(--accent);
}

.leader-profile__role {
  margin: 0 0 1.1rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--slate-500);
}

.leader-profile__tags { margin-bottom: 1.3rem; padding-top: 0; }

/* The breadcrumb bar: crumb and group label on the left, the LinkedIn link
   pinned to the right edge and vertically centred against that stack. */
.leader-profile__crumbbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
}

.leader-profile__crumbbar-text > .breadcrumb { margin-bottom: 0.5rem; }
.leader-profile__crumbbar-text > .eyebrow { margin-bottom: 0; }

/* Never lets the button's label wrap or the flex row squeeze it thinner than
   its content — the breadcrumb/eyebrow stack is the side that should give. */
.leader-profile__linkedin { flex-shrink: 0; }

.event__facts--hero {
  margin-block: 1.5rem;
}

.event__title a {
  color: inherit;
  text-decoration: none;
}

.event__title a:hover {
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   Header and footer additions
   -------------------------------------------------------------------------- */

.brand__logo {
  height: auto;
  max-height: 48px;
  width: auto;
}

.footer__description {
  font-size: 0.93rem;
}

.footer__grid--brand-only {
  grid-template-columns: minmax(0, 1fr);
}

.footer__legal {
  gap: 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer__legal li {
  display: inline;
}

/* The in-menu button is a mobile-drawer affordance; the header has its own. */
.nav__menu-cta {
  display: none;
}

@media (max-width: 1080px) {
  .nav__menu-cta {
    display: block;
  }
}

.form__note--admin {
  background: var(--amber-100);
  border-radius: var(--r-xs);
  color: var(--ink-700);
  margin-top: 1rem;
  padding: 0.7rem 0.9rem;
}

/* Sub-menus. The design has a single-level nav; this keeps depth 2 usable. */
.nav__menu .sub-menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 1081px) {
  .nav__menu li {
    position: relative;
  }

  .nav__menu .sub-menu {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    box-shadow: var(--shadow-md);
    left: 0;
    min-width: 220px;
    opacity: 0;
    padding: 0.5rem;
    pointer-events: none;
    position: absolute;
    top: calc(100% + 0.5rem);
    transform: translateY(-4px);
    transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
    z-index: 60;
  }

  /*
   * Bridge the gap between the item and its panel.
   *
   * The panel is offset 0.5rem below the item, and that 0.5rem sits OUTSIDE the
   * <li>. Moving the pointer down towards a child crosses it, li:hover goes
   * false, and the panel vanishes mid-travel. It is worse on the diagonal: the
   * panel is 220px wide against a ~71px item, so aiming at a child on the right
   * leaves the item horizontally as well.
   *
   * This invisible strip spans the panel's full width and fills the gap. It is
   * part of the sub-menu, which is a descendant of the <li>, so the pointer
   * never leaves the item while crossing. It inherits pointer-events from the
   * panel, so it is inert until the panel is actually open — no stray hit area
   * sitting under the header the rest of the time.
   */
  .nav__menu .sub-menu::before {
    content: "";
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    height: 0.5rem;
  }

  .nav__menu li:hover > .sub-menu,
  .nav__menu li:focus-within > .sub-menu {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }

  .nav__menu .sub-menu a {
    display: block;
    padding: 0.5rem 0.7rem;
    border-radius: var(--r-xs);
  }

  .nav__menu .sub-menu a:hover {
    background: var(--sand);
  }
}

/* ==========================================================================
   Past Events Gallery
   ========================================================================== */

.gallery__intro { margin-bottom: clamp(2rem, 4vw, 3rem); }

/*
 * CSS columns rather than grid: the tiles are collages of wildly different
 * aspect ratios, and columns let each keep its own height without the row
 * alignment a grid would force. break-inside stops a tile splitting across
 * a column boundary.
 */
.gallery {
  column-count: 1;
  column-gap: clamp(0.9rem, 2vw, 1.5rem);
}

@media (min-width: 620px)  { .gallery { column-count: 2; } }
@media (min-width: 1040px) { .gallery { column-count: 3; } }

.gallery__item {
  break-inside: avoid;
  margin: 0 0 clamp(0.9rem, 2vw, 1.5rem);
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}

.gallery__item:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--line);
}

/* [hidden] has to win over the display the filter tabs toggle against. */
.gallery__item[hidden] { display: none !important; }

.gallery__open {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  position: relative;
  line-height: 0;
}

.gallery__open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.gallery__item img {
  width: 100%;
  height: auto;
  display: block;
}

.gallery__badge {
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.55rem;
  border-radius: var(--r-full);
  background: rgba(8, 17, 29, 0.62);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.76rem;
  font-weight: 700;
  line-height: 1;
}

.gallery__badge svg { width: 13px; height: 13px; }

/* The picture with no photos or video behind it, positioned so a badge can sit on it. */
.gallery__static { position: relative; line-height: 0; }

/* "Virtual" sits opposite the photo count, top left, in the accent colour. */
.gallery__badge--virtual {
  right: auto;
  left: 0.7rem;
  background: rgba(27, 106, 201, 0.9);
}

/* A virtual event with a recording: the cover is a link to the event page, so it
   takes the pointer of a link rather than the magnifier of the photo viewer. */
.gallery__open--link { cursor: pointer; }

.gallery__caption {
  display: grid;
  gap: 0.2rem;
  padding: 0.85rem 1rem 1rem;
}

.gallery__title {
  color: var(--fg);
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  text-decoration: none;
}

.gallery__title:hover { color: var(--accent); }

.gallery__meta {
  color: var(--fg-muted);
  font-size: 0.83rem;
}

/* ----------------------------------------------------------- Lightbox ---- */

.spg-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  background: rgba(8, 17, 29, 0.94);
  backdrop-filter: blur(4px);
}

.spg-lightbox[hidden] { display: none; }

.spg-lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem clamp(1rem, 3vw, 2rem);
  color: #fff;
}

.spg-lightbox__title { font-size: 0.95rem; font-weight: 600; }
.spg-lightbox__count { color: rgba(255, 255, 255, 0.66); font-size: 0.85rem; }

.spg-lightbox__stage {
  flex: 1;
  display: grid;
  /* A definite row and column, so the image's max-height/max-width percentages
     resolve against the stage instead of the image's own size. */
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  place-items: center;
  padding: 0 clamp(0.5rem, 3vw, 3rem) clamp(1rem, 3vw, 2rem);
  min-height: 0;
}

.spg-lightbox__stage img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--r-sm);
}

.spg-lightbox__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  cursor: pointer;
  transition: background-color 0.2s var(--ease);
}

.spg-lightbox__btn:hover { background: rgba(255, 255, 255, 0.18); }
.spg-lightbox__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.spg-lightbox__btn svg { width: 20px; height: 20px; }

.spg-lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.spg-lightbox__nav--prev { left: clamp(0.5rem, 2vw, 1.5rem); }
.spg-lightbox__nav--next { right: clamp(0.5rem, 2vw, 1.5rem); }

/* Stop the page behind scrolling while the overlay is open. */
body.spg-lightbox-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .gallery__item { transition: none; }
}

/* A quiet hand-off between the events archive and the past-events gallery. */
.events__past {
  border-top: 1px solid var(--line-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  text-align: center;
}

.events__past-text {
  color: var(--fg-muted);
  margin: 0;
}

/*
 * Second-level items in the mobile drawer. Without this they render flat and a
 * child reads as a sibling of its parent — "Events" and "Upcoming Events"
 * sitting at the same level looks like a duplicate rather than a hierarchy.
 */
@media (max-width: 1080px) {
  .nav__menu .sub-menu {
    margin: 0;
    padding: 0;
  }

  .nav__menu .sub-menu a {
    padding-left: 1.5rem;
    font-size: 0.94rem;
    opacity: 0.78;
  }

  /* A short rule marking the items as belonging to the one above. */
  .nav__menu .sub-menu li {
    position: relative;
  }

  .nav__menu .sub-menu li::before {
    content: "";
    position: absolute;
    left: 0.35rem;
    top: 50%;
    width: 0.7rem;
    height: 1px;
    background: var(--line);
  }
}

/* ==========================================================================
   Event agenda
   ========================================================================== */

.agenda { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

.agenda__title {
  font-size: var(--step-2);
  margin: 0 0 1.5rem;
}

/*
 * A running vertical line behind every dot, not a border per item — a
 * per-item border breaks at each row's own edges, which reads as a stack of
 * boxes rather than one continuous timeline.
 */
.agenda__list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

.agenda__list::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 0.4rem;
  bottom: 0.6rem;
  width: 2px;
  background: var(--line);
}

.agenda__item {
  position: relative;
  padding: 0 0 clamp(1.6rem, 3vw, 2.25rem) 2.25rem;
}

.agenda__item:last-child { padding-bottom: 0; }

/* Centred on the line above: 12px dot, 2px line, (12 - 2) / 2 = 5px. */
.agenda__dot {
  position: absolute;
  left: 0;
  top: 0.35rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--blue-600);
}

.agenda__row { display: grid; gap: 0.3rem; }

.agenda__time {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--blue-600);
}

.agenda__what {
  margin: 0;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink-900);
}

.agenda__speaker {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate-400);
}

.agenda__detail {
  margin: 0;
  color: var(--slate-600);
  font-size: 0.95rem;
  line-height: 1.55;
}

/*
 * A break or transition — registration, tea, lunch — collapses to one line
 * of "time — what" plus an optional description, behind a smaller, quieter
 * dot: the timeline still marks its place without competing with the talks
 * either side of it for attention.
 */
.agenda__item--compact { padding-bottom: clamp(1.1rem, 2vw, 1.5rem); }

.agenda__item--compact .agenda__dot {
  left: 2px;
  top: 0.4rem;
  width: 8px;
  height: 8px;
  background: var(--slate-400);
}

.agenda__item--compact .agenda__line {
  margin: 0;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--slate-500);
}

.agenda__item--compact .agenda__detail { margin-top: 0.15rem; }

/* ==========================================================================
   Event photos, on the event's own page
   ========================================================================== */

.event-shots {
  /* .section__head carries no bottom margin — elsewhere the element after it
     brings its own — so without this the display type's descenders run into the
     first row of photos. */
  margin-top: clamp(1.5rem, 3vw, 2.2rem);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.9rem;
}

.event-shots__item {
  appearance: none;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--r-sm);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  display: block;
  box-shadow: var(--shadow-sm);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.event-shots__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.event-shots__item:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }

/* Keyboard users get the same affordance as the pointer hover. */
.event-shots__item:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 3px;
}

@media (max-width: 600px) {
  .event-shots { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
}

/* --------------------------------------------------------------------------
   Leaders Hub filter bar

   Sits above the directory grid. Laid out as a row that wraps, with the search
   field given room to grow and the dropdowns sized to their content, so adding
   a third filter later does not need the columns re-planned.
   -------------------------------------------------------------------------- */
/*
 * A grid rather than a wrapping flex row. Flex packed the controls greedily and
 * broke unevenly in the middle of the range — at 768px it put the search and
 * one dropdown on the first line, the second dropdown alone on the next and the
 * buttons alone on a third. auto-fit gives every control the same width and a
 * predictable number of columns: four on a desktop, three around a tablet, two
 * on a large phone, one on a small one.
 */
.leaders-filter {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  align-items: end;
  gap: 1rem;
  margin-bottom: 2rem;
  padding-bottom: 1.75rem;
  border-bottom: 1px solid var(--line-soft);
}

.leaders-filter__field {
  display: grid;
  gap: 0.4rem;
  min-width: 0;
}

.leaders-filter__label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--slate-700);
}

.leaders-filter input[type="search"],
.leaders-filter select {
  width: 100%;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #fff;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--ink-900);
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.leaders-filter input[type="search"]::placeholder { color: var(--slate-400); }

.leaders-filter input[type="search"]:focus,
.leaders-filter select:focus {
  outline: none;
  border-color: var(--blue-500);
  box-shadow: 0 0 0 4px var(--blue-100);
}

.leaders-filter__actions {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.leaders-filter__clear {
  font-size: 0.9rem;
  color: var(--slate-500);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.leaders-filter__clear:hover,
.leaders-filter__clear:focus-visible { color: var(--ink-900); }

.leaders-count {
  margin: 0 0 1.5rem;
  font-size: 0.9rem;
  color: var(--slate-500);
}

@media (max-width: 640px) {
  .leaders-filter { gap: 0.9rem; }
  .leaders-filter__actions { justify-content: space-between; }
  /* Full width when it is on a row of its own, rather than a stub of a button. */
  .leaders-filter__actions .btn { flex: 1 1 auto; text-align: center; }
}

/* --------------------------------------------------------------------------
   Leaders archive tiles

   The directory card: a large portrait with the name under it. Separate from
   .person, which the front page uses and which carries role, highlights and
   tags — a reader scanning a directory wants the face, and the rest belongs on
   the profile.
   -------------------------------------------------------------------------- */
.leader-tile {
  /* Anchors the stretched link below. */
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--line-soft);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

/* The whole tile is the target, not just the name.
   Measured on a phone the tile is 350x503 while its only link — the name — was
   148x23, so the portrait filling most of the card did nothing when tapped.
   Stretching the existing link keeps one entry in the accessibility tree and
   one destination, rather than wrapping the card in a second duplicate link. */
.leader-tile__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Anything else interactive has to sit above that overlay, or the stretched
   link would swallow it. */
.leader-tile__linkedin {
  position: relative;
  z-index: 2;
}

.leader-tile:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }

/* The name is the link to the profile; the portrait and the LinkedIn icon are
   their own targets. */
.leader-tile__link {
  color: inherit;
  text-decoration: none;
  min-width: 0;
}

/* With a photo the portrait is a button that opens the full-screen viewer. */
button.leader-tile__media {
  appearance: none;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  font: inherit;
  cursor: zoom-in;
}

button.leader-tile__media:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: -3px;
}

/* 4:5 matches the registered spg-portrait crop (640x800), so the frame shows
   what the editor saw when choosing the image rather than a second crop of it. */
.leader-tile__media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--sand);
}

.leader-tile__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s var(--ease);
}

.leader-tile:hover .leader-tile__media img { transform: scale(1.04); }

/* Stands in for a portrait at full frame size, so a leader without a photo
   leaves a tile the same height as the rest of the row. */
.leader-tile__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6vw, 3.6rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #fff;
  background: linear-gradient(140deg, var(--blue-500), var(--blue-700));
}

/* Name and LinkedIn icon share one row under the portrait. */
.leader-tile__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 1rem 1.15rem 1.15rem;
  /* Padding plus the 2rem LinkedIn icon, so a tile without the icon keeps its
     name on the same baseline as one with it. */
  min-height: calc(2.15rem + 2rem);
}

.leader-tile__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.12rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  text-align: left;
  color: var(--ink-900);
}

.leader-tile__link:hover .leader-tile__name { color: var(--blue-600); }

/* Keyboard users get the same affordance as the pointer hover. */
.leader-tile__link:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 3px;
}

.leader-tile__linkedin {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: #0a66c2;
  background: #e8f1fb;
  transition: color 0.25s var(--ease), background-color 0.25s var(--ease), transform 0.25s var(--ease);
}

.leader-tile__linkedin .spg-icon { width: 1rem; height: 1rem; }

.leader-tile__linkedin:hover,
.leader-tile__linkedin:focus-visible {
  color: #fff;
  background: #0a66c2;
  transform: scale(1.08);
}

.leader-tile__linkedin:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 2px;
}

/* One across on phones, which .grid-4 already does at <=620px — no override
   here, so the tiles follow the same breakpoints as every other grid. The
   portrait gets the full column width, which is the point of this layout. */

/* --------------------------------------------------------------------------
   Post byline

   These articles are bylined pieces by named practitioners, so the author is
   the credential and takes the place a featured image used to hold. Where the
   author also has a Leaders profile the name links to it, which is why it is
   styled as a link rather than as quiet meta text.
   -------------------------------------------------------------------------- */
.post__byline {
  margin: 0.15rem 0 0;
  font-size: 0.86rem;
  line-height: 1.4;
  color: var(--slate-500);
}

.post__byline-label {
  color: var(--slate-400);
}

.post__byline-name {
  font-weight: 600;
  color: var(--ink-900);
}

a.post__byline-name {
  color: var(--blue-600);
  text-decoration: none;
}

a.post__byline-name:hover {
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

/* --------------------------------------------------------------------------
   Article page

   The byline, date and category now sit in the hero with the title, so the
   reader has the piece's credentials before the first paragraph rather than
   finding them adrift above the body.
   -------------------------------------------------------------------------- */

/* The category as the hero's eyebrow, and clickable. */
.eyebrow--link { text-decoration: none; }
.eyebrow--link:hover { color: var(--amber-400); }

/* An article title is a sentence, not a label.

   It was set at the shared hero size — 62px, the same as a page called "About" —
   where a five-word page title fits on one line but a 92-character article title
   runs to three and makes a 500px band before the reader reaches a word of the
   piece.

   No max-width: the title runs the full container. At this size that is roughly
   57 characters a line, which a heading carries comfortably — and it puts the
   longest of these titles on two lines rather than the three a narrower measure
   forced. */
.single-post .page-hero h1 {
  font-size: clamp(1.85rem, 3.4vw, 2.5rem);
  line-height: 1.16;
}

.single-post .page-hero {
  padding-block: clamp(2.4rem, 4.5vw, 3.4rem) clamp(2rem, 3.5vw, 2.8rem);
}

.article-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 1rem;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.62);
}

/* The byline is a block on the cards; inline here, beside the date. */
.article-meta .post__byline { margin: 0; font-size: inherit; color: inherit; }
.article-meta .post__byline-label { color: rgba(255, 255, 255, 0.45); }
.article-meta .post__byline-name { color: #fff; }
.article-meta a.post__byline-name { color: var(--amber-400); }
.article-meta a.post__byline-name:hover { color: #fff; }
.article-meta__sep { color: rgba(255, 255, 255, 0.3); }

/* A touch wider than the default measure: these are short reads, and the
   narrower column left an awkward column of white beside a tall sidebar. */
.prose--article { font-size: 1.04rem; line-height: 1.72; }
.prose--article > * + * { margin-top: 1.35em; }

/* Section headings inside an article, smaller than .prose's default h3.
   At the shared size they ran 1.8x the body and wrapped onto two lines in this
   column, which reads as a second title rather than a signpost within the
   piece. The space above them does the separating instead. */
.prose--article h3 {
  font-size: 1.45rem;
  line-height: 1.3;
  margin-top: 2.2em;
  margin-bottom: 0.55em;
}

.prose--article h2 {
  font-size: 1.7rem;
  margin-top: 2.2em;
  margin-bottom: 0.55em;
}

/* --------------------------------------------------------------------------
   Author card
   -------------------------------------------------------------------------- */
.author-card {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 1.5rem);
  align-items: start;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  background: var(--sand);
}

.author-card__media {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(140deg, var(--blue-500), var(--blue-700));
  display: flex;
  align-items: center;
  justify-content: center;
}

.author-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }

.author-card__initials {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 600;
  color: #fff;
}

.author-card__label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--slate-400);
}

.author-card__name {
  margin: 0.35rem 0 0;
  font-family: var(--font-display);
  font-size: 1.22rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.author-card__name a { color: var(--ink-900); text-decoration: none; }
.author-card__name a:hover { color: var(--blue-600); }

/* Not uppercased, unlike the role on a leader card. These roles run long —
   "Chief Mentor, SPG Leaders | Strategic Foresight & Future Readiness" — and
   set in caps at that length the line shouts and is harder to read. */
.author-card__role {
  margin: 0.25rem 0 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--blue-600);
}

.author-card__bio {
  margin: 0.7rem 0 0;
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--slate-700);
}

.author-card .link-arrow { margin-top: 0.8rem; }

@media (max-width: 560px) {
  .author-card { grid-template-columns: 64px minmax(0, 1fr); }
  .author-card__media { width: 64px; height: 64px; }
  .author-card__initials { font-size: 1.25rem; }
}

/* --------------------------------------------------------------------------
   Sidebar

   An article runs far longer than its widgets, which left the sidebar's column
   empty for most of the scroll. Sticking it keeps the events and the join
   prompt in view instead of stranding them at the top.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .single .layout__aside,
  .blog .layout__aside,
  .archive .layout__aside {
    position: sticky;
    top: calc(var(--header-h, 72px) + 1.5rem);
    align-self: start;
  }
}

/* --------------------------------------------------------------------------
   Article disclaimer

   Legal small print, so it is set quieter and smaller than the article — present
   and readable, without competing with the writing above it.
   -------------------------------------------------------------------------- */
.post-disclaimer {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid var(--line-soft);
}

.post-disclaimer__title {
  margin: 0 0 0.5rem;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--slate-400);
}

.post-disclaimer__text {
  margin: 0;
  /* Its own measure, not the article's. It fills the same column as the body
     text but at 0.82rem, so the same width carries far more characters — about
     108 against the article's 85 on a wide monitor, which is a long way past a
     comfortable line for small print. */
  max-width: 80ch;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--slate-500);
}

/* --------------------------------------------------------------------------
   Page sign-off

   For a closing line that is a promise rather than a sentence — the About
   page ends on the brand's own two lines. Set apart above a rule so it reads
   as a sign-off instead of trailing off as another paragraph.
   -------------------------------------------------------------------------- */
.prose .about__close {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 2px solid var(--amber-400);
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  line-height: 1.45;
  color: var(--ink-900);
}

.prose .about__close strong {
  display: block;
  font-weight: 600;
}

.prose .about__close br + * ,
.prose .about__close {
  font-weight: 400;
}

/* --------------------------------------------------------------------------
   Event registration dialog
   -------------------------------------------------------------------------- */

/* Hidden until the script owns it, so a browser without JavaScript never shows
   a dialog it has no way to close. */
.event-dialog[hidden] { display: none; }

.event-dialog {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 2.5rem);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.event-dialog.is-open { opacity: 1; }

.event-dialog__backdrop {
  position: absolute;
  inset: 0;
  background: rgb(8 17 29 / 0.72);
  backdrop-filter: blur(3px);
}

.event-dialog__panel {
  position: relative;
  width: min(100%, 640px);
  /* The form is long; the panel scrolls rather than the page behind it, and
     never grows past the screen. */
  max-height: min(88vh, 900px);
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: var(--r-lg);
  background: var(--paper);
  box-shadow: var(--shadow-lg, 0 24px 60px rgb(8 17 29 / 0.3));
  transform: translateY(12px);
  transition: transform 0.25s var(--ease, ease);
}

.event-dialog.is-open .event-dialog__panel { transform: none; }

.event-dialog__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: grid;
  place-items: center;
  /* A comfortable target, and the same size the touch audit asks of controls. */
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--slate-500);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}

.event-dialog__close:hover,
.event-dialog__close:focus-visible { background: var(--sand); color: var(--fg); }

.event-dialog__title { margin: 0.5rem 0 0.35rem; font-size: clamp(1.4rem, 3.2vw, 1.9rem); }
.event-dialog__when { margin: 0 0 1.4rem; color: var(--slate-500); font-size: 0.94rem; }
.event-dialog__when:empty { display: none; }

/* The page behind must not scroll while the dialog is open, or a phone drifts
   the content away underneath it. */
.has-dialog { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .event-dialog,
  .event-dialog__panel { transition: none; }
  .event-dialog__panel { transform: none; }
}

/* --------------------------------------------------------------------------
   Brokered introductions

   The connect form on a leader's own page. It is also where the Connect button
   points when JavaScript is unavailable, so it has to stand on its own as a
   section rather than read as an afterthought under the biography.
   -------------------------------------------------------------------------- */
.leader-connect {
  border-top: 1px solid var(--line-soft);
}

.leader-connect__title {
  margin: 0.4rem 0 0.6rem;
}

.leader-connect__note {
  margin: 0 0 1.75rem;
}

.leader-connect__form {
  max-width: 34rem;
}

/*
 * The gated tile control is the same size and shape as the ungated one — it
 * still reads as "this leader is on LinkedIn". What changes is what it does,
 * which the accessible name carries ("Request an introduction to ..."), so the
 * two are not made to look like different features.
 */
.leader-tile__linkedin--gated {
  cursor: pointer;
}
