/* ==========================================================================
   audience-funnel.css — styles for three blocks in this plugin
   University of Bridgeport

     ub/audience-funnel   → .ad-funnel, .ad-lanes, .lane-panel
     ub/explainer-band    → .ad-cost
     ub/invitation-band   → .ad-visit

   SHIPPED BY THE PLUGIN, NOT THE THEME. A block that depends on the active
   theme for its appearance is only half a block: switch themes, or move the
   plugin to another site, and it renders as unstyled markup. The plugin owns
   the blocks, so it owns their CSS. See ub_block_assets() in ub-elements.php
   for the enqueue, which fires only when one of these blocks is on the post.

   It therefore assumes only what every UB page already loads: the brand
   tokens and shared primitives in the theme's style.css and ub-elements.css
   (--ub-purple, --ink, --white, .reveal, .btn, .container). Those are the
   design system, not one theme's styling, and the other content sheets in
   this codebase are written against the same base.

   PORTED FROM new-redesign/css/admissions.css, minus its .ad-hero section:
   the WordPress page builds its hero from ub/page-hero, which program.css
   already styles, so keeping the mockup's hero rules here would have meant
   two sets of hero styles competing on one page.

   THE STRUCTURAL IDEA
   Senior review named funnel segmentation by applicant type as "the single
   most important structural pattern" across the three comparable sites
   (UBalt, Wellesley, Santa Clara). All three segment; none of them segment
   without a page load.

   So the six lanes are not six cards linking to six pages. They are a
   selector bound to one detail panel: choose your lane and the requirements,
   deadlines, cost shape, and next action for YOUR situation resolve in
   place. A visitor who self-identifies gets an answer in one interaction
   instead of a navigation.

   That choice drives the CSS below. The lane rail and the panel are one
   component (.ad-funnel), the panel is a single grid whose contents swap,
   and only the active lane's copy is in the accessibility tree.
   ========================================================================== */

/* --------------------------------------------------------------------------
   UTILITY
   The theme's academics.css defines .ac-sr for its own page. This plugin
   cannot assume any theme sheet is present, so it declares its own.
   -------------------------------------------------------------------------- */
.ad-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* --------------------------------------------------------------------------
   THE FUNNEL — lane rail + detail panel as one component
   -------------------------------------------------------------------------- */
.ad-funnel {
  padding: 74px 0 90px;
  background: var(--white);
}
.ad-funnel-head {
  max-width: 44rem;
  margin-bottom: 34px;
}
.ad-funnel-head h2 {
  font-size: clamp(1.9rem, 3.3vw, 2.9rem);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.028em;
  color: var(--ink);
}
.ad-funnel-head p {
  font-size: 1.08rem;
  line-height: 1.66;
  color: var(--text-light);
  margin-top: 14px;
  max-width: 40rem;
}

/* The lane rail. Six buttons, horizontally scrollable on narrow screens
   rather than wrapping into a ragged block. */
.ad-lanes {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 0;
}
.ad-lane {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 18px 16px 20px;
  background: #F7F5FA;
  border: 1.5px solid #E5DFEC;
  border-bottom: none;
  border-radius: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-primary);
  transition: background 0.22s ease, border-color 0.22s ease, transform 0.22s ease;
}
.ad-lane:hover {
  background: #F1ECF7;
  transform: translateY(-2px);
}
.ad-lane i {
  font-size: 1.15rem;
  color: var(--ub-purple);
  transition: color 0.22s ease;
}
.ad-lane .ad-lane-name {
  font-size: 0.99rem;
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.ad-lane .ad-lane-sub {
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--text-light);
}

/* Active lane fuses into the panel below it: purple fill, and the bottom
   border removed so the tab and panel read as one surface. */
