/**
 * Panel Sections — parts/elements/panel-sections.php and
 * parts/elements/panel-step-timeline.php.
 *
 * A small library of content components (rich text, note box, accent
 * callout, media + text, card pair, step timeline) that editors mix inside
 * a single tab panel. Deliberately its own file rather than living in
 * css/blocks/tabs-rail.css: these components are panel-agnostic — they
 * render from both the rail and classic tab variants (parts/page/
 * block-tabs-rail.php and parts/page/block-tabs.php) — while tabs-rail.css
 * is 370+ lines of rail-specific mechanics (grid areas, sticky offsets,
 * the mobile scroller). Mixing them would make the rail file the de facto
 * home of unrelated content components.
 *
 * Loads after css/style.css AND after css/blocks/tabs-rail.css (functions.php
 * registers this file last), so nothing here needs !important even where it
 * overlaps tabs-rail.css's now-scoped `h3:not([class])` / `h4:not([class])`
 * rules.
 *
 * Font sizes are rem against a 10px root, not the --text-* tokens: style.css
 * sets html { font-size: 62.5% } so 1rem = 10px, and the --text-* scale
 * (authored against a 16px root) would render ~37% small here. The --space-*
 * tokens are already px and are safe to use directly. Same convention as
 * css/blocks/pillar-timeline.css and css/blocks/apply-panel.css.
 */

/* ---- section rhythm ---------------------------------------------------- */

.ps > * + * {
  margin-top: var(--space-8);
}

@media (max-width: 767px) {
  .ps > * + * {
    margin-top: var(--space-6);
  }
}

/* Safety net for the <ul>/<ol> layouts (card_pair, step_timeline): if one
   opens a section, there's no preceding sibling for .ps > * + * to match,
   so the browser's own list margin would otherwise show through. */
.ps > :first-child {
  margin-top: 0;
}

/* ---- rich text ---------------------------------------------------------
   Colour and measure only — font-size is left to style.css's WYSIWYG `p`
   rule (2rem). Overriding it here would diff every other Scholars page's
   existing tab copy for no design reason; this component only exists to
   let editors split the SAME copy across several sections instead of one
   long field. */

.ps__rich {
  color: var(--color-grey-700);
  max-width: 68ch;
}

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

.ps__rich > *:last-child {
  margin-bottom: 0;
}

.ps__rich a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.ps__rich a:hover {
  color: var(--color-brand-red-dark);
}

/* ---- note box ------------------------------------------------------------
   Grey caveat band — same treatment as .ap__footnote
   (css/blocks/apply-panel.css). */

.ps__note {
  background-color: var(--color-grey-100);
  padding: var(--space-6);
  font-size: 1.6rem;
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
}

.ps__note p {
  margin: 0;
}

.ps__note p + p {
  margin-top: var(--space-3);
}

.ps__note a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

@media (max-width: 575px) {
  .ps__note {
    padding: var(--space-4);
  }
}

/* ---- accent callout ------------------------------------------------------
   The red-left-stripe idiom already used for a WYSIWYG h4
   (css/blocks/tabs-rail.css's h4:not([class]) rule), scaled up here from a
   single heading to a whole block: a kicker (.c-eyebrow) plus body copy. The
   kicker is a <p>, never a heading — "Transfer credit" labels an aside, it
   does not open a document section.

   The full hairline border (same --border-hairline idiom as .ps__card,
   below) plus the thicker red left edge — an outlined box, not just a
   stripe — matches the reference callouts (e.g. "Transfer credit",
   "Visas are your responsibility"). */

.ps__callout {
  border: 1px solid var(--border-hairline, var(--color-grey-300));
  border-left: 3px solid var(--color-brand-red);
  padding: var(--space-6);
}

.ps__callout-kicker {
  font-size: 1.4rem;
  color: var(--color-brand-red);
  margin: 0 0 var(--space-3);
}

/* For callouts authored with a heading typed directly into the content
   wysiwyg (no separate kicker field used) instead of a plain lead sentence.
   A bare, classless <h4> here would otherwise pick up
   .tabs-rail__panel h4:not([class]) from tabs-rail.css — a second red
   left-edge stacked on top of .ps__callout's own, redundant since the
   callout box already carries one. Same size/weight as .ps__card-title,
   just without a border, so the class opts out of that shared rule. */
.ps__callout-heading {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: var(--weight-bold);
  color: var(--nu-cool-black);
  margin: 0 0 var(--space-3);
}

.ps__callout-body {
  font-size: 1.7rem;
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
}

.ps__callout-body p {
  margin: 0;
}

.ps__callout-body p + p {
  margin-top: var(--space-3);
}

.ps__callout-body a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

@media (max-width: 575px) {
  .ps__callout {
    padding: var(--space-4);
    padding-left: var(--space-4);
  }
}

