/* ==========================================================================
   home.css — "Grandeur" homepage variant
   University of Bridgeport

   Layered ON TOP of style.css. Only styles the new/reworked homepage
   sections; header, footer, buttons, and the AI sidebar are inherited
   unchanged from style.css so index.html is unaffected.

   Design decisions encoded here:
     - Outfit is the single typeface (brand guide, settled)
     - 0px border-radius everywhere (brand guide, non-negotiable)
     - The diagonal WEDGE from the hero becomes a repeated brand motif
     - Grandeur = scale contrast: oversized numerals + generous air
     - --ub-blue (#00A7E0) is a GRAPHIC colour only; it fails WCAG AA on
       white at 2.76:1. Text uses --ub-blue-text (#0A6E8F, 5.8:1).
   ========================================================================== */

:root {
  /* Accessible text-safe blue. Fills/rules keep the pure brand blue. */
  --ub-blue-text: #0A6E8F;
  --ub-purple-deep: #2A1240;
  --ink: #1B1023;

  /* The signature wedge angle, used consistently across sections. */
  --wedge: 4.5vw;

  --section-pad: 120px;

  /* ---- Hero / stats-bar interlock -------------------------------------
     The proof strip rides UP over the hero's bottom edge, and the slide
     switcher sits AT that bottom edge, so the two collide unless their
     positions are derived from one another. Expressed as variables so a
     change to the overlap can't silently re-introduce the overlap bug.  */
  --proof-overlap: 56px;   /* how far the stats bar rides over the hero  */
  --switcher-h: 38px;      /* height of the switcher block               */
  --switcher-gap: 26px;    /* clearance between switcher and stats bar   */
}
/* --switcher-h was 56px while each control stacked a numeral over its label.
   ub-elements.css now hides .hs-num above 1100px, so a control is 15px of
   clearance under its hairline plus one 19px label line = 34px. 38px keeps a
   few pixels of slack without over-reserving hero copy space, which is what
   this variable spends 1:1. */

/* The body typeface, from the token rather than from a literal.
   This rule is at (0,1,1) against style.css's `body` at (0,0,1), so it WINS —
   which meant that while it named Outfit directly, changing the typeface at
   Appearance → Theme Design left the homepage, programme pages and the brand
   guide on Outfit while the rest of the site changed. The one edit that makes
   the setting actually global. */
body.v2 {
  font-family: var(--font-primary);
  background: var(--white);
}

/* Accessible blue for BODY-COPY links only.
   Deliberately NOT a blanket `.v2 a` rule: at (0,2,1) that outranks
   .utility-left a, .main-nav > ul > li > a, .mega-column ul li a and
   .links-col a from style.css, which repaints the whole header and footer
   blue. Header, footer, and dark sections keep their own colours. */
.v2 .pathways a:not([class*="btn"]):not(.pathway-card),
.v2 .centennial2 a:not([class*="btn"]),
.v2 .centers a:not([class*="btn"]):not(.center-card),
.v2 .apply2 a:not([class*="btn"]),
.v2 .proof-strip a:not([class*="btn"]) {
  color: var(--ub-blue-text);
}
/* Duplicate of the rule in ub-elements.css; same reason for the token. */
.v2 .btn { border-radius: var(--btn-radius); }



/* --------------------------------------------------------------------------
   Centennial ribbon — MOVED TO style.css
   The ribbon is rendered by header.php on every page, but this sheet loads
   only on the homepage and program pages, so everywhere else it rendered
   unstyled: default text, no purple ground, full-width. It now lives with the
   rest of the site chrome in style.css.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   HERO — cinematic wedge
   -------------------------------------------------------------------------- */