.ad-lane[aria-selected="true"] {
  background: var(--ub-purple);
  border-color: var(--ub-purple);
  transform: none;
}
.ad-lane[aria-selected="true"] i { color: #7FD9F5; }
.ad-lane[aria-selected="true"] .ad-lane-name { color: var(--white); }
.ad-lane[aria-selected="true"] .ad-lane-sub { color: rgba(255,255,255,0.76); }

.ad-lane:focus-visible {
  outline: 3px solid var(--ub-blue);
  outline-offset: 2px;
  z-index: 2;
}

/* --------------------------------------------------------------------------
   DETAIL PANEL
   Three columns: what you need (the list), the facts card (deadlines,
   format, cost shape), and the action stack. The facts card is the
   review's "Quick Facts" pattern applied to admissions rather than to a
   program — same promise: the practical numbers never need hunting for.
   -------------------------------------------------------------------------- */
.lane-panel {
  border: 1.5px solid var(--ub-purple);
  border-radius: 0;
  background: var(--white);
  box-shadow: 0 18px 44px rgba(42,18,64,0.09);
  overflow: hidden;
}

.lane-pane { display: none; }
.lane-pane.active { display: block; }

/* The one authored motion moment on this page: the panel content rises as
   it resolves, so switching lanes reads as an answer arriving rather than
   a screen repaint.

   The animation must only ever ADD motion to an already-visible pane. It used
   to run with `both`, which applies the `from` keyframe before the animation
   starts — so opacity:0 was the pane's resting state and the keyframes were
   the only thing that made it visible. Any browser that does not advance the
   animation left the pane permanently at opacity:0 / height:0: the lane turned
   purple, the panel stayed blank, and nothing in the DOM looked wrong. Reported
   on Kinsta with animationPlayState stuck at "running".

   So the visible state lives on .lane-pane.active itself and the keyframes start
   from the offset instead. A stalled, throttled or never-composited animation
   now degrades to "fully visible, no motion" rather than to "invisible".

   That still left a 0.42s window where the pane was legitimately faded out, and
   the report persisted on the reporter's machine after the fix shipped — six
   lanes verified visible in headless Chrome on the same build, so the stall is
   environment-specific and not something this stylesheet can detect. Motion is
   not worth a blank page on an unknown number of real browsers, so opacity and
   filter are out of the animation entirely: the pane is opaque at every point
   in time, and only the 10px rise is animated. `blur()` went with them — it
   forced the pane onto a composited layer, which is the most likely thing to
   have stalled. Worst case now is a pane that appears without sliding. */
@media (prefers-reduced-motion: no-preference) {
  .lane-pane.active { animation: lane-pane-in 0.42s cubic-bezier(0.16, 1, 0.3, 1); }
}
@keyframes lane-pane-in {
  from { transform: translateY(10px); }
}

.lane-pane-inner {
  display: grid;
  grid-template-columns: 1.35fr 0.95fr;
  gap: 0;
}

/* Left: the lane's actual content.
   A flex column so the closing note settles against the bottom edge rather
   than leaving dead space when the facts rail is the taller of the two
   columns — which it is on the shorter lanes. */
.lane-pane-main {
  padding: 40px 42px 44px;
  display: flex;
  flex-direction: column;
}
/* The note keeps its own 26px top margin (declared with .ad-note) and gains
   an auto-growing spacer before it, so it sits at the bottom of a short
   column without ever crowding the list above it in a full one. */
.lane-pane-spacer { flex: 1 1 auto; min-height: 0; }

.lane-pane-lead {
  font-size: 1.28rem;
  font-weight: 600;
  line-height: 1.42;
  letter-spacing: -0.018em;
  color: var(--ink);
  max-width: 30rem;
}
.lane-pane-body {
  font-size: 1rem;
  line-height: 1.68;
  color: var(--text-light);
  margin-top: 14px;
  max-width: 34rem;
}

.lane-pane-h {
  font-size: 0.79rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ub-blue-text);
  margin-top: 34px;
  margin-bottom: 16px;
}

/* Requirement list. Numbered because admissions genuinely is a sequence —
   the exception the craft floor allows for ordered steps. */
.ad-steps {
  list-style: none;
  counter-reset: adstep;
  display: grid;
  gap: 2px;
}
.ad-steps li {
  counter-increment: adstep;
  position: relative;
  padding: 12px 0 12px 44px;
  font-size: 0.98rem;
  line-height: 1.56;
  color: var(--text-main);
  border-top: 1px solid #EDE8F2;
}
.ad-steps li:first-child { border-top: none; }
.ad-steps li::before {
  content: counter(adstep);
  position: absolute;
  left: 0;
  top: 12px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #F1ECF7;
  color: var(--ub-purple);
  font-size: 0.82rem;
  font-weight: 700;
}
.ad-steps b { color: var(--ink); font-weight: 650; }
.ad-steps a { color: var(--ub-blue-text); font-weight: 500; }

/* A single emphasized note per lane — the thing that lane's applicants
   most often get wrong or do not know to ask. */
