/**
 * Semester Timeline — parts/elements/semester-timeline.php
 *
 * Loads after css/style.css (functions.php declares theme-styles as a
 * dependency), so no !important is needed anywhere in here.
 *
 * Sizes are px, not the --text-* tokens: style.css:702 sets
 * html { font-size: 62.5% }, so 1rem is 10px and --text-4xl (2.25rem)
 * would render at 22.5px. The --space-* tokens are already px and are
 * safe to use.
 */

.block-semester-timeline {
  margin: var(--space-16) 0;
}

/* Nested inside a tab panel: kill the doubled Bootstrap gutter from the
   .container this element opens inside block-tabs' own .container. */
.block-semester-timeline--in-tab {
  margin: var(--space-8) 0 0;
}

.block-semester-timeline--in-tab .container {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.st__eyebrow {
  margin: 0 0 var(--space-4);
}

/* ---- control row: arrow | centred label | arrow ---------------------- */

.st__controls[hidden] {
  display: none;
}

.st__controls {
  display: grid;
  grid-template-columns: 44px 1fr 44px;
  align-items: center;
  gap: var(--space-4);
  margin: 0 0 var(--space-8);
}

.st__arrow {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px is the WCAG 2.5.8 target minimum; the glyph itself is thin. */
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-brand-red);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: color 160ms ease, transform 160ms ease;
}

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

.st__arrow--prev:hover {
  transform: translateX(-3px);
}

.st__arrow--next:hover {
  transform: translateX(3px);
}

.st__arrow:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* Selection wraps, so neither arrow ever becomes a no-op and there is no
   disabled state to style. */

/* ---- tablist: every tab stacked in one grid cell --------------------
   Stacking means the tablist's width is the width of the LONGEST label,
   so the centred label does not shift horizontally when the period
   changes (e.g. "Fall 2026" -> "Spring 2027").                        */

.st__tablist {
  display: grid;
  justify-items: center;
  align-items: center;
}

.st__tab {
  grid-area: 1 / 1;
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  padding: var(--space-2) var(--space-4);
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-grey-700);
  cursor: pointer;
  white-space: nowrap;
}

/* visibility, NOT display:none — display:none would strip the unselected
   tabs from the accessibility tree and AT would report a 1-tab tablist.
   They are tabindex="-1" in the markup, so they are not Tab-reachable. */
.st__tab[aria-selected="false"] {
  visibility: hidden;
  pointer-events: none;
}

.st__tab[aria-selected="true"] {
  visibility: visible;
  color: var(--color-brand-black);
}

.st__tab:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* ---- panels ---------------------------------------------------------- */

.st__panel[hidden] {
  display: none;
}

.st__panel:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* :not([hidden]) on the LEFT side matters: the plain sibling combinator
   would match "any .st__panel preceded by a .st__panel", full stop, even
   when that preceding panel is display:none. That silently added a
   margin-top to whichever panel JS made active whenever it wasn't the
   first one — Fall 2026 (index 0, no preceding sibling) rendered flush,
   Spring 2027 (index 1, a hidden-but-still-adjacent sibling) always got an
   extra gap on top of it, so the heading and rows visibly dropped lower
   every time you switched. Requiring the preceding panel to be visible
   means the gap only ever appears in the no-JS stacked fallback, which is
   the only situation where two panels are genuinely adjacent on screen. */
.st__panel:not([hidden]) + .st__panel {
  margin-top: var(--space-16);
}

.st__period {
  margin: 0 0 var(--space-8);
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-brand-black);
}

/* Once the switcher is on screen it already names the period ("FALL 2026",
   centred between the arrows), so the big display heading immediately under
   it is the same words twice. Hide it — but only in that exact situation.

   Keyed off .st__controls:not([hidden]) rather than removed from the
   template, because the control row ships [hidden] and only
   js/semester-timeline.js:134 takes that attribute off. Delete the <h2> and
   the two cases where the switcher never appears lose their only label:

     - JS off, blocked or broken. Every panel renders stacked (that fallback
       is real enough that .st__panel:not([hidden]) + .st__panel above exists
       to space it), so without this heading you get Fall's rows and Spring's
       rows in one undifferentiated run with nothing saying which is which.
     - A single period. $is_switchable is false, no control row is printed at
       all, and this heading is the only thing naming the semester.

   Both keep the visible heading because neither matches this selector.

   Visually hidden rather than display:none: the panel takes its accessible
   name from its tab, so this is not needed for that — but headings are a
   primary screen-reader navigation mode, and dropping it would leave someone
   skimming by heading going from "Dates and Timelines" straight into a list
   of dates with no semester in between. The cost is hearing the period name
   twice on entering a panel, which is the better trade. */
