/* ==========================================================================
   Site-wide layout fixes
   Added 2026-07-28. Loaded last in header.php so it overrides style.css on
   equal specificity.

   Deliberately a separate file rather than edits inside style.css. That file is
   ~2,900 lines with several rules for the same selector at different points and
   a number of commented-out blocks containing unbalanced braces. Overriding
   from the outside keeps each fix readable, keeps the diff reviewable, and
   makes the whole thing revertible by removing one <link>.

   Sections 1-6 apply to all 61 pages. The homepage hero is exempt where noted,
   because home-hero.css targets it at higher specificity.

   Sections 7 and 8 are the exceptions: each is scoped to a class carried by
   one or two specific pages. See the notes above them.
   ========================================================================== */

/* ==========================================================================
   1. THE HUGE EMPTY BAND UNDER EVERY PAGE BANNER
   ==========================================================================
   style.css:1082 sets, at top level and therefore at every screen size:

     .principalMsgBlock { height: 80vh; background-color: #b80d2e; overflow: hidden; }

   The banner inside it is .bannerSubPages at height:520px. So the section was
   locked to 80% of the viewport height regardless of its contents, and
   everything below 520px was empty section painted in its own crimson. On a
   1050px-tall window that is roughly 320px of dead colour under the banner on
   all 61 pages.

   height:auto makes the section hug the banner. The small symmetric padding
   keeps the crimson as a deliberate frame rather than a slab.
   -------------------------------------------------------------------------- */
.principalMsgBlock {
  height: auto;
  padding-top: 14px;
  padding-bottom: 14px;

  /* REQUIRED, not cosmetic.
     The banner caption .bannerbottomText is position:absolute with
     top:50%; left:50%; transform:translate(-50%,-50%) (style.css:27). In
     style.css:1082 the matching `position: relative` on .principalMsgBlock sits
     inside a commented-out block, so the section is not a positioned ancestor
     and the caption resolves against the initial containing block instead. Its
     top:50% therefore meant "50% of the viewport height down the document",
     which only ever looked centred because the section happened to be 80vh
     tall and started near the top of the page.

     With height:auto the section is about 548px, so on any viewport taller than
     roughly 1100px that caption would drift below the banner and land on the
     next section. Making the section a positioned ancestor centres the caption
     inside the banner itself, at any viewport height. */
  position: relative;
}

/* --------------------------------------------------------------------------
   Banner heights that suit the screen
   --------------------------------------------------------------------------
   .bannerSubPages is a flat 520px at every width (style.css:21), which is most
   of a phone screen before any content appears. Stepping it down keeps the
   crop sensible. object-fit:cover is already set, so these crop rather than
   squash.

   Below 435px style.css has .bannerSubPages{height:250px !important}, which
   still wins there. That is fine and intended.

   The homepage hero is unaffected: home-hero.css sets its images with
   `height: ... !important` at higher specificity.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  .bannerSubPages {
    height: 440px;
  }
}

@media (max-width: 991px) {
  .bannerSubPages {
    height: 360px;
  }
}

@media (max-width: 690px) {
  .bannerSubPages {
    height: 290px;
  }
}

/* ==========================================================================
   1b. HORIZONTAL OVERFLOW: THE WHITE STRIP DOWN THE RIGHT ON PHONES
   ==========================================================================
   A Bootstrap .row carries margin-left/right: -15px, which is designed to be
   cancelled by the 15px padding of the .container or .col-* it sits inside.

   A .row placed directly inside another .row therefore gets a second set of
   negative margins with nothing to cancel them, so it sticks 15px past its
   parent on each side. Since the parent row already reaches the container's
   padding edge, that is 30px of horizontal document overflow, and the page
   becomes horizontally scrollable. On a phone that shows up as a strip of empty
   background down the right-hand side.

   Three views do this: home.php (the Vision/Mission block), PDSHome.php and
   admissions.php.

   The child combinator matters here. `.row .row` would also match the perfectly
   valid .row > .col > .row nesting, where the inner row's negative margins are
   correct because they cancel the column's padding. Only a row that is an
   immediate child of another row is wrong.
   -------------------------------------------------------------------------- */