/* A GRID STACK, not a fixed-height box.

   Every slide is placed in the same grid area, so they still cross-fade over
   one another — but they are IN FLOW, so the tallest slide's copy sets the row
   height and the hero grows to fit it. That is what turns the clearance below
   into a guarantee instead of a hope.

   The old rule set an explicit `height`, and .hero2-body reserved the
   switcher's space with padding-bottom while centring its copy inside what was
   left. Centring splits any overflow EVENLY top and bottom, so the moment the
   copy grew taller than height − padding-bottom, half of it escaped the
   reserve and landed on the switcher. The reserve was honoured only while it
   was not needed. Measured across 270 viewport sizes, 67 overlapped — worst by
   53px at 901px of viewport height, the first pixel where the max-height:900px
   mitigation below stops applying.

   clamp() reproduces the old height/min-height/max-height triple exactly, but
   as a FLOOR rather than a ceiling: 100vh minus the 3-tier header so the
   switcher starts above the fold, never shorter than 600px, and not stretching
   past 820px on a tall monitor. Copy that needs more room than that now pushes
   the hero taller instead of pushing itself over the controls.

   WHY 246px, AND WHY THE FLOOR CAME DOWN TO 430px.
   The subtrahend used to be 236px — the header (211px) plus 25px. It now buys
   the header plus 35px of white BELOW the door band, because the band's bottom
   edge and the hero's bottom edge are the same line: ub-sections.css sets
   --doors-overlap to the band's own height, so the band rides up exactly its
   own height and its last pixel lands on the hero's last pixel. Whatever this
   clamp leaves between the hero's bottom and the fold is therefore clearance
   under the band, and 35px is the smallest amount that still reads as a margin
   rather than a slice.

   The 600px floor was sized for six stacked text layers. There are three now
   (headline, one lede, one action row), so 600px stopped being a floor and
   became a stretcher: on a 900px-tall screen it held the hero 130px taller
   than its content needed and pushed the band's clearance to 219px of dead
   white. 430px is the real floor — enough for the tallest three-layer slide
   plus the switcher reserve — and above ~670px of viewport height the middle
   term wins anyway, so the hero tracks the window as it always did. */
.hero2 {
  position: relative;
  display: grid;
  grid-template-areas: 'hero-stack';
  min-height: clamp(430px, calc(100vh - 246px), 820px);
  background: var(--ub-purple-deep);
  overflow: hidden;
}

/* Bottom scrim. The switcher track is wider than the dark panel, so its
   right-hand items sit over photography — this guarantees legibility
   regardless of the slide, and reads as a deliberate cinematic fade. */
.hero2::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 200px;
  background: linear-gradient(to top,
    rgba(42,18,64,0.93) 0%,
    rgba(42,18,64,0.58) 46%,
    rgba(42,18,64,0) 100%);
  z-index: 5;
  pointer-events: none;
}

.hero2-slide {
  /* All slides share one cell, so they overlap for the cross-fade AND the
     tallest one sizes the row. Grid stretch fills the cell, which is what
     `inset: 0` used to do. */
  grid-area: hero-stack;
  /* Still the containing block for .hero2-media and .hero2-watermark, which
     were positioned against the old absolute box. */
  position: relative;
  /* Lets .hero2-body stretch to the row height and push it taller when the
     copy needs more room. A percentage height can only do the first. */
  display: flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1.1s ease;
}
.hero2-slide.active { opacity: 1; visibility: visible; }

/* Right-hand imagery, masked by the signature diagonal */
.hero2-media {
  position: absolute;
  inset: 0 0 0 38%;
  clip-path: polygon(14% 0, 100% 0, 100% 100%, 0 100%);
  overflow: hidden;
}
.hero2-image {
  position: absolute;
  inset: -4%;
  background-size: cover;
  background-position: center;
  transform: scale(1);
}
.hero2-slide.active .hero2-image {
  animation: kenburns 22s ease-out forwards;
}
@keyframes kenburns {
  from { transform: scale(1) translate3d(0,0,0); }
  to   { transform: scale(1.07) translate3d(0, -1.2%, 0); }
}
/* Keeps white hero text legible over any photograph. */
.hero2-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(42,18,64,0.92) 0%,
    rgba(42,18,64,0.42) 34%,
    rgba(42,18,64,0.12) 70%,
    rgba(42,18,64,0.30) 100%);
}