.ad-note {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  margin-top: 26px;
  padding: 16px 18px;
  background: #F7F5FA;
  border-radius: 0;
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--text-main);
}
.ad-note i {
  color: var(--ub-purple);
  font-size: 1rem;
  margin-top: 2px;
  flex-shrink: 0;
}
.ad-note b { color: var(--ink); }
.ad-note a { color: var(--ub-blue-text); font-weight: 500; }

/* Right: facts + actions on a tinted rail */
.lane-pane-side {
  padding: 40px 38px 44px;
  background: linear-gradient(170deg, #FBFAFD 0%, #F4F0F9 100%);
  border-left: 1px solid #EDE8F2;
}

.ad-facts { display: grid; gap: 0; }
.ad-fact {
  padding: 15px 0;
  border-top: 1px solid #E5DFEC;
}
.ad-fact:first-child { border-top: none; padding-top: 0; }
.ad-fact-l {
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.085em;
  text-transform: uppercase;
  color: var(--text-light);
}
.ad-fact-v {
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.016em;
  color: var(--ink);
  margin-top: 5px;
}
.ad-fact-v small {
  display: block;
  font-size: 0.83rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--text-light);
  margin-top: 4px;
  letter-spacing: 0;
}

.ad-acts {
  display: grid;
  gap: 10px;
  margin-top: 28px;
}
.ad-acts .btn { width: 100%; text-align: center; justify-content: center; }

.ad-contact {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid #E5DFEC;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-light);
}
.ad-contact strong {
  display: block;
  color: var(--ink);
  font-weight: 650;
  margin-bottom: 5px;
}
.ad-contact a { color: var(--ub-blue-text); text-decoration: none; font-weight: 500; }
.ad-contact a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   COST — structure, not figures
   The review is right that cost belongs early. But quoting tuition in a
   mockup bakes in a number nobody owns, and a stale figure is worse than
   an honest structure. So this band explains HOW UB charges and what
   reduces it, and links out for the current rates.
   -------------------------------------------------------------------------- */
.ad-cost {
  padding: 84px 0 92px;
  background: var(--ub-purple-deep);
  color: var(--white);
  position: relative;
  overflow: hidden;
}
.ad-cost::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 38%;
  background: linear-gradient(200deg, rgba(89,45,130,0.6) 0%, rgba(89,45,130,0) 70%);
  clip-path: polygon(28% 0, 100% 0, 100% 100%, 0 100%);
  pointer-events: none;
}
.ad-cost .container { position: relative; z-index: 2; }
.ad-cost-head { max-width: 42rem; }
.ad-cost-head h2 {
  font-size: clamp(1.9rem, 3.3vw, 2.9rem);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.028em;
  color: var(--white);
}
.ad-cost-head p {
  font-size: 1.08rem;
  line-height: 1.68;
  color: rgba(255,255,255,0.82);
  margin-top: 16px;
}

.ad-cost-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 34px;
  margin-top: 48px;
}
/* A column, so the closing link can be pushed to the bottom (see the
   margin-top:auto below). Grid already stretches the items to equal height;
   without this the three links sit wherever their own paragraph happens to
   end, which reads as three misaligned rows rather than one set of choices. */
.ad-cost-item {
  padding-top: 22px;
  border-top: 2px solid rgba(127,217,245,0.45);
  display: flex;
  flex-direction: column;
}
.ad-cost-item h3 {
  font-size: 1.14rem;
  font-weight: 700;
  letter-spacing: -0.016em;
  color: var(--white);
}
.ad-cost-item p {
  font-size: 0.97rem;
  line-height: 1.66;
  color: rgba(255,255,255,0.78);
  margin-top: 10px;
}
/* In the mockup this was always a <span>. The block makes it an <a> whenever
   the author supplies a URL, so it needs the states a link owes a visitor —
   and the underline that stops "See tuition and fees →" reading as decoration
   when it is in fact the way out of this section. */
.ad-cost-item .ad-cost-fig {
  display: block;
  font-size: 0.83rem;
  font-weight: 600;
  color: #7FD9F5;
  /* auto, not a fixed gap: pushes the link to the bottom of the column so all
     three align, while the 12px keeps it off the paragraph in the tallest
     column and on one-column mobile, where there is no spare height to take. */
  margin-top: auto;
  padding-top: 12px;
  letter-spacing: 0.01em;
  text-decoration: none;
}