.row > .row {
  margin-left: 0;
  margin-right: 0;
}

/* --------------------------------------------------------------------------
   Backstop against any remaining horizontal overflow
   --------------------------------------------------------------------------
   The causes found so far are fixed at source: the nested rows above, and three
   stray closing tags in home.php that were closing .container and .row early
   and letting later rows escape their container.

   This is a guard, not the fix. Several other views still have unbalanced div
   markup (Placements, CivilEngineering and ContactUs among them, listed in the
   commit message), and there is no way to browser-test all 61 pages here. A
   vertical scrollbar is unaffected; only sideways scrolling is clamped.

   ON `html` ONLY, NOT `body`. This was originally on both, and section 9 later
   made the navbar position:sticky, which stopped working: an ancestor with any
   overflow other than visible becomes the sticky element's scroll container,
   and the navbar simply scrolled away with the page.

   `html` is the exception. When overflow is set on the root element the value
   is propagated to the viewport, and the root itself is then treated as
   overflow:visible — so the clamp still applies but no scroll container is
   introduced between the navbar and the viewport, and sticky keeps working.
   Setting it on `body` as well reintroduces exactly the container that breaks
   it, which is why body now only carries max-width.

   Verified after the change: sticky holds at 1440/768/390 on home, Admissions
   and Contact Us, and at 390px window.scrollTo(300,0) still leaves scrollX at
   0 on home, Admissions, Contact Us, Placements and Privacy Policy — the page
   cannot be dragged sideways, which is the symptom that matters.

   Note that documentElement.scrollWidth does read 405 against a 390 viewport.
   That is not page content: it is the Admission Enquiry drawer, parked
   off-screen until it is opened. It is clipped and unreachable, so it costs
   nothing.

   The fixed-position elements are unaffected either way — the two side rails,
   the enquiry panel, the popup and the bottom marquee are all positioned
   against the viewport.
   -------------------------------------------------------------------------- */
html {
  overflow-x: hidden;
  max-width: 100%;
}

body {
  /* `clip`, not `hidden` and not `visible`.

     style.css:9 sets body{overflow-x:hidden}. That is what was breaking the
     sticky navbar in section 9 — `hidden` makes body a scroll container, and a
     sticky element sticks to its nearest scrolling ancestor, so the navbar just
     scrolled away with the page.

     Setting it to `visible` fixed sticky but removed the clamp, and relying on
     the root alone turned out not to hold on real iOS Safari, which is where
     the sideways drag was reported.

     `clip` is the one value that does both: it clips overflow exactly like
     hidden, but it does NOT create a scroll container, so sticky is unaffected.
     Safari 16+, Chrome 90+. Older browsers ignore it and fall back to the
     root-level clamp above, which is the behaviour we had before. */
  overflow-x: clip;
  max-width: 100%;
}

/* --------------------------------------------------------------------------
   The actual source of the 15px: the Admission Enquiry drawer
   --------------------------------------------------------------------------
   Measured on the live site at a 393px viewport with every clamp lifted, this
   panel is 408px wide — 15px wider than the screen — and every one of its
   children inherits that. It was the only real offender on the page; the
   scrolling logo tracks are clipped by their own containers, and everything
   else measured clean.

   style.css:1790 gives it `width:100%; padding:15px; max-width:500px;
   margin-right:-105%` and parks it off-screen until opened.

   max-width is the fix that matters: capped at the smaller of 500px and the
   viewport, the panel can never be wider than the screen it is sitting on, so
   there is nothing to scroll to at any width. box-sizing is belt and braces —
   Bootstrap 3 sets border-box globally, but this file loads after it and the
   guarantee is worth making explicit on the one element that was overflowing.

   Fixing it here rather than deleting the negative margin, because that margin
   is what the open/close animation slides against (.enableEnquire sets
   margin-right:0), and re-engineering that transition on a live site is a
   bigger change than this problem warrants.
   -------------------------------------------------------------------------- */