.hero2-body {
  position: relative;
  z-index: 3;
  /* Fills the slide's width, and its own content height feeds back up to the
     grid row. `height: 100%` used to sit here; it locked the box to the hero's
     old fixed height, which is the constraint the overflow escaped from. */
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  /* `safe` degrades to start-alignment instead of splitting the overflow if the
     copy ever does exceed the box — the one-line guard against the exact
     behaviour that caused the original collision. Declared after the plain
     keyword so browsers that do not parse `safe` keep centring. */
  align-items: safe center;
  /* Reserves room for the switcher AND the stats bar that overlaps above it.
     With the hero on a min-height the row now grows to keep this reserve
     intact, so hero copy genuinely cannot run into either. */
  padding-bottom: calc(var(--proof-overlap) + var(--switcher-gap) + var(--switcher-h) + 18px);
}
/* The blue accent is a BORDER on the whole text block, so the badge, headline,
   lede and CTAs all hang off one continuous vertical line. It was previously a
   free-floating 58px stub between the badge and the headline, which read as
   misaligned against everything below it. */
.hero2-inner {
  max-width: 39rem;
  border-left: 3px solid var(--ub-blue);
  padding-left: 32px;
}

.hero2-badge {
  display: inline-block;
  background: var(--white);
  color: var(--ub-purple);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 8px 15px;
  margin-bottom: 26px;
}
/* TWO-AXIS CLAMP, and it replaces a ladder.
   A width-only clamp cannot know that 1366x768 and 1366x1050 are different
   problems, so the height-gated media queries below used to re-declare this
   font-size twice — 3.6vw at ≤900px tall, 3vw at ≤800px — to keep a headline
   sized for a tall window from swallowing a short one. min(5.2vw, 7.4vh) asks
   both questions in one value: whichever axis is scarcer sets the size. That
   deletes the two overrides, and because the shorter axis is usually height on
   a laptop, the headline actually lands LARGER here than the ladder allowed
   (56.8px at 1366x768 against 41px) while still shrinking on a 720p screen. */
.hero2-title {
  color: var(--white);
  font-size: clamp(2.6rem, min(5.2vw, 7.4vh), 4.6rem);
  font-weight: 800;
  line-height: 0.96;
  letter-spacing: -0.035em;
}
.hero2-title span {
  display: block;
  font-size: 0.42em;
  font-weight: 300;
  letter-spacing: -0.012em;
  color: rgba(255,255,255,0.9);
  margin-top: 14px;
  line-height: 1.25;
}
.hero2-sub {
  color: rgba(255,255,255,0.9);
  font-size: 1.2rem;
  /* Was 400 by inheritance. One short lede under a 57px headline reads better
     light than regular — the weight contrast is what makes two layers feel like
     two layers now that there is no badge and no accent line between them. */
  font-weight: 300;
  line-height: 1.6;
  margin-top: 24px;
  /* 30rem, not 32rem: every slide's lede is one clause, and a narrower measure
     wraps all four to the same two lines instead of three of them to two and
     one to three. */
  max-width: 30rem;
  /* Every slide's copy must begin at the same y. .hero2-body centres the block
     vertically, so a slide whose sub-paragraph wraps to fewer lines than its
     neighbours rides higher — the health-sciences badge sat 15px below the
     other two purely because its sub ran to 2 lines rather than 3.
     Reserving the longest wrap keeps the block a consistent height, so the
     centring lands identically on every slide. In em so it tracks the type size
     rather than being a fixed pixel guess. Two lines now, not three: the
     three-clause paragraphs that needed a 4.8em reserve are gone. */
  min-height: 3.2em;
}
.hero2-ctas {
  display: flex;
  flex-wrap: wrap;
  /* 22px, not 14px. Two actions 14px apart read as one segmented control; the
     wider gap makes the primary button the obvious first stop. */
  gap: 22px;
  align-items: center;
  /* The largest gap in the block, deliberately. Headline→lede is 24px and
     lede→actions is 40px, so the eye is told twice that reading ends and
     choosing begins. */
  margin-top: 40px;
}