/* Neutral tone — same box, dark left edge instead of red. For asides that
   are not urgent/flagged (e.g. a plain aligning-expectations note), so the
   red edge stays reserved for callouts that actually need the accent. */
.ps__callout--neutral {
  border-left-color: var(--nu-cool-black);
}

.ps__callout--neutral .ps__callout-kicker {
  color: var(--nu-cool-black);
}

/* ---- cta note ------------------------------------------------------------
   A grey well (same background as .ps__note) pairing body copy with a
   single CTA button — e.g. "Visit the Family Hub to get started." Text and
   button sit side by side above 767px so the button doesn't get lost below
   a long paragraph; below that they stack. */

.ps__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  background-color: var(--color-grey-100);
  padding: var(--space-6);
}

.ps__cta-body {
  font-size: 1.6rem;
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
}

.ps__cta-body p {
  margin: 0;
}

.ps__cta-body p + p {
  margin-top: var(--space-3);
}

.ps__cta-body a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.ps__cta-action {
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .ps__cta {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }
}

@media (max-width: 575px) {
  .ps__cta {
    padding: var(--space-4);
  }
}

/* ---- media + text ----------------------------------------------------
   1.2fr/1fr approximates a 55/45 split; minmax(0, …) on both tracks stops a
   long unbroken string (a URL, an email address) from blowing out its
   track past its equal share — same guard css/blocks/pillar-timeline.css
   documents for .plt__list. Body sits before the figure in the DOM, so no
   mobile order: swap is needed — it already reads body-then-image stacked. */

.ps__media-text {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--space-10);
  align-items: start;
}

.ps__mt-body > *:first-child {
  margin-top: 0;
}

.ps__mt-body a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.ps__mt-figure {
  margin: 0;
}

.ps__mt-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-image);
}

.ps__mt-caption {
  margin-top: var(--space-3);
  font-size: 1.4rem;
  font-style: italic;
  line-height: var(--leading-normal);
  color: var(--color-grey-700);
}

@media (max-width: 1199px) {
  .ps__media-text {
    gap: var(--space-8);
  }
}

/* Stacks at the same 991px breakpoint the rail itself flips to a top strip
   at, so the panel regains its full width exactly when the two columns
   would otherwise get too narrow to hold a caption comfortably. */
@media (max-width: 991px) {
  .ps__media-text {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }
}

/* ---- card pair ---------------------------------------------------------
   Hairline-bordered cards — same idiom as .cc__card / .cc__grid
   (style.css's Contact Cards component). */

/* margin-top is deliberately left unset here, not zeroed — it needs to
   inherit .ps > * + *'s margin-top when a card_pair follows another
   section (a zeroed margin-top on .ps__cards has equal specificity to that
   rule and, being later in the file, silently wins, collapsing the gap
   between e.g. an accent_callout and the cards below it). .ps > *:first-child
   below covers the one case that needs an explicit zero: a browser's
   default <ul> margin when card_pair opens the section. */
.ps__cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  margin-bottom: 0;
  padding: 0;
  list-style: none;
}

/* Kills style.css's `ol li` / `ul li` counter-glyph pseudo-element — this
   list draws no marker of its own. */
.ps__card::before {
  content: none;
}

.ps__card {
  margin: 0;
  padding: var(--space-6);
  border: 1px solid var(--border-hairline, var(--color-grey-300));
  background-color: var(--color-brand-white);
}

/* Highlighted variant — a card carrying a kicker (e.g. "Urgent situations")
   flips its border red instead of grey. No tint fill: the reference keeps a
   white background and lets the red border carry the emphasis, matching
   .ps__callout's red-edge-on-white treatment rather than introducing a
   second, tinted alert style. */
.ps__card--highlight {
  border-color: var(--color-brand-red);
}

.ps__card-kicker {
  font-size: 1.4rem;
  color: var(--color-brand-red);
  margin: 0 0 var(--space-3);
}

.ps__card-title {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--nu-cool-black);
  margin: 0 0 var(--space-3);
}

.ps__card-body {
  font-size: 1.6rem;
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
}

.ps__card-body p {
  margin: 0;
}

.ps__card-body p + p {
  margin-top: var(--space-3);
}

/* overflow-wrap: anywhere is load-bearing, not decorative — an address like
   newyorkcityadvising@northeastern.edu (36 characters, no break opportunity)
   is
   wider than a card's content box at 375px without it (WCAG 1.4.10). */
.ps__card-body a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

.ps__card-action {
  margin-top: var(--space-4);
}

/* A link-only card (no title, no body — see panel-sections.php's card_pair
   filter) has .ps__card-action as its sole child; without this the button
   sits var(--space-4) below empty space instead of flush with the card's
   own padding. Same :first-child-reset idiom as .git__label above. */