.enquireNowFormCont {
  box-sizing: border-box;
  max-width: min(500px, 100%);
}

/* ==========================================================================
   1c. THE NAVBAR GOING "TRANSPARENT" AT MID-RANGE WIDTHS
   ==========================================================================
   header-style.css:376 sets, at top level:

     .navBarStyle { height: 92px; }

   and only resets it to auto below 690px (lines 402 and 556).

   That is a fixed height, not a minimum. Between roughly 700px and the width at
   which all eleven top-level menu items still fit on one line, .navbar-nav wraps
   onto a second row. The nav's content then stands about 190px tall while its
   box stays 92px, so the background only paints the first 92px and the wrapped
   menu row hangs outside it. Because that overflow lands exactly where the page
   banner begins, the menu appears to sit directly on the banner photo with no
   background behind it, which is what reads as the navbar going transparent.

   The white seen in that state is .shadow-navbar (header-style.css:306), which
   script.js adds to .navbar on scroll. It is on the same element, so it is
   clipped to the same 92px.

   min-height keeps the 92px floor the design assumes while letting the bar grow
   to cover its own content whenever the menu wraps. Confined to 691px and up so
   the mobile rules, which already use height:auto, are untouched.
   -------------------------------------------------------------------------- */
@media (min-width: 691px) {
  .navBarStyle {
    height: auto;
    min-height: 92px;
  }
}

/* --------------------------------------------------------------------------
   Keep the menu on one line for longer
   --------------------------------------------------------------------------
   The rule above makes the wrapped state render correctly, but the bar still
   grows and pushes the banner down when it happens. Tightening the link boxes
   through the band where wrapping occurs keeps all eleven items on one row at
   far more widths, so the taller state is reached much less often.

   header-style.css:287 sets padding-top/bottom and font-size on these links but
   leaves the horizontal padding at Bootstrap's 15px. Trimming that to 9px across
   eleven links recovers roughly 130px, and the single point of font size a
   little more. The !important is needed only because the original font-size
   declaration carries one.
   -------------------------------------------------------------------------- */
@media (min-width: 691px) and (max-width: 1199px) {
  .navbar-nav > li > a {
    padding-left: 9px;
    padding-right: 9px;
    font-size: 13px !important;
  }
}

/* ==========================================================================
   2. TEXT RUNNING UNDER THE FIXED SIDE RAILS ON MOBILE
   ==========================================================================
   Three elements are position:fixed against the edges of the viewport and are
   never hidden or moved on small screens:

     .social_icon  left edge,  50px wide  (.social-btn is 50x50, newstyle.css:1)
     .enquireBtn   right edge, 180x31 rotated -90deg, so ~31px wide
     .brochureBtn  right edge, same

   On a phone that removes about 81px from an already narrow viewport, and
   because .container only carries Bootstrap's 15px padding, body copy ran
   underneath both rails and the first and last words became unreadable.

   Docking the rails to the bottom on mobile is not available: .marqmain is
   already fixed to bottom:0 at 50px tall with z-index 999.

   So the rails are made a little smaller on phones, and .container is given
   enough horizontal padding to clear them. The padding is symmetric even
   though the left rail is wider, because most of this content is centred and
   asymmetric padding would visibly push it off-centre.

   .container-fluid is deliberately NOT padded: it is what the full-bleed
   banners and the Infrastructure strip use, and insetting those would leave
   white gutters down the sides of images that are meant to reach the edge.
   -------------------------------------------------------------------------- */