/* Oversized centennial watermark — heraldic grandeur, low opacity */
.hero2-watermark {
  position: absolute;
  right: 3vw;
  bottom: -6vh;
  font-size: 34vh;
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.05em;
  color: rgba(255,255,255,0.07);
  z-index: 2;
  pointer-events: none;
  user-select: none;
}


/* Short laptop viewports: tighten the hero so headline, CTAs and switcher
   all still fit between the header and the fold.
   MUCH SHORTER THAN IT WAS, and the deletions are the point:
     • `min-height: 470px` is gone. It was a later declaration than the clamp
       above at equal specificity, so it won outright and pinned the hero to
       470px at every viewport height up to 900px — which now leaves the door
       band 220px short of the fold instead of 35px.
     • The .hero2-title override is gone: min(5.2vw, 7.4vh) already reads the
       height axis, so a second, coarser answer to the same question could only
       disagree with it.
     • .hero2-badge is gone from the fold's content (the centennial ribbon 190px
       directly above already carries the same words), so tuning its margin here
       styled an element that no longer renders.
   What remains is what genuinely differs on a short screen: the switcher's
   clearance, and the two vertical rhythms that are luxuries rather than
   legibility. */
@media (min-width: 1101px) and (max-height: 820px) {
  /* Tighter clearance on short screens; padding-bottom follows from these. */
  :root { --switcher-gap: 20px; }
  .hero2-sub { margin-top: 18px; }
  .hero2-ctas { margin-top: 30px; }
  .hero2-watermark { font-size: 26vh; }
}

/* --------------------------------------------------------------------------
   PROOF STRIP — overlaps the hero edge
   -------------------------------------------------------------------------- */
.proof-strip {
  position: relative;
  z-index: 5;
  margin-top: calc(var(--proof-overlap) * -1);
  padding-bottom: 100px;
}
.college-page-hero + .proof-strip,
.pg-hero + .proof-strip {
  margin-top: -44px;
}
.proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  background: var(--white);
  box-shadow: var(--shadow-lg);
}
.proof-cell {
  padding: 30px 26px;
  border-right: 1px solid #E8ECEE;
  border-top: 4px solid var(--ub-purple);
  transition: var(--transition);
}
.proof-cell:nth-child(even) { border-top-color: var(--ub-blue); }
.proof-cell:last-child { border-right: none; }
.proof-cell:hover { transform: translateY(-6px); }
.proof-num {
  font-size: 2.9rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ub-purple);
}
.proof-label {
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--text-main);
  margin-top: 9px;
  line-height: 1.35;
}
.proof-note {
  font-size: 0.78rem;
  color: var(--text-light);
  margin-top: 6px;
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   OUTCOMES — full-bleed dark band, editorial scale
   -------------------------------------------------------------------------- */
.outcomes {
  background: var(--ink);
  color: var(--white);
  padding: var(--section-pad) 0 90px;
  position: relative;
  overflow: hidden;
}
/* Wedge motif, echoed as a hairline */
.outcomes::before {
  content: '';
  position: absolute;
  top: 0; right: 0;
  width: 46%;
  height: 100%;
  background: linear-gradient(160deg, rgba(89,45,130,0.55) 0%, rgba(89,45,130,0) 62%);
  clip-path: polygon(24% 0, 100% 0, 100% 100%, 0 100%);
  pointer-events: none;
}
.outcomes .container { position: relative; z-index: 2; }

.outcomes-head {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 60px;
  align-items: end;
  padding-bottom: 56px;
  border-bottom: 1px solid rgba(255,255,255,0.14);
}
.outcomes .eyebrow-rule { color: #7FD9F5; }
.mega-figure {
  font-size: clamp(6rem, 15vw, 13.5rem);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: -0.05em;
  color: var(--white);
}
.mega-caption {
  font-size: clamp(1.4rem, 2.3vw, 2.05rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--white);
  margin-top: 12px;
}
.mega-sub {
  font-size: 1rem;
  color: rgba(255,255,255,0.62);
  margin-top: 12px;
  line-height: 1.6;
  max-width: 30rem;
}

.outcomes-splits {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 34px;
}
.split-stat { border-left: 3px solid var(--ub-blue); padding-left: 18px; }
.split-stat .n {
  font-size: 2.5rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--white);
}
.split-stat .l {
  font-size: 0.9rem;
  color: rgba(255,255,255,0.7);
  margin-top: 8px;
  line-height: 1.45;
}

/* Employer roster, reversed */
.employers2 { margin-top: 66px; }
.employers2 h3 {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
  margin-bottom: 30px;
}
.employer-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: rgba(255,255,255,0.12);
}
.employer-name {
  background: var(--ink);
  padding: 26px 20px;
  font-size: 1.22rem;
  font-weight: 700;
  letter-spacing: -0.012em;
  color: rgba(255,255,255,0.82);
  text-align: center;
  transition: var(--transition);
}
.employer-name:hover { color: var(--white); background: rgba(89,45,130,0.5); }