.ps__card-action:first-child {
  margin-top: 0;
}

@media (max-width: 1199px) {
  .ps__cards {
    gap: var(--space-4);
  }
}

/* Stacks at 767px, not .cc__grid's 575px: these cards sit inside a panel
   that has already lost width to the rail/container, so two ~300px cards
   at 768px read fine while two ~170px cards would not. */
@media (max-width: 767px) {
  .ps__cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- subsection ----------------------------------------------------------
   A minor heading within a tab (e.g. "Northeastern Traditions" inside
   Community and Activities), set off from what precedes it by a hairline
   rule rather than a bordered box — this is a division within the panel's
   own flow, not a separate callout or card. */

.ps__subsection {
  border-top: 1px solid var(--border-hairline, var(--color-grey-300));
  padding-top: var(--space-6);
}

.ps__subsection-heading {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--nu-cool-black);
  margin: 0 0 var(--space-3);
}

.ps__subsection-body {
  font-size: 1.6rem;
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
}

.ps__subsection-body p {
  margin: 0;
}

.ps__subsection-body p + p {
  margin-top: var(--space-3);
}

.ps__subsection-body a {
  color: var(--color-brand-red);
  text-decoration: underline;
  overflow-wrap: anywhere;
}

/* ---- step timeline -------------------------------------------------------
   parts/elements/panel-step-timeline.php. Technique borrowed from
   css/blocks/pillar-timeline.css (see that element's header comment for the
   four specific tricks reused) and re-scaled: three columns inside a panel
   that has already lost 180-260px + a gap to the rail, not five full-bleed
   page columns. */

/* margin-top intentionally unset, not zeroed — same reasoning as
   .ps__cards above: it needs to inherit .ps > * + *'s margin-top when a
   step_timeline follows another section. */
.pst__list {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  column-gap: var(--space-8);
  align-items: start;
  margin-bottom: 0;
  padding: 0;
  list-style: none;
}

/* One continuous rule on the list itself, not a border-top per item — a
   per-item border breaks at every column gap. */
.pst__list::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background-color: var(--color-grey-300);
}

.pst__item {
  position: relative;
  padding: var(--space-8) 0 0;
  margin: 0;
}

/* Kills style.css's ol li counter-glyph pseudo-element — this list draws
   its own marker, not a numbered glyph. */
.pst__item::before {
  content: none;
}

/* Marker hangs off the item's own origin so it lands on the item's start
   edge in both orientations; translate pulls it onto the hairline. */
.pst__marker {
  position: absolute;
  top: 0;
  left: 0;
  width: 12px;
  height: 12px;
  background-color: var(--nu-cool-black);
  transform: translateY(-50%);
}

.pst__item[aria-current="step"] .pst__marker {
  background-color: var(--color-brand-red);
}

.pst__label {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--nu-cool-black);
  margin: 0 0 var(--space-3);
  overflow-wrap: anywhere;
}

.pst__item[aria-current="step"] .pst__label {
  color: var(--color-brand-red);
}

.pst__desc {
  font-size: 1.6rem;
  font-weight: var(--weight-light);
  line-height: var(--leading-relaxed);
  color: var(--color-grey-700);
  margin: 0;
}

@media (max-width: 1199px) {
  .pst__list {
    column-gap: var(--space-6);
  }

  .pst__label {
    font-size: 1.8rem;
  }
}

/* Vertical rail at <= 991px — same breakpoint the rail itself flips its own
   nav at, and the same value pillar-timeline.css uses for its own
   horizontal/vertical flip. */
@media (max-width: 991px) {
  .pst__list {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
    row-gap: var(--space-8);
  }

  /* Same pseudo-element, rotated into a full-height rail on the left. */
  .pst__list::before {
    top: 0;
    bottom: 0;
    right: auto;
    width: 1px;
    height: auto;
  }

  .pst__item {
    padding: 0 0 0 var(--space-8);
  }

  /* 0.6em, not pillar-timeline's 0.55em: tuned against this component's
     2rem/1.25 label rather than pillar-timeline's 1.4rem kicker — centres
     the square on the label's cap-height instead of sitting slightly high. */
  .pst__marker {
    top: 0.6em;
    left: 0;
    transform: translateX(-50%);
  }
}

@media (max-width: 767px) {
  .pst__list {
    row-gap: var(--space-6);
  }

  .pst__item {
    padding-left: var(--space-6);
  }
}

/* ---- focus -------------------------------------------------------------- */

.ps a:focus-visible,
.pst__list a:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* ---- motion --------------------------------------------------------------
   Nothing in this file animates on its own; css/blocks/tabs-rail.css's
   reduced-motion rule already blanket-kills animation under
   .block-tabs--rail, which is this component's only current parent. */