@media (max-width: 690px) {
  .social-btn {
    width: 38px;
    height: 38px;
  }

  .social-btn i {
    font-size: 16px;
  }

  .container {
    padding-left: 44px;
    padding-right: 44px;
  }
}

/* Very narrow phones: claw a little width back for line length. 38px still
   clears the 38px rail, and the right rail is only ~31px. */
@media (max-width: 400px) {
  .container {
    padding-left: 38px;
    padding-right: 38px;
  }
}

/* --------------------------------------------------------------------------
   Justified text on narrow columns
   --------------------------------------------------------------------------
   style.css:2910 has a bare `p { text-align: justify }` applying site-wide. On
   a phone-width column that stretches word spacing into wide rivers, which is
   what made the Vision and Mission copy look broken.

   This override is also a bare `p` selector, so it is equally weak: any rule
   that sets text-align via a class still wins, and nothing that is
   deliberately centred is affected.
   -------------------------------------------------------------------------- */
@media (max-width: 690px) {
  p {
    text-align: left;
  }
}

/* ==========================================================================
   3. "WHY CHOOSE TAE?" / "CAREER OUTCOMES" TEXT CROSSING THE COLOUR SPLIT
   ==========================================================================
   .grayBoxBlock1 paints both columns with one hard-stop gradient on the
   section:

     desktop            background: linear-gradient(to left, #000 50%, #AF9890 50%)
     <=690px (st:2717)  background: linear-gradient(to top,  #000 50%, #AF9890 50%)

   Side by side that works, because each column really is half the width. Once
   the columns stack on mobile it only works if each column happens to be
   exactly half the section's height, and they are not: "Why Choose TAE?" has
   four lines of list copy and "Career Outcomes." has two longer paragraphs.
   The result was the last line of the first column spilling across onto the
   second column's colour, which reads as text overflowing out of its box.

   Giving each column its own background removes the guesswork. The colour now
   follows the content instead of a fixed percentage.
   -------------------------------------------------------------------------- */
@media (max-width: 690px) {
  .grayBoxBlock1 {
    background: #000;
    padding: 0;
  }

  .grayBoxBlock1 .row > div {
    padding: 22px 18px;
  }

  .grayBoxBlock1 .row > div:first-of-type {
    background: #AF9890;
  }

  .grayBoxBlock1 .row > div:last-of-type {
    background: #000;
  }
}

/* ==========================================================================
   7. CONTACT US — the address / phone / email block
   ==========================================================================
   The only page-scoped section in this file. Everything above applies to all
   61 pages; these rules are confined to .contactBlock, which exists on
   contactUs.php alone. Kept here rather than in a new stylesheet so header.php
   does not gain a <link> that 60 pages would download and not use.

   The markup fault is described in contactUs.php. The visual fault was that
   the three labels used .headingClass, which is text-align:center
   (style.css:435), while their values were left-aligned — so the block had two
   competing axes and nothing lined up with anything. It also gave no
   indication of which value belonged to which label beyond proximity.

   Rebuilt as a list: fixed-width icon column, label, value. One left edge for
   the text, one for the icons.
   -------------------------------------------------------------------------- */
.contactBlock {
  padding: 46px 0 52px;
}

@media (max-width: 690px) {
  .contactBlock {
    padding: 28px 0 32px;
  }
}

/* style.css:2910 sets a bare p{text-align:justify} site-wide. On this narrow
   half-column it stretched the intro into visible rivers of white space. */
.contactBlock .contactIntro {
  text-align: left;
  margin: 0 0 26px;
  line-height: 1.6;
}

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

.contactBlock .contactList > li {
  display: flex;
  align-items: flex-start;
  gap: 16px;

  /* A hairline between entries, not a box around each — three bordered cards
     would outweigh the amount of content actually in them. */
  padding: 18px 0;
  border-bottom: 1px solid #e4e4e4;
}

.contactBlock .contactList > li:first-child {
  padding-top: 0;
}