/* --------------------------------------------------------------------------
   PATHWAYS — outcome-first program finder
   -------------------------------------------------------------------------- */
.pathways {
  padding: clamp(2.25rem, 3.5vw, 3.5rem) 0;
  background: var(--bg-light);
}
.ac-colleges + .pathways {
  padding-top: clamp(1rem, 1.75vw, 1.75rem);
}
.pathways-head {
  margin-bottom: clamp(1.5rem, 2.5vw, 2.25rem);
}

.pathway-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-bottom: 2px solid #DEE4E7;
  margin-bottom: clamp(1.5rem, 2.25vw, 2rem);
}
.pathway-tab {
  background: none;
  border: none;
  border-bottom: 4px solid transparent;
  margin-bottom: -3px;
  padding: 15px 26px 15px 0;
  margin-right: 34px;
  font-family: inherit;
  font-size: 1.06rem;
  font-weight: 700;
  color: var(--text-light);
  cursor: pointer;
  transition: var(--transition);
  letter-spacing: -0.01em;
}
.pathway-tab:hover { color: var(--ub-purple); }
.pathway-tab.active { color: var(--ub-purple); border-bottom-color: var(--ub-purple); }

.pathway-panel { display: none; }
.pathway-panel.active { display: block; }

.pathway-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 26px;
}
.pathway-card {
  background: var(--white);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  display: flex;
  flex-direction: column;
  border-bottom: 4px solid transparent;
  transition: var(--transition);
}
.pathway-card:hover {
  transform: translateY(-10px);
  box-shadow: var(--shadow-lg);
  border-bottom-color: var(--ub-blue);
}
.pathway-thumb {
  height: 168px;
  background-size: cover;
  background-position: center;
  position: relative;
}
/* Wedge motif again, as a corner cut on every card */
.pathway-thumb::after {
  content: '';
  position: absolute;
  bottom: 0; right: 0;
  border-style: solid;
  border-width: 0 0 26px 26px;
  border-color: transparent transparent var(--white) transparent;
}
.pathway-body { padding: 22px 22px 24px; flex: 1; display: flex; flex-direction: column; }
.pathway-degree {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ub-blue-text);
}
.pathway-name {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text-main);
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin: 9px 0 14px;
}
.pathway-outcome {
  margin-top: auto;
  padding-top: 15px;
  border-top: 1px solid #EDF1F2;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.pathway-outcome .v {
  font-size: 1.42rem;
  font-weight: 800;
  color: var(--ub-purple);
  letter-spacing: -0.025em;
  line-height: 1;
}
.pathway-outcome .k {
  font-size: 0.74rem;
  color: var(--text-light);
  text-align: right;
  line-height: 1.3;
  font-weight: 600;
}
.pathways-foot {
  margin-top: 44px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
}
.pathways-foot .disclaimer {
  font-size: 0.82rem;
  color: var(--text-light);
  max-width: 34rem;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   SOUND — full-bleed panoramic, 50/50 overlay
   -------------------------------------------------------------------------- */
.sound {
  position: relative;
  min-height: 620px;
  display: flex;
  align-items: center;
  background-image: url('../images/ub-seaside-pano.jpg');
  background-size: cover;
  /* Bias upward so the Sound and Seaside Park stay in frame, not the rooftops.
     NOT background-attachment: fixed — scrolling happens in
     .main-content-wrapper, and `fixed` anchors to the viewport instead,
     which strands the image mid-section. */
  background-position: center 34%;
}
.sound::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(96deg,
    rgba(27,16,35,0.93) 0%,
    rgba(27,16,35,0.78) 38%,
    rgba(27,16,35,0.30) 62%,
    rgba(27,16,35,0.08) 100%);
}
.sound .container { position: relative; z-index: 2; }
.sound-panel { max-width: 40rem; color: var(--white); padding: 90px 0; }
.sound-panel .eyebrow-rule { color: #7FD9F5; }
.sound-panel h2 {
  font-size: clamp(2.4rem, 4.4vw, 4rem);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--white);
}
.sound-panel p {
  font-size: 1.16rem;
  line-height: 1.68;
  color: rgba(255,255,255,0.84);
  margin-top: 22px;
}
.sound-facts {
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: 40px;
  margin-top: 42px;
  justify-content: start;
}
/* Direct children only — a bare `.sound-facts div` also matches the nested
   .n and .l elements, which draws the accent rule three times per stat. */