.st__controls:not([hidden]) ~ .st__panel .st__period {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- rows ------------------------------------------------------------ */

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

.st__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-8);
  min-height: 96px;
  padding: var(--space-8) var(--space-10);
}

/* A visible gap between rows reads as a stack of distinct cards — matching
   the reference — rather than a zebra-striped table. */
.st__row + .st__row {
  margin-top: var(--space-2);
}

.st__row-event {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
}

.st__row-date {
  flex: 0 0 auto;
  font-size: 16px;
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  text-align: right;
  white-space: nowrap;
}

/* Three-step background cycle: black -> brand red -> light grey.
   --color-grey-100 (#F5F5F5) was tried first and rejected: the tab panel
   this renders inside is #f7f7f7 (style.css:7323), two points off, so the
   grey row read as no card at all — see the "invisible row" bug. Contrast
   with --color-grey-200 against the page: #FFF on #000 = 21:1; #FFF on
   #C8102E = 5.9:1; #000 on #EBEBEB = 17.5:1 — all pass AA for normal text. */
.st__row:nth-child(3n + 1) {
  background-color: var(--color-brand-black);
  color: var(--color-brand-white);
}

.st__row:nth-child(3n + 2) {
  background-color: var(--color-brand-red);
  color: var(--color-brand-white);
}

.st__row:nth-child(3n + 3) {
  background-color: var(--color-grey-200);
  color: var(--color-brand-black);
}

/* ---- row hover ------------------------------------------------------- */

/* Purely decorative. .st__row is a plain <li> with no link inside, so this
   says "the pointer is here", not "this is clickable" — which is also why it
   stops at 4px and why there is no cursor change, no colour change and no
   matching :focus-within rule. There is nothing here to focus.
 *
   The whole bar moves rather than just its label: these rows are solid
   colour blocks, and sliding the text alone reads as the type coming loose
   from its background. 4px into the gutter that .container leaves at every
   breakpoint, so this cannot push the page into horizontal overflow.
 *
   Behind (hover: hover) because an unguarded :hover sticks on iOS — the row
   you tapped to change tabs would stay shifted until you tapped elsewhere. */
@media (hover: hover) {
  .st__row {
    transition: transform var(--duration-fast) var(--ease-out);
  }

  .st__row:hover {
    transform: translateX(4px);
  }
}

/* ---- responsive ------------------------------------------------------ */

/* Between 576 and 767 the row is still side-by-side but the date must be
   allowed to wrap, or a range like "March 22-April 2" squeezes the event
   text to one word per line. */
@media (max-width: 767px) {
  .st__period {
    font-size: 28px;
  }

  .st__row {
    gap: var(--space-4);
    padding: var(--space-4) var(--space-6);
  }

  .st__row-date {
    white-space: normal;
  }
}

/* Stack below 576. */
@media (max-width: 575px) {
  .st__row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    min-height: 0;
    padding: var(--space-4);
  }

  .st__row-event {
    font-size: 20px;
  }

  .st__row-date {
    text-align: left;
  }

  .st__controls {
    grid-template-columns: 44px 1fr 44px;
    gap: var(--space-2);
  }

  .st__tab {
    font-size: 14px;
    white-space: normal;
  }
}

/* ---- reduced motion -------------------------------------------------- */

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

  .st__arrow--prev:hover,
  .st__arrow--next:hover {
    transform: none;
  }

  /* Same reasoning as the arrows above: the blanket override at
     style.css:716 zeroes transition-duration but never touches the
     transform, so without this the row would still jump 4px — instantly,
     which is more jarring than the animation it replaced. */
  .st__row {
    transition: none;
  }

  .st__row:hover {
    transform: none;
  }

  /* style.css:7472 gives .block-tabs__tab-content an unguarded
     `animation: fadeIn .5s`, which this component inherits when nested in
     a tab. Suppress it here for the timeline's own subtree; fixing the
     tabs block itself is out of scope. */
  .block-semester-timeline,
  .block-semester-timeline * {
    animation: none;
  }
}