.contactBlock .contactList > li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

/* Fixed 44px badge so all three icons occupy the same width regardless of the
   glyph inside them, which is what puts the labels on a single left edge.
   flex-shrink:0 stops the circle deforming into an ellipse when the address
   wraps. */
.contactBlock .contactIcon {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;

  /* #b80d2e is the crimson already used by .principalMsgBlock and the header. */
  background: #b80d2e;
  color: #fff;
  font-size: 17px;
}

.contactBlock .contactDetail {
  /* Without min-width:0 a flex item refuses to shrink below its longest
     unbreakable word, and the email address would push the row wider than the
     column on small screens. */
  min-width: 0;
}

/* Deliberately not .headingClass — that is the centred 51px display style used
   for section titles, and these are field labels. */
.contactBlock .contactLabel {
  font-family: "Poppins", sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #777;
  margin: 0 0 6px;
  text-align: left;
}

.contactBlock .contactValue {
  font-family: "Poppins", sans-serif;
  font-size: 16px;
  font-weight: 600;
  color: #1a1a1a;
  line-height: 1.55;
  margin: 0;
  text-align: left;

  /* The email has no spaces to break at. */
  overflow-wrap: break-word;
}

.contactBlock .contactValue a {
  color: #1a1a1a;
  text-decoration: none;
}