a.ad-cost-fig {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(127, 217, 245, 0.4);
  transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

a.ad-cost-fig:hover,
a.ad-cost-fig:focus-visible {
  color: var(--white);
  text-decoration-color: var(--white);
}

a.ad-cost-fig:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
  border-radius: 2px;
}

.ad-cost-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 46px;
}

/* --------------------------------------------------------------------------
   VISIT / NEXT STEP
   -------------------------------------------------------------------------- */
.ad-visit { padding: 84px 0 92px; background: #F7F5FA; }
.ad-visit-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
}
.ad-visit h2 {
  font-size: clamp(1.9rem, 3.1vw, 2.7rem);
  font-weight: 800;
  line-height: 1.07;
  letter-spacing: -0.028em;
  color: var(--ink);
}
.ad-visit p {
  font-size: 1.06rem;
  line-height: 1.68;
  color: var(--text-light);
  margin-top: 16px;
  max-width: 32rem;
}
.ad-visit-acts { display: flex; flex-wrap: wrap; gap: 13px; margin-top: 28px; }

.ad-visit-media {
  position: relative;
  border-radius: 0;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  box-shadow: 0 22px 50px rgba(42,18,64,0.16);
}
.ad-visit-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --------------------------------------------------------------------------
   RESPONSIVE
   The lane rail is the load-bearing responsive problem: six tabs cannot
   sit in a row on a phone. Below 1080px it becomes a horizontal scroller
   that keeps the tab metaphor; below 720px the tabs become full-width
   stacked rows and the panel loses its side rail.
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  /* WRAP, DON'T SCROLL.
     This was a horizontal snap-scroller with hidden scrollbars. Six lanes at
     168px each need ~1000px, so on a phone two were visible and the other four
     — International, Nursing Pathways, English Language, and whichever else
     fell off — were reachable only by a horizontal swipe with nothing on
     screen to suggest it. A visitor who never guessed would conclude UB has no
     route for them. That is the whole page failing for the applicants the
     lanes exist to serve.

     Wrapping shows all six at once. It costs the tab-fuses-into-panel join,
     which only reads in a single row, so below this breakpoint the lanes
     become a self-contained grid of cards sitting above the panel — see the
     restored bottom border and radius. */
  .ad-lanes {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
  }
  .ad-lane {
    border-bottom: 1.5px solid #E5DFEC;
    border-radius: 0;
  }
  /* No longer fusing into the panel, so the active lane needs its own
     complete outline rather than an open bottom edge. */
  .ad-lane[aria-selected="true"] {
    border-bottom-color: var(--ub-purple);
  }
  .lane-panel {
    margin-top: 8px;
    border-radius: 0;
  }
  .lane-pane-inner { grid-template-columns: 1fr; }
  .lane-pane-side {
    border-left: none;
    border-top: 1px solid #EDE8F2;
  }
  .ad-cost-grid { grid-template-columns: 1fr; gap: 26px; }
  .ad-visit-inner { grid-template-columns: 1fr; gap: 34px; }
  .ad-visit-media { order: -1; aspect-ratio: 16 / 9; }
}

@media (max-width: 720px) {
  .ad-funnel { padding: 52px 0 66px; }
  .lane-pane-main { padding: 30px 24px 34px; }
  .lane-pane-side { padding: 30px 24px 36px; }
  .ad-steps li { padding-left: 38px; }
  .ad-cost { padding: 60px 0 68px; }
  .ad-visit { padding: 60px 0 68px; }
  /* Two columns, three rows. Three would put "English Language" and
     "Applying from high school" into two-character-wide columns. */
  .ad-lanes { grid-template-columns: repeat(2, 1fr); }
  .ad-lane { padding: 14px 13px 15px; gap: 6px; }
  .ad-lane i { font-size: 1.05rem; }
}

/* Narrowest phones: the subtitle is the first thing to go visually. The lane
   NAME is what a visitor matches themselves against; "Applying from high
   school" is helpful, not load-bearing, and keeping it visible here forces
   three-line tabs.

   Hidden with the clip pattern rather than display:none, because the subtitle
   is real text inside the <button> and so forms part of its accessible name.
   display:none would drop it from that name, leaving a screen-reader user on a
   small phone with less information than one on a laptop — the opposite of
   what a responsive rule should do. */
@media (max-width: 400px) {
  .ad-lanes { gap: 6px; }
  .ad-lane { padding: 13px 11px 14px; }
  .ad-lane .ad-lane-name { font-size: 0.92rem; }
  .ad-lane .ad-lane-sub {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}