.sound-facts > div { border-top: 3px solid var(--ub-blue); padding-top: 13px; }
.sound-facts .n {
  font-size: 2.1rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--white);
}
.sound-facts .l {
  font-size: 0.84rem;
  color: rgba(255,255,255,0.66);
  margin-top: 7px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* --------------------------------------------------------------------------
   CENTENNIAL TIMELINE 1927 → 2027
   -------------------------------------------------------------------------- */
.centennial2 {
  padding: var(--section-pad) 0;
  background: var(--white);
  position: relative;
  overflow: hidden;
}
.centennial2 .ghost-year {
  position: absolute;
  top: 40px;
  right: -2vw;
  font-size: 26vw;
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.05em;
  color: rgba(89,45,130,0.045);
  pointer-events: none;
  user-select: none;
}
.centennial2 .container { position: relative; z-index: 2; }

.timeline2 {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0;
  margin-top: 56px;
  border-top: 3px solid #E4E9EB;
}
.tl-node { padding: 0 22px 0 0; position: relative; padding-top: 30px; }
.tl-node::before {
  content: '';
  position: absolute;
  top: -3px; left: 0;
  width: 100%;
  height: 3px;
  background: var(--ub-purple);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s cubic-bezier(0.25,0.8,0.25,1);
}
.tl-node.in-view::before { transform: scaleX(1); }
.tl-node::after {
  content: '';
  position: absolute;
  top: -8px; left: 0;
  width: 13px; height: 13px;
  background: var(--ub-purple);
}
.tl-node:last-child::after { background: var(--ub-blue); }
.tl-year {
  font-size: 1.85rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--ub-purple);
  line-height: 1;
}
.tl-node:last-child .tl-year { color: var(--ub-blue-text); }
.tl-text {
  font-size: 0.92rem;
  color: var(--text-light);
  line-height: 1.5;
  margin-top: 11px;
}
.tl-text strong { color: var(--text-main); font-weight: 700; display: block; margin-bottom: 3px; }

/* --------------------------------------------------------------------------
   CENTERS OF EXCELLENCE — real facilities
   -------------------------------------------------------------------------- */