.contactBlock .contactValue a:hover,
.contactBlock .contactValue a:focus {
  color: #b80d2e;
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   The map
   --------------------------------------------------------------------------
   .google-maps (style.css:2334) is a padding-bottom:75% aspect-ratio box with
   margin-top:2em, so the map started 32px below the top of the text column and
   the two halves never began on the same line. The ratio also left it much
   taller than the text beside it.
   -------------------------------------------------------------------------- */
.contactBlock .contactMap {
  margin-top: 0;
  margin-bottom: 0;

  /* 4:3 -> 3:2. Closer to the height of the contact list next to it. */
  padding-bottom: 66%;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

/* Stacked below 768px, where col-sm-6 stops applying and the map would
   otherwise sit flush against the last contact row. */
@media (max-width: 767px) {
  .contactBlock .contactMap {
    margin-top: 28px;
    padding-bottom: 75%;
  }
}

/* ==========================================================================
   8. VISION / MISSION PANELS
   ==========================================================================
   On home.php and admissions.php, and nowhere else.

   The two coloured panels had NO PADDING OF THEIR OWN. Every gap around the
   text came from three things that were never meant to space a filled panel:

     - Bootstrap's 15px column padding, which is a gutter between columns, not
       an inset from a background edge;
     - the h2's default margin;
     - .headingClass{margin-bottom:3%} and .ParagraphClass{margin-bottom:2%},
       both percentages, and percentage margins resolve against the container's
       WIDTH. So the gap under a heading grew on a wide screen and collapsed on
       a narrow one — the same root cause documented at the top of
       home-sections.css.

   The visible result: on a phone the Vision text ran straight into the top
   edge of the Mission panel with nothing between them, and the last line of
   Mission sat on the bottom edge of its own panel. Fixed values throughout.

   The colours stay inline in the views. Note that the left "Vision panel" is
   not a panel at all — that column has no background of its own and what shows
   is the row's own colour behind it. Only the Mission column is painted. That
   is why the two have always appeared exactly equal in height.
   -------------------------------------------------------------------------- */
.visionMission {
  border-radius: 20px;

  /* Does the corner rounding, and contains the two floated columns so the row
     ends flush with the taller of them. Without it the row ran a few pixels
     past the bottom of the Mission panel and leaked a thin strip of the
     lighter row colour under it on narrow screens. */
  overflow: hidden;
}

.visionMission > [class*="col-"] {
  /* Replaces the 15px gutter. Vertical padding did not exist at all before. */
  padding: 30px 32px;
}

@media (max-width: 767px) {
  /* Stacked. The two panels meet edge to edge, so this padding is also the
     entire separation between the Vision text and the Mission heading. */
  .visionMission > [class*="col-"] {
    padding: 24px 22px;
  }
}

/* .headingClass carries margin-bottom:3% and the h2 its own default top
   margin, which set the panel's top inset rather than the padding above. */
.visionMission .headingClass {
  margin-top: 0;
  margin-bottom: 14px;
}

.visionMission .ParagraphClass {
  /* The only paragraph in each panel, so its bottom margin was pure dead space
     inside the padding. */
  margin-bottom: 0;

  /* style.css:2910 has a bare p{text-align:justify} site-wide. Across a half
     column it stretched "To be a premier knowledge centre of the nation for
     socio-economic" into visibly uneven word spacing. */
  text-align: left;

  /* Unitless, so it tracks the font size instead of being pinned at 28px. */
  line-height: 1.6;
}

/* ==========================================================================
   9. THE WHITE BAND BETWEEN THE NAVBAR AND THE BANNER
   ==========================================================================
   Reported on the live site 2026-07-28. Roughly 90px of empty white across the
   full width, between the header and the banner, on all 61 pages.

   Pre-existing, not introduced by this engagement — verified on the live site
   by disabling home-hero.css, home-sections.css, site-fixes.css and
   counter.css and re-measuring: the gap stayed at exactly 90px.

   THE CAUSE
   ---------
   style.css:1099 sets `.principalMsgBlock { margin-top: 90px }`. That margin
   exists to clear the navbar, and it would be correct if the navbar were
   position:fixed — a fixed element is out of the flow, so the content below it
   needs to reserve its height.

   But the navbar is NOT fixed at the top of the page. header.php marks it
   `data-spy="affix"`, and Bootstrap 3's affix plugin only swaps in
   position:fixed once the page is scrolled past the offset. At rest the navbar
   is position:relative, in the flow, occupying its own 97px. So the browser
   rendered 97px of navbar, then 90px of margin against the white page
   background, and only then the banner.

   It also meant the whole page jumped upward by ~97px the moment you started
   scrolling, as the navbar left the flow.

   THE FIX
   -------
   position:sticky does what the affix plugin was reaching for, without ever
   leaving the flow: the navbar occupies its space normally and pins to the top
   once it would scroll out of view. Nothing below it needs a margin, and there
   is no jump, because nothing is ever removed from the layout.

   The plugin still runs and still adds .affix on scroll — that is left alone,
   because .affix also carries the drop shadow in header-style.css:178 that
   marks the header as detached. Only its `position` is overridden.

   `.affix~.container-fluid { top: 50px }` (header-style.css:202) was written
   to compensate for the same jump. It matches nothing: every .container-fluid
   on the site is a descendant of the navbar or of a later section, never a
   sibling of the navbar, so the general sibling combinator never selects one.
   Left in place as inert.
   -------------------------------------------------------------------------- */
.navbar.navBarStyle {
  position: sticky;
  top: 0;

  /* Matches the z-index .affix uses, so the header sits above page content
     from the outset rather than only after the plugin fires. */
  z-index: 999999;
}

/* Beats `.affix { position: fixed }` (0,1,0) at (0,3,0), so the navbar stays
   sticky rather than being pulled out of the flow when the plugin fires. */
.navbar.navBarStyle.affix,
.navbar.navBarStyle.affix-top,
.navbar.navBarStyle.affix-bottom {
  position: sticky;
  top: 0;
}

/* The margin the navbar no longer needs.

   Two selectors because home.php's banner is `.principalMsgBlock.homeHero`,
   and home-hero.css targets that at (0,2,0). A bare `.principalMsgBlock` here
   is (0,1,0) and would lose to it. The second selector matches that
   specificity and wins on source order, this file being loaded last. */
.principalMsgBlock,
.principalMsgBlock.homeHero {
  margin-top: 0;
}