.centers { padding: var(--section-pad) 0; background: var(--bg-light); }
.centers-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
  margin-top: 52px;
}
.center-card {
  position: relative;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background-size: cover;
  background-position: center;
  text-decoration: none;
}
.center-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(27,16,35,0.93) 0%,
    rgba(27,16,35,0.55) 42%,
    rgba(27,16,35,0.08) 100%);
  transition: var(--transition);
}
.center-card:hover::before { background: linear-gradient(to top, rgba(89,45,130,0.95) 0%, rgba(27,16,35,0.5) 55%, rgba(27,16,35,0.1) 100%); }
.center-body { position: relative; z-index: 2; padding: 30px 28px; }
.center-body .kicker {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #7FD9F5;
}
.center-body h3 {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.02em;
  line-height: 1.18;
  margin: 10px 0 9px;
}
.center-body p {
  font-size: 0.94rem;
  color: rgba(255,255,255,0.78);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   APPLY — numbered steps on the wedge
   -------------------------------------------------------------------------- */
.apply2 { padding: var(--section-pad) 0; background: var(--white); }
.apply2-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: 50px;
}
.apply2-step {
  border-top: 4px solid var(--ub-purple);
  background: var(--bg-light);
  padding: 30px 26px 32px;
  position: relative;
  transition: var(--transition);
}
.apply2-step:hover { transform: translateY(-8px); box-shadow: var(--shadow-md); }
.apply2-step .n {
  font-size: 3.4rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: rgba(89,45,130,0.18);
}
.apply2-step h3 {
  font-size: 1.32rem;
  font-weight: 700;
  color: var(--text-main);
  letter-spacing: -0.02em;
  margin: 10px 0 10px;
}
.apply2-step p { font-size: 0.98rem; color: var(--text-light); line-height: 1.58; }


/* ==========================================================================
   RESPONSIVE
   Breakpoints follow context.md: 1100px then 768px.
   ========================================================================== */
@media (max-width: 1100px) {
  :root { --section-pad: 88px; }

  /* Leaves the grid stack: below 1100px the switcher is a pill rail BELOW the
     copy in normal flow (ub-elements.css), so slides must not share a cell with
     it. display:block restores the stacked document order. */
  .hero2 { display: block; min-height: 0; }
  /* Stacked layout is already on a solid dark panel — the scrim would only
     dim the CTAs. */
  .hero2::after { display: none; }
  .hero2-slide {
    position: relative;
    opacity: 1;
    visibility: visible;
    display: none;
  }
  .hero2-slide.active { display: block; }
  .hero2-media {
    position: relative;
    inset: auto;
    height: 320px;
    clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%);
  }
  .hero2-image { inset: 0; }
  .hero2-body { padding: 46px 0 34px; }
  .hero2-inner { max-width: none; padding-left: 22px; }
  /* The desktop badge-alignment reserve is not needed here: below 1100px the
     hero is height:auto and the body is simply top-padded, so copy already
     starts at a fixed offset whatever its length. Keeping the reserve would
     only add dead space under a short sub-paragraph. */
  .hero2-sub { min-height: 0; }
  .hero2-watermark { display: none; }
  /* The switcher's own responsive treatment (the numbered pill rail) lives with
     the component in ub-elements.css, not here. */

  .proof-strip { margin-top: 0; padding: 0 0 var(--section-pad); }
  .proof-grid { grid-template-columns: repeat(2, 1fr); box-shadow: var(--shadow-md); }
  .proof-cell:nth-child(2) { border-right: none; }
  .proof-cell:nth-child(1), .proof-cell:nth-child(2) { border-bottom: 1px solid #E8ECEE; }

  .outcomes-head { grid-template-columns: 1fr; gap: 40px; }
  .outcomes-splits { grid-template-columns: 1fr; gap: 24px; }
  .employer-row { grid-template-columns: repeat(2, 1fr); }

  .pathway-grid { grid-template-columns: repeat(2, 1fr); }

  .sound { background-attachment: scroll; min-height: 0; }
  .sound-facts { grid-template-columns: repeat(3, 1fr); gap: 22px; }

  .timeline2 { grid-template-columns: repeat(2, 1fr); row-gap: 34px; }
  .centers-grid { grid-template-columns: repeat(2, 1fr); }
  .apply2-grid { grid-template-columns: 1fr; }
  .centennial2 .ghost-year { font-size: 38vw; }
}

@media (max-width: 768px) {
  :root { --section-pad: 66px; }

  /* The ribbon's mobile hide moved to style.css. It is header chrome from
     header.php on every page, but this sheet only loads on the homepage and
     program pages — so the ribbon vanished on a phone there and stayed put
     everywhere else. Same reason the site measure moved: chrome cannot be
     styled from a sheet that only some pages load. */

  .hero2-media { height: 240px; }
  .hero2-inner { padding-left: 18px; }
  .hero2-badge { margin-bottom: 18px; }
  .hero2-ctas .btn, .hero2-ctas .btn-ghost { width: 100%; text-align: center; }

  .proof-grid { grid-template-columns: 1fr; }
  .proof-cell { border-right: none; border-bottom: 1px solid #E8ECEE; }
  .proof-cell:last-child { border-bottom: none; }

  .employer-row { grid-template-columns: 1fr; }
  .employer-name { padding: 19px 16px; font-size: 1.08rem; }

  .pathway-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .pathway-tab { white-space: nowrap; margin-right: 22px; font-size: 0.98rem; }
  .pathway-grid { grid-template-columns: 1fr; }

  .sound-facts { grid-template-columns: 1fr; gap: 20px; }
  .timeline2 { grid-template-columns: 1fr; }
  .tl-node { padding-right: 0; }
  .centers-grid { grid-template-columns: 1fr; }
  .center-card { min-height: 320px; }

  /* .sticky-cta's mobile treatment moved to ub-elements.css with the component. */
}


/* ==========================================================================
   MULTI-AUDIENCE HOMEPAGE — the page-level remainder of the old home3.css
   University of Bridgeport

   home3.css is gone. It was a page-named stylesheet holding mostly BLOCK
   styles, which now ship with the plugin that renders them
   (ub-elements/assets/blocks/ub-sections.css). What is left is genuinely
   page-level — composition of this homepage, not the appearance of any one
   block — so it belongs here, in the homepage's own sheet.

   The athletics mega-menu panel and the footer audience row that also lived
   in home3.css had already moved to style.css, because footer.php and the nav
   render them on EVERY page while home3.css only loaded where section blocks
   were present. Do not re-add them here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   SHORT VIEWPORTS — the ladder, and why it is one line long now
   It used to read:

     1. NEVER let hero copy collide with the switcher.        (hard)
     2. Keep the hero headline and CTAs legible.              (trim type)
     3. Let the band's descriptor line fall below the fold.   (cheapest)

   That was an order of SACRIFICE, and it existed because the header, six hero
   text layers, the switcher and a 128px band all wanted the same ~520px. Every
   rung was a negotiation the layout could not win outright: --doors-overlap
   climbed to 118px and then dropped to 96px, the band's padding was trimmed
   twice, and the headline was re-clamped twice, all to buy back pixels for a
   collision the geometry could not otherwise avoid.

   The fold no longer over-commits, so there is nothing to arbitrate:

     • Rule 3 has no subject. The descriptor is gone from the band's content, so
       the cheapest thing to sacrifice does not exist. The three --doors-overlap
       values collapse to one, because the band is one height everywhere.
     • Rule 2 moved into the value itself. home.css's headline is now
       clamp(2.6rem, min(5.2vw, 7.4vh), 4.6rem) — it reads the height axis
       directly, so a media query re-clamping it by height can only be a second,
       coarser opinion about the same thing. Both overrides deleted.
     • Rule 1 is now structural rather than negotiated: .hero2 is a grid stack on
       min-height with slides in flow, so copy that needs more room makes the
       hero taller instead of escaping onto the controls.

   What is left is the one thing still genuinely different on a 720p screen: the
   buttons can lose a few pixels of padding without losing legibility. The
   descriptor sizes stay, inert on this page but correct the moment an editor
   types a `line` back into a door — see the note in home-scale.css.
   -------------------------------------------------------------------------- */
/* ≈13" laptops once browser chrome is subtracted, and 1280x720 screens.
   The .door-line trim that used to sit alongside this moved to the plugin
   sheet with the door band. */
@media (min-width: 1101px) and (max-height: 800px) {
  .hero2-ctas .btn-large,
  .hero2-ctas .btn-ghost { padding: 13px 26px; }
}

@media (max-width: 1180px) {
  .cta-section .cta-container { flex-direction: column; align-items: center; text-align: center; gap: 32px; }
}
