1 2 3 4<!DOCTYPE html> 5<html lang="en"> 6<head> 7 <meta charset="utf-8" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 9 <title>High School - Southern Regional School District</title> 10 11 12 13 <link rel="stylesheet" href="/assets/libs/bootstrap/dist/css/bootstrap.min.css" /> 14 <link href="/assets/libs/fontawesome/css/fontawesome.min.css" rel="stylesheet" /> 15 <link href="/assets/libs/fontawesome/css/all.min.css" rel="stylesheet" /> 16 <link href="/assets/libs/datatables/datatables.min.css" rel="stylesheet" /> 17 18 <link rel="stylesheet" href="/css/site_widescreen.css?v=aBwU0vS3Oec6Wnih7PayNAsNh00-bEF2cC6WkGoFBY8" /> 19 20 <link href="/assets/libs/sweetalert2/dist/sweetalert2.min.css?v=YKKnn5oXErZthQwr01oz4mEVF11gcVMJYcmUuhoyUgM" rel="stylesheet" /> 21 <link href="/assets/libs/sweetalert2/theme-dark/dark.min.css?v=PpzFdOmOk7hAm20FVuUQYuZjzEfhA-PYni6S9t84TWg" rel="stylesheet" /> 22 <link href="/assets/libs/tempus-dominus/dist/css/tempus-dominus.min.css" rel="stylesheet" /> 23 <link href="/assets/libs/video.js/video-js.min.css?v=aORQtrgEimlqIhbLColAj9pemXUbsyiUhfc__eCEwXw" rel="stylesheet" /> 24 <link rel="stylesheet" href="/css/navigation.css?v=R0kvcNJQdUfJ4Ln1W-0umu6dhq36Q7D0D69K1rWX5Hw" /> 25 <link href="/css/cookieprefs.css?v=NhZiTy6Whal9xq6ubiPiRmUo_Ww4HD9bOjuEfXJh3E8" rel="stylesheet" /> 26 <link rel="stylesheet" href="/css/accessibility.css?v=tUBMBVVX9wIIsVqI9f5Ux4NqxKT_z6c7MDwXzohHwzE" /> 27 28 29 30 31 32 33 34 35 36 37 38 39 <style> 40 41/* Hero Video Wrapper */ 42.hero-video-wrapper { 43 position: relative; 44 width: 100%; 45 margin-bottom: 2rem; 46 overflow: hidden; 47 /*min-height: 400px;*/ 48} 49 50/* Video container - shown by default */ 51.hero-video { 52 position: relative; 53 width: 100%; 54 aspect-ratio: 16 / 7; 55 max-height: 70vh; 56 overflow: hidden; 57 background-color: #000; 58 border-radius: 15px; 59 transition: opacity 0.4s ease-in-out; 60 z-index: 2; 61} 62 63 .hero-video video { 64 position: absolute; 65 inset: 0; /* top:0; right:0; bottom:0; left:0 */ 66 width: 100%; 67 height: 100%; 68 display: block; /* prevents inline-layout quirks on iOS */ 69 object-fit: cover; /* crop and fill like background-size:cover */ 70 -webkit-object-fit: cover; 71 transform: none; /* remove translate(-50%,-50%) which can mis-size on iOS */ 72 z-index: 0; 73 /* GPU hack to avoid rendering glitches on some iOS builds */ 74 -webkit-transform: translateZ(0); 75 transform: translateZ(0); 76 } 77 78 /* Fallback: ensure video still covers container */ 79 .hero-video video:not([style*="object-fit"]) { 80 min-width: 100%; 81 min-height: 100%; 82 left: 50%; 83 top: 50%; 84 transform: translate(-50%, -50%); 85 } 86 87 .hero-video .hero-overlay { 88 position: absolute; 89 inset: 0; 90 z-index: 1; 91 display: flex; 92 align-items: center; 93 padding: 2rem; 94 /* background: linear-gradient(180deg, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.55) 100%); */ 95 } 96 97 .hero-video .hero-caption { 98 max-width: 55%; 99 background: linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.45) 100%); 100 border-radius: 8px; 101 padding: 1rem 1.25rem; 102 color: #fff; 103 } 104 105 .hero-video .hero-caption.text-start { 106 margin-left: 2rem; 107 } 108 109 .hero-video .carousel-title { 110 font-size: clamp(1.25rem, 3.6vw, 1.75rem); 111 font-weight: 700; 112 margin-bottom: .25rem; 113 color: #fff; 114 } 115 116 .hero-video .carousel-subtitle { 117 font-size: clamp(.9rem, 2.2vw, 1rem); 118 margin-bottom: .75rem; 119 color: rgba(255,255,255,0.92); 120 } 121 122 /* Hide native video controls */ 123 .hero-video video::-webkit-media-controls { 124 display: none !important; 125 } 126 127/* Responsive adjustments */ 128@media (max-width: 991.98px) { 129 .hero-video .hero-caption { 130 max-width: 85%; 131 margin: 0 auto; 132 text-align: center; 133 } 134 135 .hero-video .hero-caption.text-start { 136 margin-left: auto; 137 } 138 139 .hero-video .hero-overlay { 140 justify-content: center; 141 } 142} 143 144@media (max-width: 767.98px) { 145 .hero-video, 146 #siteCarousel { 147 aspect-ratio: 16 / 9; 148 } 149} 150 151@media (max-width: 575.98px) { 152 .hero-video .hero-caption { 153 padding: .75rem; 154 max-width: calc(100% - 2rem); 155 } 156} 157 158/* iOS-specific video optimizations */ 159@supports (-webkit-touch-callout: none) { 160 .hero-video video { 161 -webkit-transform: translateZ(0); 162 transform: translateZ(0); 163 } 164} 165 166.hero-video-wrapper { 167 width: auto; 168 margin-left: -12px; 169 margin-right: -12px; 170} 171 172.hero-video { 173 border-radius: 0px; 174} 175 176#siteCarousel .carousel-inner { 177 border-radius: 0px; 178} 179 180#siteCarousel .carousel-image { 181 border-radius: 0px; 182} 183 184/* ---------------------------------------------------------------- 185 School buttons on hero-video overlay (stacked and equal width) 186 Place the HTML for the buttons inside .hero-overlay, e.g.: 187 <div class="school-buttons">
188 <a href="/HighSchool" class="btn-school">High School</a> 189 <a href="/MiddleSchool" class="btn-school">Middle School</a> 190 </div> 191 ---------------------------------------------------------------- */ 192 193/* Container for the stacked school buttons */ 194.hero-video .hero-overlay .school-buttons { 195 position: absolute; 196 top: 12px; 197 left: 12px; 198 display: flex; 199 flex-direction: column; /* stack vertically */ 200 gap: 8px; 201 z-index: 5; /* above overlay content */ 202 align-items: stretch; /* children stretch to container width */ 203 width: -webkit-max-content; /* size to widest child */ 204 width: -moz-max-content; 205 width: max-content; 206 pointer-events: auto; /* allow clicks */ 207} 208 209 /* Button base style (fills container width) */ 210 .hero-video .hero-overlay .school-buttons .btn-school { 211 display: inline-flex; 212 align-items: center; 213 justify-content: center; 214 width: 100%; /* equal width */ 215 /* padding: 8px 12px; */ 216padding: 12px 16px; 217 border-radius: 8px; 218 background: rgba(0,0,0, 0.80); 219 /* background: rgba(15, 23, 42, 0.85) */; 220 color: #fff; 221 font-weight: 700; 222 font-size: 0.95rem; 223 border: 1px solid rgba(255,255,255,0.06); 224 text-decoration: none; 225 transition: background 160ms ease, transform 120ms ease; 226 -webkit-tap-highlight-color: transparent; 227 } 228 229 /* Hover / focus */ 230 .hero-video .hero-overlay .school-buttons .btn-school:hover, 231 .hero-video .hero-overlay .school-buttons .btn-school:focus { 232 background: linear-gradient(90deg,#BBA687,#F59E0B); 233 color: #0f172a; 234 transform: translateY(-1px); 235 outline: none; 236 text-decoration: none; 237 } 238 239/* Small screen adjustments */ 240@media (max-width: 576px) { 241 .hero-video .hero-overlay .school-buttons { 242 top: 8px; 243 left: 8px; 244 gap: 6px; 245 } 246 247 .hero-video .hero-overlay .school-buttons .btn-school { 248 padding: 6px 10px; 249 font-size: 0.85rem; 250 border-radius: 6px; 251 } 252} 253 254/* Center stacked school buttons vertically in the middle of the video */ 255.hero-video .hero-overlay .school-buttons.center-vertical { 256 position: absolute; 257 top: 50%; /* center vertically */ 258 left: 12px; 259 transform: translateY(-50%); /* shift up by half height */ 260} 261 262/* On very small screens prefer top-left placement to avoid covering caption */ 263@media (max-width: 576px) { 264 .hero-video .hero-overlay .school-buttons.center-vertical { 265 top: 12px; 266 left: 12px; 267 transform: none; 268 align-items: flex-start; 269 width: -webkit-max-content; 270 width: -moz-max-content; 271 width: max-content; 272 } 273} 274 275/* ---------------------------------------------------------------- 276 Facebook Grid (Desktop/Tablet) 277 ---------------------------------------------------------------- */ 278.facebook-grid { 279 display: grid; 280 grid-template-columns: repeat(3, 1fr); 281 gap: 1rem; 282 align-items: stretch; 283} 284 285.facebook-card { 286 background: #fff; 287 border-radius: 8px; 288 overflow: hidden; 289 box-shadow: 0 2px 8px rgba(0,0,0,0.06); 290 display: flex; 291 flex-direction: column; 292 min-height: 0; 293 height: 100%; 294} 295 296.facebook-card-media img { 297 width: 100%; 298 height: 200px; 299 object-fit: cover; 300 object-position: top center; 301 display: block; 302} 303 304.facebook-card-body { 305 padding: 0.75rem 1rem; 306 flex: 1; 307 display: flex; 308 flex-direction: column; 309 justify-content: space-between; 310} 311 312.facebook-card-text { 313 color: #444; 314 font-size: 0.95rem; 315 line-height: 1.4; 316 margin-bottom: 0.5rem; 317 text-align: left; 318 word-wrap: break-word; 319 overflow-wrap: break-word; 320} 321 322.facebook-card-meta { 323 display: flex;
324 align-items: center; 325 justify-content: flex-start; 326 gap: 0.5rem; 327 font-size: 0.85rem; 328 color: #6c757d; 329 flex-wrap: wrap; 330} 331 332@media (max-width: 991px) { 333 .facebook-grid { 334 grid-template-columns: repeat(2, 1fr); 335 } 336} 337 338@media (max-width: 575px) { 339 .facebook-grid { 340 grid-template-columns: 1fr; 341 } 342 343 .facebook-card-media img { 344 height: 180px; 345 } 346} 347 348/* ---------------------------------------------------------------- 349 Mobile Carousel for Facebook Cards (â¤576px) 350 ---------------------------------------------------------------- */ 351.facebook-carousel-wrapper { 352 position: relative; 353 overflow: hidden !important; 354 width: 100%; 355 max-width: 100%; 356 box-sizing: border-box; 357 margin: 0 auto; 358 padding: 0; 359} 360 361.facebook-carousel-track { 362 display: flex; 363 width: 100%; 364 transition: transform 300ms ease, height 300ms ease; /* add height transition */ 365 will-change: transform, height; 366 touch-action: pan-y; 367 gap: 0; 368 margin: 0; 369 padding: 0; 370 align-items: flex-start; 371 overflow: visible; /* allow content to determine height */ 372} 373 374/* Each card becomes full-width slide with variable height */ 375.facebook-carousel-track .facebook-card { 376 flex: 0 0 100%; 377 width: 100%; 378 max-width: 100%; 379 min-width: 100%; 380 box-sizing: border-box; 381 margin: 0; 382 padding: 0; 383 height: auto !important; /* allow natural/variable height */ 384 min-height: auto !important; /* override any min-height */ 385 border-radius: 0 !important; /* remove radius on mobile */ 386 box-shadow: none !important; /* remove shadow on mobile */ 387} 388 389.facebook-carousel-track .facebook-card-media { 390 width: 100%; 391 max-width: 100%; 392 overflow: hidden; 393} 394 395.facebook-carousel-track .facebook-card-media img { 396 display: block; 397 width: 100%; 398 max-width: 100%; 399 height: auto; 400 max-height: 400px; 401 object-fit: cover; 402 object-position: top center; 403} 404 405.facebook-carousel-track .facebook-card-body { 406 padding: 0.75rem 1rem; 407 display: flex; 408 flex-direction: column; 409 justify-content: flex-start; 410} 411 412.facebook-carousel-track .facebook-card-text { 413 word-wrap: break-word; 414 overflow-wrap: break-word; 415 max-width: 100%; 416} 417 418/* Controls */ 419.facebook-carousel-controls { 420 display: flex; 421 gap: 12px; 422 justify-content: center; 423 align-items: center; 424 margin-top: 1rem; 425 padding: 0.5rem 0; 426} 427 428.facebook-prev, 429.facebook-next { 430 min-width: 44px; 431 height: 44px; 432 display: inline-flex;
433 align-items: center; 434 justify-content: center; 435 border-radius: 6px; 436 padding: 0 12px; 437 font-size: 1.5rem; 438 background: rgba(0,0,0,0.05); 439 border: 1px solid rgba(0,0,0,0.1); 440 cursor: pointer; 441} 442 443.facebook-prev:hover, 444.facebook-next:hover { 445 background: rgba(0,0,0,0.1); 446} 447 448.facebook-carousel-dots { 449 display: flex; 450 gap: 6px; 451 align-items: center; 452display:none; 453} 454 455.facebook-dot { 456 width: 10px; 457 height: 10px; 458 border-radius: 50%; 459 background: rgba(0,0,0,0.12); 460 border: none; 461 padding: 0; 462 cursor: pointer; 463 transition: all 0.2s; 464} 465 466.facebook-dot.active { 467 background: #BBA687; 468 transform: scale(1.2); 469} 470 471/* Mobile-specific constraints */ 472@media (max-width: 576px) { 473 .facebook-grid { 474 display: none !important; 475 } 476 477 .facebook-carousel-wrapper, 478 .facebook-carousel-controls { 479 display: block; 480 } 481 482 #facebookGridContainer { 483 width: 100%; 484 max-width: 100%; 485 overflow: hidden !important; 486 box-sizing: border-box; 487 padding: 0; 488 margin: 0; 489 } 490 491 /* Ensure parent containers don't overflow */ 492 .event-area, 493 .container { 494 max-width: 100%; 495 overflow-x: hidden; 496 } 497} 498 499/* Desktop */ 500@media (min-width: 577px) { 501 .facebook-carousel-wrapper, 502 .facebook-carousel-controls { 503 display: none; 504 } 505} 506 507 508.service-area.two { 509width: calc(100% - 100px); 510position: relative; 511z-index: 20; 512 margin: -100px 50px 0; 513 border-top-left-radius: 5px; 514 border-top-right-radius: 5px; 515 background: linear-gradient(180deg, rgb(187 166 135) 0%, rgb(187 166 135) 0%, #ffffff 100%); 516} 517 518.varsity-backdrop{ 519display:none 520} 521 522 523.content-body[data-ishomepage="False"] a { 524 color: #000000; 525 text-decoration: underline; 526} 527 528 .content-body[data-ishomepage="False"] a:hover { 529 color: #BBA687; 530 text-decoration: underline; 531 } 532 533 534 .video-controls { 535 position: absolute; 536 right: 15px; 537 bottom: 15px; 538 z-index: 10; 539 540 display: flex; 541 gap: 10px; 542} 543 544.video-control-btn { 545 width: 44px; 546 height: 44px; 547 548 display: flex;
549 align-items: center; 550 justify-content: center; 551 552 border: none; 553 border-radius: 50%; 554 555 background: rgba(0, 0, 0, 0.8); 556 color: #fff; 557 558 cursor: pointer; 559 transition: all .2s ease; 560} 561 562.video-control-btn:hover, 563.video-control-btn:focus { 564 background: #BBA687; 565 color: #000; 566 outline: 3px solid #fff; 567 outline-offset: 2px; 568} 569 570.video-control-btn i { 571 font-size: 1rem; 572} 573 </style> 574 575 576 <!-- Pass SessionId to JavaScript securely --> 577
577<script> 578 window.SRSD_SessionId = '01a102d6-9edb-74fa-b302-a7b6a7bfc46d'; 579 </script>
579 580 581
581<script> 582 window.SRSD_GoogleAnalyticsId = 'UA-24485360-2'; 583 </script>
583 584 585 586 <!-- Google Translate Script --> 587
587<script type="text/javascript"> 588 function googleTranslateElementInit() { 589 new google.translate.TranslateElement({ 590 pageLanguage: 'en', 591 includedLanguages: 'es,fr,de,it,pt,zh-CN,zh-TW,ja,ko,ar,hi,ru,pl,nl,sv,no,da,fi,tr,el,he,vi,th,id,ms,tl', 592 layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL, 593 autoDisplay: false, 594 multilanguagePage: true 595 }, 'google_translate_element'); 596 } 597 </script>
597 598
598<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
598 599</head> 600<body> 601 <div id="a11y-content-wrapper"> 602 603 <h1 class="visually-hidden" id="page-title"> 604 High School 605 </h1> 606 607 <!-- Skip to Main Content --> 608 609 610 611 <!-- Header Area Start --> 612 <header class="top"> 613 614 <div class="header-area"> 615 <div class="container"> 616 <div class="row pt-2 headerColor"> 617 618 <div class="col-12 text-end"> 619 620 621 <a href="/" title="District Homepage" class="btn btn-link select-schools-link" id="lnkDistrictHomePage" aria-label="District Home Page">District</a> 622 623 <a href="#" title="Select a School Menu" class="btn btn-link select-schools-link" id="menuToggle_Schools" aria-label="Select School">Schools<i class="fa-solid fa-chevron-right" style="font-size:0.65rem"></i></a> 624 <!-- Translation dropdown (uses Font Awesome globe icon) --> 625 626 <div id="google_translate_element"></div> 627 628 <div class="header-social"> 629 <ul> 630 631 <li><a target="_blank" title="Facebook" href="https://www.facebook.com/share/1BEiixaxfh/?mibextid=wwXIfr"><i class="fab fa-facebook-f"></i></a></li> 632 <li><a target="_blank" title="Instagram" href="https://www.instagram.com/ramlifesrsd/?igsh=MW80YTNkeG9nNXB3Mg%3D%3D&utm_source=qr"><i class="fab fa-instagram"></i></a></li> 633 </ul> 634 </div> 635 636 637 </div> 638 639 </div> 640 </div> 641 </div> 642 643 644 645 646 647 648 649 650 651 652 <div class="header-area header-sticky" style="background-color: white;"> 653 <div class="container"> 654 <div class="row align-items-center"> 655 <div class="col-md-9 col-sm-7 col-6"> 656 <div class="logo-container mt-2 mb-1"> 657 <div class="logo"> 658 <a href="/"> 659 <img src="/assets/images/logos/srLogo_1.png" alt="Southern Regional School District" /> 660 </a> 661 </div> 662 <div class="logoText"> 663 <span class="logo-title"> 664 <span class="line1">Southern Regional</span> 665 <span class="line2">High School</span> 666 </span> 667 <span class="logo-subtitle"></span> 668 </div> 669 </div> 670 </div> 671 <div class="col-md-3 col-sm-5 col-6"> 672 <div class="content-wrapper text-end"> 673 <!-- Hamburger Menu Button --> 674 <button class="hamburger-menu-btn" id="menuToggle" type="button" 675 aria-label="Toggle navigation menu" aria-expanded="false"> 676 <span class="hamburger-line"></span> 677 <span class="hamburger-line"></span> 678 <span class="hamburger-line"></span> 679 </button> 680 681 <!--Search Form Start--> 682 <div class="search-btn"> 683 <ul class="header-search search-toggle"> 684 <li class="search-menu"> 685 <i class="fa fa-search"></i> 686 </li> 687 </ul> 688 <div class="search"> 689 <div class="search-form"> 690 <form id="search-form" action="/Search" method="get"> 691 <input type="search" placeholder="Search here..." name="q" aria-label="Search" /> 692 <button type="submit" aria-label="Submit search">
693 <span><i class="fa fa-search"></i></span> 694 </button> 695 </form> 696 </div> 697 </div> 698 </div> 699 <!--End of Search Form--> 700 </div> 701 </div> 702 </div> 703 </div> 704 </div> 705 </header> 706 <!-- Header Area End --> 707 <!-- Off-Canvas Navigation Panel --> 708 <div class="offcanvas-overlay" id="offcanvasOverlay"></div> 709 <nav class="offcanvas-menu" id="offcanvasMenu" role="navigation" aria-label="Main navigation"> 710 <div class="offcanvas-header"> 711 <div class="offcanvas-logo"> 712 713 <h2>HIGH SCHOOL</h2> 714 </div> 715 <button class="offcanvas-close" id="menuClose" type="button" aria-label="Close navigation menu"> 716 <i class="fa fa-times"></i> 717 </button> 718 </div> 719 <div class="offcanvas-body"> 720 721 <div class="d-lg-none"> 722 <ul class="offcanvas-nav-list"> 723 <li class="nav-item dropdown" data-level="0"> 724 <a class="nav-link dropdown-toggle has-icon" 725 href="javascript:void(0);" 726 id="dropdown_District_0_56cfdbf3" 727 role="button" 728 aria-expanded="false" 729 tabindex="0" 730 style="padding-left: 20px; padding-right: 45px;"> 731 District 732 <i class="fas fa-chevron-down dropdown-arrow"></i> 733 </a> 734 <ul class="dropdown-menu" aria-labelledby="dropdown_District_0_56cfdbf3"> 735 736 <li class="nav-item"> 737 <a class="dropdown-item" 738 href="/" 739 target="_self" 740 style="padding-left: 35px;"> 741 Home 742 </a> 743 </li> </ul> 744 </li> 745 746 <li class="nav-item"> 747 <a class="nav-link" 748 href="/HighSchool" 749 target="_self" 750 style="padding-left: 20px;"> 751 Home 752 </a> 753 </li> 754 <li class="nav-item"> 755 <a class="nav-link" 756 href="https://athletics.srsd.net" 757 target="_blank" 758 style="padding-left: 20px;"> 759 Athletics 760 </a> 761 </li> 762 <li class="nav-item"> 763 <a class="nav-link" 764 href="/HighSchool/Contacts" 765 target="_self" 766 style="padding-left: 20px;"> 767 Contacts 768 </a> 769 </li> <li class="nav-item dropdown" data-level="0"> 770 <a class="nav-link dropdown-toggle has-icon" 771 href="javascript:void(0);" 772 id="dropdown_Departments_0_fe83ab50" 773 role="button" 774 aria-expanded="false" 775 tabindex="0" 776 style="padding-left: 20px; padding-right: 45px;"> 777 Departments 778 <i class="fas fa-chevron-down dropdown-arrow"></i> 779 </a> 780 <ul class="dropdown-menu" aria-labelledby="dropdown_Departments_0_fe83ab50"> 781 782 <li class="nav-item"> 783 <a class="dropdown-item" 784 href="/HighSchool/Departments/AFJROTC" 785 target="_self" 786 style="padding-left: 35px;"> 787 Air Force Junior ROTC 788 </a> 789 </li> 790 <li class="nav-item"> 791 <a class="dropdown-item" 792 href="/HighSchool/Departments/AppliedTech" 793 target="_self" 794 style="padding-left: 35px;"> 795 Applied Technology 796 </a> 797 </li> 798 <li class="nav-item"> 799 <a class="dropdown-item"
800 href="/HighSchool/Departments/Art" 801 target="_self" 802 style="padding-left: 35px;"> 803 Art 804 </a> 805 </li> 806 <li class="nav-item"> 807 <a class="dropdown-item" 808 href="/HighSchool/Departments/BizEd" 809 target="_self" 810 style="padding-left: 35px;"> 811 Business and Computer Education 812 </a> 813 </li> 814 <li class="nav-item"> 815 <a class="dropdown-item" 816 href="/HighSchool/Departments/English" 817 target="_self" 818 style="padding-left: 35px;"> 819 English 820 </a> 821 </li> 822 <li class="nav-item"> 823 <a class="dropdown-item" 824 href="/HighSchool/Departments/ESL" 825 target="_self" 826 style="padding-left: 35px;"> 827 ESL 828 </a> 829 </li> 830 <li class="nav-item"> 831 <a class="dropdown-item" 832 href="/HighSchool/Departments/FCS" 833 target="_self" 834 style="padding-left: 35px;"> 835 Family and Consumer Science 836 </a> 837 </li> 838 <li class="nav-item"> 839 <a class="dropdown-item" 840 href="/HighSchool/Departments/Guidance" 841 target="_self" 842 style="padding-left: 35px;"> 843 Guidance 844 </a> 845 </li> 846 <li class="nav-item"> 847 <a class="dropdown-item" 848 href="/HighSchool/Departments/Math" 849 target="_self" 850 style="padding-left: 35px;"> 851 Mathematics 852 </a> 853 </li> 854 <li class="nav-item"> 855 <a class="dropdown-item" 856 href="/HighSchool/Departments/Music" 857 target="_self" 858 style="padding-left: 35px;"> 859 Performing Arts 860 </a> 861 </li> 862 <li class="nav-item"> 863 <a class="dropdown-item" 864 href="/HighSchool/Departments/Physed" 865 target="_self" 866 style="padding-left: 35px;"> 867 Physical Education 868 </a> 869 </li> 870 <li class="nav-item"> 871 <a class="dropdown-item" 872 href="/HighSchool/Departments/Science" 873 target="_self" 874 style="padding-left: 35px;"> 875 Science 876 </a> 877 </li> 878 <li class="nav-item"> 879 <a class="dropdown-item" 880 href="/HighSchool/Departments/SocialStudies" 881 target="_self" 882 style="padding-left: 35px;"> 883 Social Studies 884 </a> 885 </li> 886 <li class="nav-item"> 887 <a class="dropdown-item" 888 href="/HighSchool/Departments/SpecServ" 889 target="_self" 890 style="padding-left: 35px;"> 891 Special Services 892 </a> 893 </li> 894 <li class="nav-item"> 895 <a class="dropdown-item" 896 href="/HighSchool/Departments/ModernMedia" 897 target="_self" 898 style="padding-left: 35px;"> 899 TV Production 900 </a> 901 </li> 902 <li class="nav-item"> 903 <a class="dropdown-item" 904 href="/HighSchool/Departments/WorldLanguage" 905 target="_self" 906 style="padding-left: 35px;"> 907 World Language 908 </a> 909 </li> </ul> 910 </li> 911 <li class="nav-item dropdown" data-level="0"> 912 <a class="nav-link dropdown-toggle has-icon" 913 href="javascript:void(0);" 914 id="dropdown_Students_0_d717a794" 915 role="button" 916 aria-expanded="false" 917 tabindex="0" 918 style="padding-left: 20px; padding-right: 45px;"> 919 Students 920 <i class="fas fa-chevron-down dropdown-arrow"></i> 921 </a> 922 <ul class="dropdown-menu" aria-labelledby="dropdown_Students_0_d717a794"> 923 924 <li class="nav-item"> 925 <a class="dropdown-item"
926 href="/HighSchool/Stulife" 927 target="_self" 928 style="padding-left: 35px;"> 929 Dashboard 930 </a> 931 </li> 932 <li class="nav-item"> 933 <a class="dropdown-item" 934 href="/HighSchool/StuLife/Clubs" 935 target="_self" 936 style="padding-left: 35px;"> 937 Clubs & Activities 938 </a> 939 </li> 940 <li class="nav-item"> 941 <a class="dropdown-item" 942 href="https://webappsv3.srsd.net/Applications/Students/ConfidenceCloset/Store" 943 target="_blank" 944 style="padding-left: 35px;"> 945 Confidence Closet 946 </a> 947 </li> 948 <li class="nav-item"> 949 <a class="dropdown-item" 950 href="https://mail.google.com/a/srsd.org" 951 target="_blank" 952 style="padding-left: 35px;"> 953 Email 954 </a> 955 </li> 956 <li class="nav-item"> 957 <a class="dropdown-item" 958 href="https://students.c3.genesisedu.net/srsd/sis/view?gohome=true" 959 target="_blank" 960 style="padding-left: 35px;"> 961 Genesis Portal 962 </a> 963 </li> 964 <li class="nav-item"> 965 <a class="dropdown-item" 966 href="https://www.desmos.com/calculator" 967 target="_blank" 968 style="padding-left: 35px;"> 969 Desmos 970 </a> 971 </li> 972 <li class="nav-item"> 973 <a class="dropdown-item" 974 href="/HighSchool/StuLife/NationalHonorSociety" 975 target="_self" 976 style="padding-left: 35px;"> 977 National Honor Society 978 </a> 979 </li> 980 <li class="nav-item"> 981 <a class="dropdown-item" 982 href="https://www.ixl.com/signin/southernregsd" 983 target="_blank" 984 style="padding-left: 35px;"> 985 IXL 986 </a> 987 </li> 988 <li class="nav-item"> 989 <a class="dropdown-item" 990 href="http://www.khanacademy.org/" 991 target="_blank" 992 style="padding-left: 35px;"> 993 Khan Academy 994 </a> 995 </li> 996 <li class="nav-item"> 997 <a class="dropdown-item" 998 href="http://srsdlibraryportal.weebly.com/" 999 target="_blank" 1000 style="padding-left: 35px;"> 1001 Library Portal 1002 </a> 1003 </li> 1004 <li class="nav-item"> 1005 <a class="dropdown-item" 1006 href="https://student.naviance.com/southernreg" 1007 target="_blank" 1008 style="padding-left: 35px;"> 1009 Naviance 1010 </a> 1011 </li> 1012 <li class="nav-item"> 1013 <a class="dropdown-item" 1014 href="https://www.noredink.com/login" 1015 target="_blank" 1016 style="padding-left: 35px;"> 1017 No Red Ink 1018 </a> 1019 </li> 1020 <li class="nav-item"> 1021 <a class="dropdown-item" 1022 href="http://theoceancountylibrary.org/" 1023 target="_self" 1024 style="padding-left: 35px;"> 1025 Ocean County Library 1026 </a> 1027 </li> 1028 <li class="nav-item"> 1029 <a class="dropdown-item" 1030 href="https://login.microsoftonline.com/?whr=srsd.org" 1031 target="_blank" 1032 style="padding-left: 35px;"> 1033 Office 365 1034 </a> 1035 </li> 1036 <li class="nav-item"> 1037 <a class="dropdown-item" 1038 href="https://www.peardeck.com/products/pear-assessment" 1039 target="_blank" 1040 style="padding-left: 35px;"> 1041 Pear Assessment 1042 </a> 1043 </li> 1044 <li class="nav-item"> 1045 <a class="dropdown-item" 1046 href="http://pressofatlanticcity.com/" 1047 target="_blank" 1048 style="padding-left: 35px;"> 1049 Press of AC 1050 </a> 1051 </li> 1052 <li class="nav-item"> 1053 <a class="dropdown-item" 1054 href="http://www.quill.org/" 1055 target="_blank" 1056 style="padding-left: 35px;"> 1057 Quill 1058 </a> 1059 </li> 1060 <li class="nav-item"> 1061 <a class="dropdown-item" 1062 href="http://www.quizlet.com/" 1063 target="_blank" 1064 style="padding-left: 35px;"> 1065 Quizlet 1066 </a> 1067 </li> 1068 <li class="nav-item"> 1069 <a class="dropdown-item" 1070 href="https://www.readworks.org/" 1071 target="_blank" 1072 style="padding-left: 35px;"> 1073 ReadWorks 1074 </a> 1075 </li> 1076 <li class="nav-item"> 1077 <a class="dropdown-item" 1078 href="https://www.savvas.com/" 1079 target="_blank" 1080 style="padding-left: 35px;"> 1081 Savvas 1082 </a> 1083 </li> 1084 <li class="nav-item"> 1085 <a class="dropdown-item"
1086 href="/HighSchool/StudentBulletins" 1087 target="_self" 1088 style="padding-left: 35px;"> 1089 Student Bulletins 1090 </a> 1091 </li> 1092 <li class="nav-item"> 1093 <a class="dropdown-item" 1094 href="/uploads/website/High School/Student Life/2627/HSStudentHandbook2026-2027FINAL080426.pdf" 1095 target="_blank" 1096 style="padding-left: 35px;"> 1097 Student Handbook 1098 </a> 1099 </li> 1100 <li class="nav-item"> 1101 <a class="dropdown-item" 1102 href="https://sites.google.com/a/srsd.org/southern-regional-student-council/" 1103 target="_blank" 1104 style="padding-left: 35px;"> 1105 Student Council 1106 </a> 1107 </li> 1108 <li class="nav-item"> 1109 <a class="dropdown-item" 1110 href="https://wayground.com/login" 1111 target="_blank" 1112 style="padding-left: 35px;"> 1113 Waygound 1114 </a> 1115 </li> </ul> 1116 </li> 1117 </ul> 1118 </div> 1119 <div class="nav-desktop-layout d-none d-lg-flex"> 1120 1121 <div class="nav-col-headers"> 1122 <ul class="nav-desktop-headers-list"> 1123 <li class="nav-desktop-header-item active"> 1124 <button class="nav-desktop-header-button" 1125 type="button" 1126 data-panel="nav-panel-0" 1127 aria-expanded="true"> 1128 <span>District</span> 1129 <i class="fas fa-chevron-right nav-header-arrow" aria-hidden="true"></i> 1130 </button> 1131 </li> 1132 <li class="nav-desktop-header-item nav-desktop-header-link"> 1133 <a href="/HighSchool" 1134 target="_self"> 1135 Home 1136 </a> 1137 </li> 1138 <li class="nav-desktop-header-item nav-desktop-header-link"> 1139 <a href="https://athletics.srsd.net" 1140 target="_blank"> 1141 Athletics 1142 </a> 1143 </li> 1144 <li class="nav-desktop-header-item nav-desktop-header-link"> 1145 <a href="/HighSchool/Contacts" 1146 target="_self"> 1147 Contacts 1148 </a> 1149 </li> 1150 <li class="nav-desktop-header-item"> 1151 <button class="nav-desktop-header-button" 1152 type="button" 1153 data-panel="nav-panel-4" 1154 aria-expanded="false"> 1155 <span>Departments</span> 1156 <i class="fas fa-chevron-right nav-header-arrow" aria-hidden="true"></i> 1157 </button> 1158 </li> 1159 <li class="nav-desktop-header-item"> 1160 <button class="nav-desktop-header-button" 1161 type="button" 1162 data-panel="nav-panel-5" 1163 aria-expanded="false"> 1164 <span>Students</span> 1165 <i class="fas fa-chevron-right nav-header-arrow" aria-hidden="true"></i> 1166 </button> 1167 </li> 1168 </ul> 1169 </div> 1170 1171 1172 <div class="nav-col-divider" aria-hidden="true"></div> 1173 1174 <div class="nav-col-children"> 1175 <div class="nav-desktop-children-panel active" id="nav-panel-0"> 1176 <ul class="nav-desktop-children-list"> 1177 1178 <li> 1179 <a class="nav-desktop-child-link" 1180 href="/" 1181 target="_self"> 1182 Home 1183 </a> 1184 </li> </ul> 1185 </div> 1186 <div class="nav-desktop-children-panel" id="nav-panel-1"> 1187 <div class="nav-desktop-solo-panel">
1188 <a href="/HighSchool" 1189 class="nav-desktop-solo-link" 1190 target="_self"> 1191 Home <i class="fas fa-chevron-right ms-1" aria-hidden="true"></i> 1192 </a> 1193 </div> 1194 </div> 1195 <div class="nav-desktop-children-panel" id="nav-panel-2"> 1196 <div class="nav-desktop-solo-panel"> 1197 <a href="https://athletics.srsd.net" 1198 class="nav-desktop-solo-link" 1199 target="_blank"> 1200 Athletics <i class="fas fa-chevron-right ms-1" aria-hidden="true"></i> 1201 </a> 1202 </div> 1203 </div> 1204 <div class="nav-desktop-children-panel" id="nav-panel-3"> 1205 <div class="nav-desktop-solo-panel"> 1206 <a href="/HighSchool/Contacts" 1207 class="nav-desktop-solo-link" 1208 target="_self"> 1209 Contacts <i class="fas fa-chevron-right ms-1" aria-hidden="true"></i> 1210 </a> 1211 </div> 1212 </div> 1213 <div class="nav-desktop-children-panel" id="nav-panel-4"> 1214 <ul class="nav-desktop-children-list"> 1215 1216 <li> 1217 <a class="nav-desktop-child-link" 1218 href="/HighSchool/Departments/AFJROTC" 1219 target="_self"> 1220 Air Force Junior ROTC 1221 </a> 1222 </li> 1223 <li> 1224 <a class="nav-desktop-child-link" 1225 href="/HighSchool/Departments/AppliedTech" 1226 target="_self"> 1227 Applied Technology 1228 </a> 1229 </li> 1230 <li> 1231 <a class="nav-desktop-child-link" 1232 href="/HighSchool/Departments/Art" 1233 target="_self"> 1234 Art 1235 </a> 1236 </li> 1237 <li> 1238 <a class="nav-desktop-child-link" 1239 href="/HighSchool/Departments/BizEd" 1240 target="_self"> 1241 Business and Computer Education 1242 </a> 1243 </li> 1244 <li> 1245 <a class="nav-desktop-child-link" 1246 href="/HighSchool/Departments/English" 1247 target="_self"> 1248 English 1249 </a> 1250 </li> 1251 <li> 1252 <a class="nav-desktop-child-link" 1253 href="/HighSchool/Departments/ESL" 1254 target="_self"> 1255 ESL 1256 </a> 1257 </li> 1258 <li> 1259 <a class="nav-desktop-child-link" 1260 href="/HighSchool/Departments/FCS" 1261 target="_self"> 1262 Family and Consumer Science 1263 </a> 1264 </li> 1265 <li> 1266 <a class="nav-desktop-child-link" 1267 href="/HighSchool/Departments/Guidance" 1268 target="_self"> 1269 Guidance 1270 </a> 1271 </li> 1272 <li> 1273 <a class="nav-desktop-child-link" 1274 href="/HighSchool/Departments/Math" 1275 target="_self"> 1276 Mathematics 1277 </a> 1278 </li> 1279 <li> 1280 <a class="nav-desktop-child-link" 1281 href="/HighSchool/Departments/Music" 1282 target="_self"> 1283 Performing Arts 1284 </a> 1285 </li> 1286 <li> 1287 <a class="nav-desktop-child-link" 1288 href="/HighSchool/Departments/Physed" 1289 target="_self"> 1290 Physical Education 1291 </a> 1292 </li> 1293 <li> 1294 <a class="nav-desktop-child-link"
1295 href="/HighSchool/Departments/Science" 1296 target="_self"> 1297 Science 1298 </a> 1299 </li> 1300 <li> 1301 <a class="nav-desktop-child-link" 1302 href="/HighSchool/Departments/SocialStudies" 1303 target="_self"> 1304 Social Studies 1305 </a> 1306 </li> 1307 <li> 1308 <a class="nav-desktop-child-link" 1309 href="/HighSchool/Departments/SpecServ" 1310 target="_self"> 1311 Special Services 1312 </a> 1313 </li> 1314 <li> 1315 <a class="nav-desktop-child-link" 1316 href="/HighSchool/Departments/ModernMedia" 1317 target="_self"> 1318 TV Production 1319 </a> 1320 </li> 1321 <li> 1322 <a class="nav-desktop-child-link" 1323 href="/HighSchool/Departments/WorldLanguage" 1324 target="_self"> 1325 World Language 1326 </a> 1327 </li> </ul> 1328 </div> 1329 <div class="nav-desktop-children-panel" id="nav-panel-5"> 1330 <ul class="nav-desktop-children-list"> 1331 1332 <li> 1333 <a class="nav-desktop-child-link" 1334 href="/HighSchool/Stulife" 1335 target="_self"> 1336 Dashboard 1337 </a> 1338 </li> 1339 <li> 1340 <a class="nav-desktop-child-link" 1341 href="/HighSchool/StuLife/Clubs" 1342 target="_self"> 1343 Clubs & Activities 1344 </a> 1345 </li> 1346 <li> 1347 <a class="nav-desktop-child-link" 1348 href="https://webappsv3.srsd.net/Applications/Students/ConfidenceCloset/Store" 1349 target="_blank"> 1350 Confidence Closet 1351 </a> 1352 </li> 1353 <li> 1354 <a class="nav-desktop-child-link" 1355 href="https://mail.google.com/a/srsd.org" 1356 target="_blank"> 1357 Email 1358 </a> 1359 </li> 1360 <li> 1361 <a class="nav-desktop-child-link" 1362 href="https://students.c3.genesisedu.net/srsd/sis/view?gohome=true" 1363 target="_blank"> 1364 Genesis Portal 1365 </a> 1366 </li> 1367 <li> 1368 <a class="nav-desktop-child-link" 1369 href="https://www.desmos.com/calculator" 1370 target="_blank"> 1371 Desmos 1372 </a> 1373 </li> 1374 <li> 1375 <a class="nav-desktop-child-link" 1376 href="/HighSchool/StuLife/NationalHonorSociety" 1377 target="_self"> 1378 National Honor Society 1379 </a> 1380 </li> 1381 <li> 1382 <a class="nav-desktop-child-link" 1383 href="https://www.ixl.com/signin/southernregsd" 1384 target="_blank"> 1385 IXL 1386 </a> 1387 </li> 1388 <li> 1389 <a class="nav-desktop-child-link" 1390 href="http://www.khanacademy.org/" 1391 target="_blank"> 1392 Khan Academy 1393 </a> 1394 </li> 1395 <li> 1396 <a class="nav-desktop-child-link" 1397 href="http://srsdlibraryportal.weebly.com/" 1398 target="_blank"> 1399 Library Portal 1400 </a> 1401 </li> 1402 <li> 1403 <a class="nav-desktop-child-link" 1404 href="https://student.naviance.com/southernreg" 1405 target="_blank"> 1406 Naviance 1407 </a> 1408 </li> 1409 <li> 1410 <a class="nav-desktop-child-link" 1411 href="https://www.noredink.com/login" 1412 target="_blank"> 1413 No Red Ink 1414 </a> 1415 </li> 1416 <li> 1417 <a class="nav-desktop-child-link" 1418 href="http://theoceancountylibrary.org/" 1419 target="_self"> 1420 Ocean County Library 1421 </a> 1422 </li> 1423 <li> 1424 <a class="nav-desktop-child-link" 1425 href="https://login.microsoftonline.com/?whr=srsd.org" 1426 target="_blank"> 1427 Office 365 1428 </a> 1429 </li> 1430 <li> 1431 <a class="nav-desktop-child-link" 1432 href="https://www.peardeck.com/products/pear-assessment" 1433 target="_blank"> 1434 Pear Assessment 1435 </a> 1436 </li> 1437 <li> 1438 <a class="nav-desktop-child-link" 1439 href="http://pressofatlanticcity.com/" 1440 target="_blank"> 1441 Press of AC 1442 </a> 1443 </li> 1444 <li> 1445 <a class="nav-desktop-child-link" 1446 href="http://www.quill.org/" 1447 target="_blank"> 1448 Quill 1449 </a> 1450 </li> 1451 <li> 1452 <a class="nav-desktop-child-link" 1453 href="http://www.quizlet.com/" 1454 target="_blank"> 1455 Quizlet 1456 </a> 1457 </li> 1458 <li> 1459 <a class="nav-desktop-child-link" 1460 href="https://www.readworks.org/" 1461 target="_blank"> 1462 ReadWorks 1463 </a> 1464 </li> 1465 <li> 1466 <a class="nav-desktop-child-link" 1467 href="https://www.savvas.com/" 1468 target="_blank"> 1469 Savvas 1470 </a> 1471 </li> 1472 <li> 1473 <a class="nav-desktop-child-link"
1474 href="/HighSchool/StudentBulletins" 1475 target="_self"> 1476 Student Bulletins 1477 </a> 1478 </li> 1479 <li> 1480 <a class="nav-desktop-child-link" 1481 href="/uploads/website/High School/Student Life/2627/HSStudentHandbook2026-2027FINAL080426.pdf" 1482 target="_blank"> 1483 Student Handbook 1484 </a> 1485 </li> 1486 <li> 1487 <a class="nav-desktop-child-link" 1488 href="https://sites.google.com/a/srsd.org/southern-regional-student-council/" 1489 target="_blank"> 1490 Student Council 1491 </a> 1492 </li> 1493 <li> 1494 <a class="nav-desktop-child-link" 1495 href="https://wayground.com/login" 1496 target="_blank"> 1497 Waygound 1498 </a> 1499 </li> </ul> 1500 </div> 1501 </div> 1502 1503 </div> 1504 1505 1506 </div> 1507 </nav> 1508 1509 1510 <nav class="offcanvas-menu" id="offcanvasMenu_Schools" role="navigation" aria-label="Select Schools Navigation"> 1511 <div class="offcanvas-header"> 1512 <div class="offcanvas-logo" style="font-weight:600"> 1513 <h2>SCHOOLS</h2> 1514 </div> 1515 <button class="offcanvas-close" id="menuClose_Schools" type="button" aria-label="Close navigation menu"> 1516 <i class="fa fa-times"></i> 1517 </button> 1518 </div> 1519 <div class="offcanvas-body"> 1520 1521 <ul class="offcanvas-nav-list"> 1522 1523 <li class="nav-item"> 1524 <a class="nav-link" href="/HighSchool" target="_self" style="padding-left: 20px;" title="Southern Regional High School"> 1525 High School 1526 </a> 1527 </li> 1528 <li class="nav-item"> 1529 <a class="nav-link" href="/MiddleSchool" target="_self" style="padding-left: 20px;" title="Southern Regional Middle School"> 1530 Middle School 1531 </a> 1532 </li> 1533 </ul> 1534 1535 1536 </div> 1537 </nav> 1538 1539 1540 1541 1542 1543 1544 1545 <!-- Main Content Area --> 1546 <div class="container"> 1547 <main id="main-content" role="main" class="pb-3"> 1548 1549<input name="__RequestVerificationToken" type="hidden" value="CfDJ8A4nzWENaJhLnegwM-pvDews-Oqbs-qlsjmEZhMTshr9qubfSs57wAUSSCvbtpxqL9Zpl_Y-KTsK9vM2-YKskPmKOpoL5UmWzhn978IfeGRupZapHnzHwt9M1oHkgTIYU13OsUdhpKoN3AbMTfXGzbU" /> 1550 1551 1552 1553 1554<div class="dynamic-content"> 1555 1556 1557 1558 <div class="varsity-backdrop pt-3 mb-2" aria-hidden="false"> 1559 <div class="container"> 1560 1561 <h2 class="h1 fw-bold p-0 m-0">High School</h2> 1562 1563 <nav aria-label="breadcrumb" class="mb-3"> 1564 <ol class="breadcrumb"> 1565 <li class="breadcrumb-item"> 1566 <a href="/">Home</a> 1567 </li> 1568 <li class="breadcrumb-item active" aria-current="page">High School</li> 1569 </ol> 1570 </nav> 1571 </div> 1572 </div> 1573 <div class="content-body" data-ishomepage="False"> 1574 <section class="hero-video-wrapper" id="heroVideoWrapper" aria-label="Homepage featured content"> 1575 <!-- Video Hero (shown by default) --> 1576 <div id="heroVideoContainer" class="hero-video" style="opacity: 1; display: block;"> 1577 <video id="heroVideo" autoplay="true" loop="true" muted="true" playsinline="true" preload="auto" poster="/assets/images/hsDrone.jpg" webkit-playsinline="true"> 1578 <source src="https://videos.srsd.net/mp4/hsDroneV1.mp4" type="video/mp4"> 1579 </video> 1580 1581 <!-- Accessibility Controls --> 1582 <div class="video-controls"> 1583 <button id="videoPlayPause" type="button" class="video-control-btn" aria-label="Pause background video" aria-pressed="false"> 1584 <i class="fas fa-pause" aria-hidden="true"></i>
1585 <span class="visually-hidden">Pause Video</span> 1586 </button> 1587 1588 <button id="videoMute" type="button" class="video-control-btn" aria-label="Unmute background video" aria-pressed="true"> 1589 <i class="fas fa-volume-mute" aria-hidden="true"></i> 1590 <span class="visually-hidden">Toggle Audio</span> 1591 </button> 1592 </div> 1593 </div> 1594</section> 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613<div class="service-area two pt-25"> 1614 <div class="container"> 1615 <div class="row"> 1616 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1617 <a href="/Genesis" target="_blank"> 1618 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1619 <div class="card-body text-center"> 1620 <i class="fa-thin fa-computer fa-4x btnOne mainIconsBottomBorder"></i> 1621 <blockquote> 1622 Genesis Student & Parent Portals 1623 </blockquote> 1624 </div> 1625 </div> 1626 </a> 1627 </div> 1628 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1629 <a href="/Board/Services/Tech/Email"> 1630 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1631 <div class="card-body text-center"> 1632 <i class="fa-thin fa-envelope fa-4x btnTwo mainIconsBottomBorder"></i> 1633 <blockquote> 1634 Student & Faculty Email 1635 </blockquote> 1636 </div> 1637 </div> 1638 </a> 1639 </div> 1640 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1641 <a href="/HighSchool/Calendar"> 1642 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1643 <div class="card-body text-center"> 1644 <i class="fa-thin fa-calendars fa-4x btnFour mainIconsBottomBorder"></i> 1645 <blockquote> 1646 Academic & Activity Calendars 1647 </blockquote> 1648 </div> 1649 </div> 1650 </a> 1651 </div> 1652 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1653 <a href="/HighSchool/Departments/Guidance"> 1654 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1655 <div class="card-body text-center"> 1656 <i class="fa-thin fa-user-graduate fa-4x btnThree mainIconsBottomBorder"></i> 1657 <blockquote> 1658 Guidance 1659 </blockquote> 1660 </div> 1661 </div> 1662 </a> 1663 </div> 1664 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1665 <a href="/HighSchool/StudentBulletins"> 1666 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1667 <div class="card-body text-center"> 1668 <i class="fa-thin fa-newspaper fa-4x btnFive mainIconsBottomBorder"></i> 1669 <blockquote> 1670 Bulletins 1671 </blockquote> 1672 </div> 1673 </div> 1674 </a> 1675 </div> 1676 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1677 <a href="/HighSchool/StuLife/Clubs"> 1678 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1679 <div class="card-body text-center"> 1680 <i class="fa-thin fa-puzzle-piece fa-4x btnSix mainIconsBottomBorder"></i> 1681 <blockquote> 1682 Clubs/Activities 1683 </blockquote> 1684 </div> 1685 </div> 1686 </a> 1687 </div> 1688 1689 1690 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1691 <a target="_blank" href="/uploads/website/High%20School/Student%20Life/2627/HSStudentHandbook2026-2027FINAL080426.pdf"> 1692 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1693 <div class="card-body text-center"> 1694 <i class="fa-thin fa-book fa-4x btnSeven mainIconsBottomBorder"></i> 1695 <blockquote> 1696 Student Handbook 1697 </blockquote> 1698 </div> 1699 </div> 1700 </a> 1701 </div> 1702 1703 1704 1705 <div class="col-sm-6 col-md-4 col-lg-4 col-xl-3 mb-3"> 1706 <a target="_blank" href="https://athletics.srsd.net"> 1707 <div class="card shadow-sm h-100 makePop" style="transform: translateY(0px); box-shadow: rgba(0, 0, 0, 0.08) 0px 2px 8px;"> 1708 <div class="card-body text-center"> 1709 <i class="fa-thin fa-person-basketball fa-4x btnEight mainIconsBottomBorder"></i> 1710 <blockquote> 1711 Athletics 1712 </blockquote> 1713 </div> 1714 </div> 1715 </a> 1716 </div> 1717 1718 </div> 1719 </div> 1720</div> 1721 1722 1723 1724 1725 1726 1727 1728<div class="event-area one text-center pt-25 pb-25"> 1729 <div class="container"> 1730 <div class="row"> 1731 <div class="col-12"> 1732 <div class="section-title"> 1733 <h2>CLASS INFORMATION</h2> 1734 </div> 1735 </div> 1736 </div> 1737 <div id="classInformationContainer"> 1738 <div class="text-center py-4"> 1739 <i class="fa fa-spinner fa-spin fa-2x" aria-hidden="true"></i>
1740 <span class="ms-2">Loading Class Information...</span> 1741 </div> 1742 </div> 1743 </div> 1744</div> 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763<div class="event-area one text-center pt-25 pb-25"> 1764 <div class="container"> 1765 <div class="row"> 1766 <div class="col-12"> 1767 <div class="section-title"> 1768 <h2>Important Information</h2> 1769 </div> 1770 </div> 1771 </div> 1772 <div id="announcementsContainer"> 1773 <div class="text-center py-4"> 1774 <i class="fa fa-spinner fa-spin fa-2x" aria-hidden="true"></i> 1775 <span class="ms-2">Loading Important Information...</span> 1776 </div> 1777 </div> 1778 </div> 1779</div> 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798<div class="event-area one text-center pt-25 pb-25"> 1799 <div class="container"> 1800 <div class="row"> 1801 <div class="col-12"> 1802 <div class="section-title"> 1803 <h2>UPCOMING EVENTS</h2> 1804 </div> 1805 </div> 1806 </div> 1807 <div id="topTenCalendarEventsContainer"> 1808 <div class="text-center py-4"> 1809 <i class="fa fa-spinner fa-spin fa-2x" aria-hidden="true"></i> 1810 <span class="ms-2">Loading events...</span> 1811 </div> 1812 </div> 1813 </div> 1814</div> 1815 1816 1817 1818 1819 1820 1821 1822 1823<section class="about-school-section py-5"> 1824 <div class="container"> 1825 1826 <!-- Section Title --> 1827 <div class="text-center mb-4"> 1828 <h2 class="section-title">About Our School</h2> 1829 <p class="text-muted"> 1830 Southern Regional High School is committed to academic excellence, innovation, 1831 leadership development, and preparing students for success in college, careers, 1832 and life. 1833 </p> 1834 </div> 1835 1836 <!-- Main Content Card --> 1837 <div class="card shadow-sm border-0 rounded-4"> 1838 <div class="card-body p-4 p-md-5"> 1839 1840 <!-- Welcome --> 1841 <div class="mb-5"> 1842 <h3 class="fw-bold text-primary mb-3"> 1843 <i class="fa-solid fa-school me-2"></i>Welcome to Southern Regional High School 1844 </h3> 1845 1846 <p class="text-secondary lh-lg"> 1847 Southern Regional High School is an innovative, comprehensive, and challenging 1848 learning community dedicated to empowering students for future success. 1849 We proudly offer a diverse range of academic and co-curricular opportunities 1850 designed to meet the interests and aspirations of every student. 1851 </p> 1852 1853 <p class="text-secondary lh-lg"> 1854 Our faculty and staff take tremendous pride in representing the Southern 1855 Regional family. Their caring, student-centered, and nurturing approach 1856 creates an environment where students are encouraged to grow academically, 1857 socially, and personally. Together, we strive to remain a leading force 1858 in education while inspiring excellence in everything we do. 1859 </p> 1860 </div> 1861 1862 <!-- Academic Excellence --> 1863 <div class="mb-5"> 1864 <h4 class="fw-bold text-dark mb-3"> 1865 <i class="fa-solid fa-graduation-cap text-success me-2"></i>Academic Excellence 1866 </h4> 1867 1868 <p class="text-secondary lh-lg"> 1869 Southern Regional High School offers more than 200 courses designed to 1870 challenge, inspire, and prepare students for the future. Advanced Placement 1871 and Honors courses provide rigorous academic opportunities in
1871English, 1872 History, Mathematics, Science, Art, Music, and World Languages. 1873 </p> 1874 1875 <p class="text-secondary lh-lg"> 1876 Through our extensive Dual Credit Program, students may earn both high 1877 school and college credits in over 23 course offerings, giving them a 1878 valuable head start toward higher education and career pathways. 1879 </p> 1880 </div> 1881 1882 <!-- Career & Elective Opportunities --> 1883 <div class="mb-5"> 1884 <h4 class="fw-bold text-dark mb-3"> 1885 <i class="fa-solid fa-lightbulb text-warning me-2"></i>Career & Elective Opportunities 1886 </h4> 1887 1888 <p class="text-secondary lh-lg"> 1889 Students can explore a wide variety of elective courses designed to expose 1890 them to new interests, practical skills, and career-focused experiences. 1891 Programs in TV Production offer hands-on learning in sports broadcasting, 1892 news production, and film creation. 1893 </p> 1894 1895 <p class="text-secondary lh-lg"> 1896 The Applied Technology Department provides opportunities in woodworking, 1897 power and auto mechanics, metalworking, computer-aided design, photography, 1898 and engineering. Students can also develop creative talents through painting, 1899 drawing, pottery, sculpture, and other visual arts courses. 1900 </p> 1901 1902 <p class="text-secondary lh-lg"> 1903 Air Force Junior ROTC further expands student opportunities through 1904 aerospace science, leadership training, character development, 1905 and community service. 1906 </p> 1907 1908 <p class="text-secondary lh-lg"> 1909 The Family and Consumer Sciences Department offers a variety of courses in food preparation and nutrition, clothing and textiles, child development and parenting, consumer awareness, and personal and family relations. 1910 1911 1912 </p> 1913 </div> 1914 1915 <!-- Student Life --> 1916 <div class="mb-5"> 1917 <h4 class="fw-bold text-dark mb-3"> 1918 <i class="fa-solid fa-users text-info me-2"></i>Student Life & Involvement 1919 </h4> 1920 1921 <p class="text-secondary lh-lg"> 1922 Education extends beyond the classroom. Southern Regional High School 1923 offers more than 70 co-curricular and extracurricular activities, 1924 allowing students to pursue their passions, develop leadership skills, 1925 and build lifelong friendships. 1926 </p> 1927 1928 <p class="text-secondary lh-lg"> 1929 Participation in these programs fosters school spirit, teamwork, 1930 and personal growth, supporting our belief that 1931 <strong>"We Offer Something for Everyone."</strong> 1932 </p> 1933 </div> 1934 1935 <!-- Student Support --> 1936 <div class="mb-5"> 1937 <h4 class="fw-bold text-dark mb-3"> 1938 <i class="fa-solid fa-heart text-danger me-2"></i>Student Support Services 1939 </h4> 1940 1941 <p class="text-secondary lh-lg"> 1942 Our Guidance Department and Child Study Team work collaboratively to 1943 provide comprehensive support systems for all students. These services 1944 assist with high school transitions, academic planning, college and career 1945 readiness, special education services, and social-emotional wellbeing. 1946 </p> 1947 1948 <p class="text-secondary lh-lg"> 1949 By tailoring programs to individual needs and helping students establish 1950 meaningful goals, our support teams ensure every learner is positioned 1951 for success. 1952 </p> 1953 </div> 1954 1955 <!-- Highlights --> 1956 <div> 1957 <h4 class="fw-bold text-dark mb-3"> 1958 <i class="fa-solid fa-star text-warning me-2"></i>Program Highlights 1959 </h4> 1960 1961 <div class="row"> 1962 <div class="col-md-6"> 1963 <ul class="list-unstyled highlight-list"> 1964 <li><i class="fa-solid fa-check-circle text-success me-2"></i>200+ academic course offerings</li> 1965 <li><i class="fa-solid fa-check-circle text-success me-2"></i>Advanced Placement & Honors programs</li> 1966 <li><i class="fa-solid fa-check-circle text-success me-2"></i>23+ Dual Credit college courses</li> 1967 <li><i class="fa-solid fa-check-circle text-success me-2"></i>
1967Comprehensive Health & Wellness programs</li> 1968 </ul> 1969 </div> 1970 1971 <div class="col-md-6"> 1972 <ul class="list-unstyled highlight-list"> 1973 <li><i class="fa-solid fa-check-circle text-success me-2"></i>70+ clubs and extracurricular activities</li> 1974 <li><i class="fa-solid fa-check-circle text-success me-2"></i>Applied Technology & Engineering pathways</li> 1975 <li><i class="fa-solid fa-check-circle text-success me-2"></i>TV Production & Media programs</li> 1976 <li><i class="fa-solid fa-check-circle text-success me-2"></i>Air Force JROTC leadership opportunities</li> 1977 </ul> 1978 </div> 1979 </div> 1980 </div> 1981 1982 <!-- Excellence Statement --> 1983 <div class="mt-5 p-4 bg-light rounded-4 border-start border-5 border-primary"> 1984 <h4 class="fw-bold text-primary mb-3"> 1985 <i class="fa-solid fa-award me-2"></i>Committed to Excellence 1986 </h4> 1987 1988 <p class="mb-0 lh-lg"> 1989 Southern Regional High School is committed to providing challenging 1990 learning opportunities aligned with the New Jersey Student Learning 1991 Standards. Through strong community partnerships and a dedication to 1992 student achievement, we prepare young adults to become engaged citizens 1993 who make positive contributions to both their local communities and 1994 the larger global society. We strive every day to create an environment 1995 where students are encouraged to serve, challenged to grow, and empowered 1996 to succeed. 1997 </p> 1998 </div> 1999 2000 </div> 2001 </div> 2002 2003 </div> 2004</section> 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 </div> 2029</div> 2030 2031 2032 </main> 2033 </div> 2034 2035 <!-- Footer Start --> 2036 <footer class="footer-area"> 2037 <div class="main-footer"> 2038 <div class="container"> 2039 <div class="footer-content"> 2040 <div class="row"> 2041<div class="col-12"> 2042<blockquote> 2043<hr /> 2044</blockquote> 2045</div> 2046</div> 2047<div class="row"> 2048<div class="col-lg-4 col-md-6 col-sm-12 order-1 order-md-1"> 2049<div class="single-widget single-widget-right"> 2050<h3>About Us</h3> 2051<ul> 2052 <li><a href="/AboutUs/ContactInformation">Contact Information</a></li> 2053 <li><a href="/AboutUs/Directions">Directions</a></li> 2054 <li><a href="/AboutUs/CampusMap">Campus Map</a></li> 2055 <li><a href="/Board">Board of Education</a></li> 2056 <li><a href="/AboutUs/MissionStatement">Mission Statement</a></li> 2057 <li><a href="/AboutUs/BriefHistory">History</a></li> 2058</ul> 2059</div> 2060</div> 2061<div class="col-lg-4 col-md-6 col-sm-12 order-3 order-md-2"> 2062<div class="single-widget"> 2063<div class="footer-logo pb-25 text-center"> 2064<p> 2065<a href="/"><img style="max-width: 100px;height: auto;" src="/assets/images/logos/srLogo_2.png" alt="Southern Regional School District Home" /></a><br /> 2066<strong>Southern Regional School District</strong> 2067</p> 2068<p> 2069<i class="fas fa-location-dot"></i> 105 Cedar Bridge Rd.<br /> 2070Manahawkin, NJ 08050 2071</p> 2072<p><i class="fas fa-phone"></i> 1 (609) 597-9481</p> 2073<p><i class="fas fa-fax"></i> 1 (609) 756-2654</p> 2074<p> 2075<i class="fa-solid fa-globe-www"></i> www.srsd.net 2076</p> 2077<div class="footer-social"> 2078<ul> 2079 <li><a href="https://www.facebook.com/share/1BEiixaxfh/?mibextid=wwXIfr"><i class="fab fa-facebook-f"></i></a></li> 2080 <li><a href="https://www.instagram.com/ramlifesrsd/?igsh=MW80YTNkeG9nNXB3Mg%3D%3D&utm_source=qr"><i class="fab fa-instagram"></i></a></li> 2081</ul> 2082</div> 2083</div> 2084</div> 2085</div> 2086<div class="col-lg-4 col-md-6 col-sm-12 order-2 order-md-3 pt-4 pt-lg-0"> 2087<div class="single-widget"> 2088<h3>Links & Resources</h3> 2089<ul> 2090 <li><a href="/Calendars">Calendars</a></li> 2091 <li><a target="_blank" href="https://snn.srsd.net">Southern News Network</a></li> 2092 <li><a target="_blank" href="https://tickets.srsd.net/">SR Tickets</a></li> 2093 <li><a target="_blank" href="https://fan.hudl.com/usa/nj/manahawkin/organization/5205/southern-regional-high-school">Livestream</a></li> 2094 <li><a href="/Board/Employment">Employment Opportunities</a></li> 2095 <li><a href="/Board/PublicNotices">Public Notices</a></li> 2096 <li>
2096<a href="/HighSchool/Departments/Guidance/Scholarship">Scholarship Program</a></li> 2097</ul> 2098</div> 2099</div> 2100</div> 2101 2102 </div> 2103 </div> 2104 </div> 2105 <div class="footer-bottom text-center"> 2106 <div class="container"> 2107 <div class="row"> 2108 <div class="col-12 mt-3 mb-3"> 2109 <p>© 2004 - 2026 - All rights reserved. <a href="/">Southern Regional School District</a></p> 2110 </div> 2111 <div class="col-12 mb-3 cookieStyle"> 2112 2113 <a class="me-3" href="/TOS">Terms of Service</a> <a class="me-3" href="/PrivacyPolicy">Privacy Policy</a> <a href="/SiteMap">Site Map</a> 2114 2115 2116 2117 </div> 2118 2119 2120 <div class="col-12 mb-2 cookieStyle"> 2121 <a href="#" id="manageCookiePrefs" class="cookie-manage-link">Manage cookies </a> <i class="fa-solid fa-cookie-bite" style="color:#FFF"></i> 2122 </div> 2123 </div> 2124 </div> 2125 </div> 2126 </footer> 2127 <!-- Footer End --> 2128 </div> 2129 2130 <!-- Load scripts in correct order --> 2131
2131<script src="/assets/libs/jquery/dist/jquery.min.js?v=OaVG6prZf4v69dPg6PhVattBXkcOWQB62pdZ3ORyrao"></script>
2131 2132
2132<script src="/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js?v=5P1JGBOIxI7FBAvT_mb1fCnI5n_NhQKzNUuW7Hq0fMc"></script>
2132 2133
2133<script src="/assets/libs/datatables/datatables.min.js"></script>
2133 2134
2134<script src="/assets/libs/fullcalendar/index.global.min.js?v=IrvbgPSOqMnATuRffKE0D2WQbl8UVaEMJnkWdjtTqy8"></script>
2134 2135
2135<script src="/assets/libs/scrollup/jquery.scrollup.min.js?v=t2YrqZoTLq_Qt8zIw0BMiuRC2X5-a3O7PODU8RwoyYw"></script>
2135 2136
2136<script src="/assets/libs/sweetalert2/dist/sweetalert2.min.js?v=vzVoJ7an41OdWdF92fT4lj71a-wpWRa3R2h2Ssvr2aM"></script>
2136 2137 2138
2138<script src="/assets/libs/inputmask/dist/jquery.inputmask.min.js?v=5oiwHICle0yTRnZCN2ZeJtIArHp308CK7VYboY8FNe8"></script>
2138 2139
2139<script src="/assets/libs/luxon/luxon.min.js?v=Gf7owtNug1Hx_SyBFHX-wOBCo6BH4ucEyTZOD-85yNA"></script>
2139 2140
2140<script src="/assets/libs/tempus-dominus/dist/js/tempus-dominus.min.js?v=IqcDz-NpC38R9u_Ld4e0rVSyJY3O68by1jL0oUmFPXE"></script>
2140 2141 2142
2142<script src="/assets/libs/video.js/video.min.js?v=Wws3zBwoqnaS63RRtrn78tI-tu4EJc5thv9l2IWfdbc"></script>
2142 2143 2144 2145
2145<script src="/js/utilitymethods.js?v=FvuQfnjUwzDmqVoGUlL0mI6Q9cxp6bwnGPoxyUZ8gJI"></script>
2145 2146
2146<script src="/js/varsity-backdrop.js?v=zzF_B3oTNKg-kwkjLRzg5CtVpvzn5If8Y5kR_lvWeFY"></script>
2146 2147
2147<script src="/js/heroWrapperResizer.js?v=6Qz0s5FFTc8-bnxTsu48bCLWmNOWSUS0b0Y5p2H2MLI"></script>
2147 2148
2148<script src="/js/cookieprefs.js?v=_n-082nXy4A8Ip2apUlRRmBmcRn3npQ-PfpRrSviRM0"></script>
2148 2149
2149<script src="/js/translate.js?v=6Y7ohYR7yKy67Yiv3JJnzm1pUsmSFmEtNdtBXj8Quz8"></script>
2149 2150
2150<script src="/js/translate-google.js?v=8w0e4bPxnt_wNo9kQLW6F30ymms4N6_U_KQOGpC_85Q"></script>
2150 2151 2152 2153
2153<script src="/js/falinkify.js?v=9jerkC69kRS1GBjd_ej_7KudXoYbN5ITKdaw_a4CGWc"></script>
2153 2154 <!-- Load site.js BEFORE navigation.js --> 2155
2155<script src="/js/site.js?v=2va7Qk5KQmUdFBo3GKTFxq604zCIlBI6cDUfwlrt9Bk"></script>
2155 2156 2157 <!-- Load navigation.js AFTER site.js to ensure it takes precedence --> 2158
2158<script src="/js/navigation.js?v=Ri948IaMQL9fiDPFttgXTQWNHR2oDY_lVn4mX5SfF4U"></script>
2158 2159
2159<script src="/js/navigationSchools.js?v=qGyfpUCtUA2_tLHCxWXpBIBtyJJ8fGyBx4bmRDa3MMk"></script>
2159 2160 2161 2162 2163 2164
2164<script> 2165 document.addEventListener('DOMContentLoaded', function () { 2166 2167 let top10CalendarEvents = []; 2168 let announcements = []; 2169 let posts = []; 2170 let hasTriggeredFallback = false; 2171 2172 2173 // Initialize the dashboard 2174 init(); 2175 2176 async function init() { 2177 try { 2178 2179 videoControls(); 2180 //videoFallback(); 2181 2182 //await facebookInit(); 2183 await loadFrontPageInformation(); 2184 await loadTop10CalendarEvents(); 2185 attachMakePop(); 2186 2187 $('main, #main-content').faLinkify(); 2188 } catch (error) { 2189 console.error('Error initializing Page:', error); 2190 //Toast.fire({ icon: 'error', title: 'An error occurred while loading the dashboard. Please refresh and try again.' }); 2191 } 2192 } 2193 2194 2195 function videoControls(){ 2196 2197 const video = document.getElementById('heroVideo'); 2198 const playPauseBtn = document.getElementById('videoPlayPause'); 2199 const muteBtn = document.getElementById('videoMute'); 2200 2201 playPauseBtn.addEventListener('click', function () { 2202 2203 if (video.paused) { 2204 2205 video.play(); 2206 2207 this.innerHTML = 2208 '<i class="fas fa-pause" aria-hidden="true"></i><span class="visually-hidden">Pause Video</span>'; 2209 2210 this.setAttribute('aria-label', 'Pause background video'); 2211 2212 } else { 2213 2214 video.pause(); 2215 2216 this.innerHTML = 2217 '<i class="fas fa-play" aria-hidden="true"></i><span class="visually-hidden">Play Video</span>'; 2218 2219 this.setAttribute('aria-label', 'Play background video'); 2220 } 2221 }); 2222 2223 muteBtn.addEventListener('click', function () { 2224 2225 video.muted = !video.muted; 2226 2227 if (video.muted) { 2228 2229 this.innerHTML = 2230 '<i class="fas fa-volume-mute" aria-hidden="true"></i><span class="visually-hidden">Unmute Video</span>'; 2231 2232 this.setAttribute('aria-label', 'Unmute background video'); 2233 2234 } else { 2235 2236 this.innerHTML = 2237 '<i class="fas fa-volume-up" aria-hidden="true"></i><span class="visually-hidden">Mute Video</span>'; 2238 2239 this.setAttribute('aria-label', 'Mute background video'); 2240 } 2241 }); 2242 2243 2244 2245 } 2246 2247 function videoFallback() { 2248 const video = document.getElementById('heroVideo'); 2249 const videoContainer = document.getElementById('heroVideoContainer'); 2250 const carousel = document.getElementById('siteCarousel'); 2251 const heroOverlay = document.getElementById('heroOverlay'); 2252 2253 if (!video || !carousel || !videoContainer) return; 2254 2255 //heroOverlay.classList.add('d-none'); 2256 2257 //heroOverlay.classList.remove('d-none'); 2258 2259 2260 // Function to show carousel fallback with smooth transition 2261 function showCarouselFallback() { 2262 if (hasTriggeredFallback) return; 2263 hasTriggeredFallback = true; 2264 2265 // Fade out video 2266 videoContainer.style.opacity = '0'; 2267 2268 setTimeout(() => { 2269 // Hide video container 2270 videoContainer.style.display = 'none'; 2271 2272 // Show carousel with absolute positioning first 2273 carousel.style.display = 'block'; 2274 carousel.style.position = 'relative'; 2275 2276 // Trigger reflow 2277 carousel.offsetHeight; 2278 2279 // Fade in carousel 2280 setTimeout(() => { 2281 carousel.style.opacity = '1'; 2282 2283 // Initialize Bootstrap carousel 2284 if (typeof bootstrap !== 'undefined') { 2285 new bootstrap.Carousel(carousel); 2286 } 2287 }, 50); 2288 }, 300); 2289 } 2290 2291 // iOS Safari loop fix - manually restart video when it ends 2292 video.addEventListener('ended', function () { 2293 this.currentTime = 0; 2294 this.play().catch(err => { 2295 console.log('Video replay failed:', err); 2296 }); 2297 }); 2298 2299 // Additional iOS fix - ensure video plays on load 2300 video.addEventListener('loadedmetadata', function () { 2301 this.play().catch(err => {
2302 console.log('Video autoplay failed:', err); 2303 showCarouselFallback(); 2304 }); 2305 }); 2306 2307 // Check if video can play successfully 2308 video.addEventListener('canplay', function () { 2309 // Video is ready, keep it visible 2310 videoContainer.style.opacity = '1'; 2311 videoContainer.style.display = 'block'; 2312 }); 2313 2314 // Handle video errors 2315 video.addEventListener('error', function () { 2316 console.log('Video error detected'); 2317 showCarouselFallback(); 2318 }); 2319 2320 // Handle stalled/suspended video 2321 video.addEventListener('stalled', function () { 2322 console.log('Video stalled'); 2323 2324 //try to replay the video 2325 this.play().catch(err => { 2326 console.log('Video replay after stall failed:', err); 2327 showCarouselFallback(); 2328 }); 2329 2330 2331 2332 }); 2333 2334 // Fallback timeout - if video doesn't start within 2 seconds, show carousel 2335 setTimeout(function () { 2336 if (video.readyState < 2 || video.paused) { 2337 console.log('Video timeout - switching to carousel'); 2338 showCarouselFallback(); 2339 } 2340 }, 2000); 2341 2342 // Check if video source exists 2343 const sources = video.querySelectorAll('source'); 2344 let sourcesFailed = 0; 2345 2346 sources.forEach(function (source) { 2347 const testVideo = document.createElement('video'); 2348 testVideo.src = source.src; 2349 testVideo.onerror = function () { 2350 sourcesFailed++; 2351 if (sourcesFailed === sources.length) { 2352 console.log('All video sources failed'); 2353 showCarouselFallback(); 2354 } 2355 }; 2356 }); 2357 } 2358 2359 //#region Front Page Information 2360 async function loadFrontPageInformation() { 2361 try { 2362 const response = await fetch('/api/content/front-page?whichSchool=hs', { 2363 method: 'GET', 2364 headers: { 2365 'Content-Type': 'application/json', 2366 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value || '' 2367 } 2368 }); 2369 2370 const result = await response.json(); 2371 2372 2373 2374 if (result.isSuccess && result.result) { 2375 2376 // Show important information modal if requested by the server 2377 try { 2378 2379 2380 var importantInfo = []; 2381 2382 2383 if (result.result.displayImportantInformation && Array.isArray(result.result.posts) && result.result.posts.length > 0) { 2384 2385 2386 const filtered = result.result.posts.filter(item => { 2387 if (!item) return false; 2388 const cat = String(item.categoryName || '').trim(); 2389 return cat === 'High School Important Information' || cat === 'High School Security/Fire Drill'; 2390 }); 2391 2392 if (filtered.length > 0) { 2393 importantInfo = importantInfo.concat(filtered); 2394 } 2395 2396 //sort by categoryName with High School Security/Fire Drill first 2397 importantInfo.sort((a, b) => { 2398 const catA = String(a.categoryName || '').trim(); 2399 const catB = String(b.categoryName || '').trim(); 2400 2401 if (catA === 'High School Security/Fire Drill' && catB !== 'High School Security/Fire Drill') return -1; 2402 if (catA !== 'High School Security/Fire Drill' && catB === 'High School Security/Fire Drill') return 1; 2403 return 0; 2404 }); 2405 2406 2407 } 2408 2409 if (importantInfo.length > 0) { 2410 showImportantInformationModal(importantInfo); 2411 } 2412 2413 2414 2415 } catch (modalErr) { 2416 console.error('Error showing important information modal:', modalErr); 2417 } 2418 2419 2420 2421 2422 2423 const filteredAnnouncements = result.result.posts.filter(item => { 2424 if (!item) return false; 2425 const cat = String(item.categoryName || '').trim(); 2426 return cat === 'High School Announcement'; 2427 }); 2428 2429 if (filteredAnnouncements.length > 0) { 2430 announcements = announcements.concat(filteredAnnouncements); 2431 } 2432 2433 2434 if (result.isSuccess && result.result.posts && announcements && announcements.length > 0) { 2435 2436 renderAnnouncements(); 2437 } else { 2438 renderNoAnnouncements(); 2439 } 2440 2441 2442 2443 if (result.isSuccess && result.result && result.result.posts) { 2444 posts = result.result.posts.filter(item => { 2445 if (!item) return false; 2446 const cat = String(item.categoryName || '').trim(); 2447 return cat !== 'High School Important Information' && cat !== 'High School Security/Fire Drill' && cat !== 'High School Announcement'; 2448 }); 2449 } 2450 2451 if (result.isSuccess && result.result.posts && posts && posts.length > 0) { 2452 2453 renderPosts();
2454 } else { 2455 renderNoPosts(); 2456 } 2457 2458 2459 } 2460 2461 } catch (error) { 2462 //console.error('Error loading Front Page Information:', error); 2463 2464 //renderAnnouncementsError(); 2465 } 2466 } 2467 2468 //#endregion 2469 2470 //#region Posts 2471 2472 function renderPosts() { 2473 const container = document.getElementById('classInformationContainer'); 2474 container.innerHTML = ''; // Clear existing content 2475 2476 if (!posts || posts.length === 0) { 2477 renderNoPosts(); 2478 return; 2479 } 2480 2481 // Group posts by categoryName (fallback to category or 'Uncategorized') 2482 const groups = {}; 2483 posts.forEach(item => { 2484 if (!item) return; 2485 const cat = String(item.categoryName || 'Uncategorized').trim(); 2486 if (!groups[cat]) groups[cat] = []; 2487 groups[cat].push(item); 2488 }); 2489 2490 const allowedCategories = Object.keys(groups); 2491 if (allowedCategories.length === 0) { 2492 renderNoPosts(); 2493 return; 2494 } 2495 2496 // Helper to create safe slug for ids 2497 const slug = s => String(s).replace(/[^\w-]/g, ''); 2498 2499 // Sort categories alphabetically (adjust locale/options as needed) 2500 allowedCategories.sort((a, b) => a.localeCompare(b, 'en', { numeric: true })); 2501 2502 // Helper to render a single item card (keeps same look as other cards) 2503 function renderItemCard(item) { 2504 const title = escapeHtml(item.title || ''); 2505 const infoHtml = item.information || ''; 2506 const targetAttr = item.target ? `target="${escapeHtml(item.target)}"` : ''; 2507 const urlHtml = item.url ? `<a ${targetAttr} href="${escapeHtml(item.url)}">${escapeHtml(item.linkTitle || item.url)}</a>` : ''; 2508 return ` 2509 <div class="card mb-3" style="border: none; border-left: 4px solid #000; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: transform 0.2s, box-shadow 0.2s;"> 2510 <div class="card-body" style="padding: 1.5rem; background: #fff;"> 2511 <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 10px;"> 2512 <div style="flex-shrink: 0; width: 32px; height: 32px; background: linear-gradient(135deg, #BBA687 0%, #897962 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; font-weight: 700; font-size: 0.875rem;"> 2513 <i class="fa-duotone fa-solid fa-circle-info fa-2x" style="--fa-secondary-color: #BBA687;"></i> 2514 </div> 2515 <h6 class="card-title mb-0" style="text-align:left; font-weight: 700; font-size: 1.125rem; color: #303030; flex: 1; line-height: 1.4;"> 2516 ${urlHtml ? `<a ${targetAttr} href="${escapeHtml(item.url)}">${title}</a>` : title} 2517 </h6> 2518 </div> 2519 <div class="card-text" style="text-align:justify; color: #606060; line-height: 1.6; font-size: 0.9375rem; margin-top: 12px;">${infoHtml}</div> 2520 </div> 2521 </div> 2522 `; 2523 } 2524 2525 const accId = `postsAccordion`; 2526 let html = `<div class="accordion" id="${accId}">`; 2527 2528 allowedCategories.forEach((cat, catIndex) => { 2529 const items = (groups[cat] || []).slice().sort((x, y) => {
2530 const ox = Number.isFinite(Number(x.orderID)) ? Number(x.orderID) : Number.MAX_SAFE_INTEGER; 2531 const oy = Number.isFinite(Number(y.orderID)) ? Number(y.orderID) : Number.MAX_SAFE_INTEGER; 2532 return ox - oy || String(x.title || '').localeCompare(String(y.title || ''), 'en', { numeric: true }); 2533 }); 2534 2535 const collapseId = `collapse-${slug(cat)}-${catIndex}`; 2536 const headerId = `heading-${slug(cat)}-${catIndex}`; 2537 const displayName = escapeHtml(cat); 2538 2539 // Split items into two columns 2540 const midPoint = Math.ceil(items.length / 2); 2541 const leftColumn = items.slice(0, midPoint); 2542 const rightColumn = items.slice(midPoint); 2543 2544 html += ` 2545 <div class="accordion-item"> 2546 <h2 class="accordion-header" id="${headerId}"> 2547 <button class="accordion-button collapsed" type="button" 2548 data-bs-toggle="collapse" 2549 data-bs-target="#${collapseId}" 2550 aria-expanded="false" 2551 aria-controls="${collapseId}"> 2552 ${displayName} 2553 </button> 2554 </h2> 2555 <div id="${collapseId}" class="accordion-collapse collapse" aria-labelledby="${headerId}" data-bs-parent="#${accId}"> 2556 <div class="accordion-body"> 2557 ${items.length === 0 ? `<p class="text-muted mb-0">No items in this category.</p>` : (items.length === 1 ? ` 2558 <div class="row"> 2559 <div class="col-12"> 2560 ${renderItemCard(items[0])} 2561 </div> 2562 </div> 2563 ` : ` 2564 <div class="row"> 2565 <div class="col-lg-6"> 2566 ${leftColumn.map(item => renderItemCard(item)).join('')} 2567 </div> 2568 <div class="col-lg-6"> 2569 ${rightColumn.map(item => renderItemCard(item)).join('')} 2570 </div> 2571 </div> 2572 `)} 2573 </div> 2574 </div> 2575 </div> 2576 `; 2577 }); 2578 2579 html += `</div>`; // close accordion 2580 container.innerHTML = html; 2581} 2582 2583 function renderPosts_old() { 2584 const container = document.getElementById('classInformationContainer'); 2585 container.innerHTML = ''; // Clear existing content 2586 2587 if (!posts || Object.keys(posts).length === 0) { 2588 renderNoPosts(); 2589 return; 2590 } 2591 2592 // Keep only categories we care about 2593 //|| k === 'msnews' 2594 let allowedCategories = Object.keys(posts).filter(k => 2595 k.startsWith('classof') || k === 'vocationalSchool' 2596 ); 2597 2598 if (allowedCategories.length === 0) { 2599 renderNoPosts(); 2600 return; 2601 } 2602 2603 const slug = s => String(s).replace(/[^\w-]/g, ''); 2604 2605 const formatCategory = (cat) => { 2606 if (cat.startsWith('classof')) return cat.replace(/classof/i, 'Class of '); 2607 if (cat === 'msnews') return 'Middle School News'; 2608 if (cat === 'vocationalSchool') return 'Vocational School'; 2609 return cat; 2610 }; 2611 2612 // Sort categories ascending by their display name 2613 allowedCategories.sort((a, b) => formatCategory(a).localeCompare(formatCategory(b), 'en', { numeric: true })); 2614 2615 const accId = `postsAccordion`; 2616 let html = `<div class="accordion" id="${accId}">`; 2617 2618 allowedCategories.forEach((cat, catIndex) => { 2619 // Sort items by orderID ascending (coerce to number; missing -> large) 2620 const items = (posts[cat] || []).slice().sort((x, y) => {
2621 const ox = Number.isFinite(Number(x.orderID)) ? Number(x.orderID) : Number.MAX_SAFE_INTEGER; 2622 const oy = Number.isFinite(Number(y.orderID)) ? Number(y.orderID) : Number.MAX_SAFE_INTEGER; 2623 return ox - oy || String(x.title || '').localeCompare(String(y.title || ''), 'en', { numeric: true }); 2624 }); 2625 2626 const collapseId = `collapse-${slug(cat)}-${catIndex}`; 2627 const headerId = `heading-${slug(cat)}-${catIndex}`; 2628 const displayName = escapeHtml(formatCategory(cat)); 2629 2630 // Split items into two columns 2631 const midPoint = Math.ceil(items.length / 2); 2632 const leftColumn = items.slice(0, midPoint); 2633 const rightColumn = items.slice(midPoint); 2634 2635 // Helper function to render a single item card 2636 function renderItemCard(item) { 2637 const title = escapeHtml(item.title || ''); 2638 const infoHtml = item.information || ''; 2639 const targetAttr = item.target ? `target="${item.target}"` : ''; 2640 const urlHtml = item.url ? `<a ${targetAttr} href="${item.url}">${escapeHtml(item.linkTitle || item.url)}</a>` : ''; 2641 2642 return ` 2643 <div class="card mb-3" style="border: none; border-left: 4px solid #000; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: transform 0.2s, box-shadow 0.2s;"> 2644 <div class="card-body" style="padding: 1.5rem; background: #fff;"> 2645 <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 10px;"> 2646 <div style="flex-shrink: 0; width: 32px; height: 32px; background: linear-gradient(135deg, #BBA687 0%, #897962 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; font-weight: 700; font-size: 0.875rem;"> 2647 <i class="fa-duotone fa-solid fa-circle-info fa-2x" style="--fa-secondary-color: #BBA687;"></i> 2648 </div> 2649 <h6 class="card-title mb-0" style="text-align:left; font-weight: 700; font-size: 1.125rem; color: #303030; flex: 1; line-height: 1.4;"> 2650 ${urlHtml ? `<a ${targetAttr} href="${item.url}">${title}</a>` : title} 2651 </h6> 2652 </div> 2653 <div class="card-text" style="text-align:justify; color: #606060; line-height: 1.6; font-size: 0.9375rem; margin-top: 12px;">${infoHtml}</div> 2654 </div> 2655 </div> 2656 `; 2657 } 2658 2659 html += ` 2660 <div class="accordion-item"> 2661 <h2 class="accordion-header" id="${headerId}"> 2662 <button class="accordion-button collapsed" type="button" 2663 data-bs-toggle="collapse" 2664 data-bs-target="#${collapseId}" 2665 aria-expanded="false" 2666 aria-controls="${collapseId}"> 2667 ${displayName} 2668 </button> 2669 </h2> 2670 <div id="${collapseId}" class="accordion-collapse collapse" aria-labelledby="${headerId}" data-bs-parent="#${accId}"> 2671 <div class="accordion-body"> 2672 ${items.length === 0 ? `<p class="text-muted mb-0">No items in this category.</p>` : (items.length === 1 ? ` 2673 <div class="row"> 2674 <div class="col-12"> 2675 ${renderItemCard(items[0])} 2676 </div> 2677 </div> 2678 ` : ` 2679 <div class="row"> 2680 <div class="col-lg-6"> 2681 ${leftColumn.map(item => renderItemCard(item)).join('')} 2682 </div> 2683 <div class="col-lg-6"> 2684 ${rightColumn.map(item => renderItemCard(item)).join('')} 2685 </div> 2686 </div> 2687 `)} 2688 </div> 2689 </div> 2690 </div> 2691 `; 2692 }); 2693 2694 html += `</div>`; // close accordion 2695 container.innerHTML = html; 2696 } 2697 2698 //function renderPosts() { 2699 // const container = document.getElementById('classInformationContainer'); 2700 // container.innerHTML = ''; // Clear existing content 2701 2702 // if (!posts || Object.keys(posts).length === 0) { 2703 // renderNoPosts();
2704 // return; 2705 // } 2706 2707 // // Keep only categories we care about 2708 // let allowedCategories = Object.keys(posts).filter(k => 2709 // k.startsWith('classof') || k === 'msnews' || k === 'vocationalSchool' 2710 // ); 2711 2712 // if (allowedCategories.length === 0) { 2713 // renderNoPosts(); 2714 // return; 2715 // } 2716 2717 // const slug = s => String(s).replace(/[^\w-]/g, ''); 2718 2719 // const formatCategory = (cat) => { 2720 // if (cat.startsWith('classof')) return cat.replace(/classof/i, 'Class of '); 2721 // if (cat === 'msnews') return 'Middle School News'; 2722 // if (cat === 'vocationalSchool') return 'Vocational School'; 2723 // return cat; 2724 // }; 2725 2726 // // Sort categories ascending by their display name 2727 // allowedCategories.sort((a, b) => formatCategory(a).localeCompare(formatCategory(b), 'en', { numeric: true })); 2728 2729 // const accId = `postsAccordion`; 2730 // let html = `<div class="accordion" id="${accId}">`; 2731 2732 // allowedCategories.forEach((cat, catIndex) => { 2733 // // Sort items by orderID ascending (coerce to number; missing -> large) 2734 // const items = (posts[cat] || []).slice().sort((x, y) => {
2735 // const ox = Number.isFinite(Number(x.orderID)) ? Number(x.orderID) : Number.MAX_SAFE_INTEGER; 2736 // const oy = Number.isFinite(Number(y.orderID)) ? Number(y.orderID) : Number.MAX_SAFE_INTEGER; 2737 // return ox - oy || String(x.title || '').localeCompare(String(y.title || ''), 'en', { numeric: true }); 2738 // }); 2739 2740 // const collapseId = `collapse-${slug(cat)}-${catIndex}`; 2741 // const headerId = `heading-${slug(cat)}-${catIndex}`; 2742 // const displayName = escapeHtml(formatCategory(cat)); 2743 2744 // html += ` 2745 // <div class="accordion-item"> 2746 // <h2 class="accordion-header" id="${headerId}"> 2747 // <button class="accordion-button collapsed" type="button" 2748 // data-bs-toggle="collapse" 2749 // data-bs-target="#${collapseId}" 2750 // aria-expanded="false" 2751 // aria-controls="${collapseId}"> 2752 // ${displayName} 2753 // </button> 2754 // </h2> 2755 // <div id="${collapseId}" class="accordion-collapse collapse" aria-labelledby="${headerId}" data-bs-parent="#${accId}"> 2756 // <div class="accordion-body"> 2757 // ${items.length === 0 ? `<p class="text-muted mb-0">No items in this category.</p>` : ` 2758 // <div class="row"> 2759 // ${items.map(item => { 2760 // const title = escapeHtml(item.title || ''); 2761 // const infoHtml = item.information || ''; 2762 // const targetAttr = item.target ? `target="${item.target}"` : ''; 2763 // const urlHtml = item.url ? `<a ${targetAttr} href="${item.url}">${escapeHtml(item.linkTitle || item.url)}</a>` : ''; 2764 2765 2766 // return ` 2767 // <div class="col-lg-6 mb-3"> 2768 // <div class="card mb-3" style="border: none; border-left: 4px solid #000; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: transform 0.2s, box-shadow 0.2s;" onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 4px 12px rgba(0,0,0,0.12)';" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 8px rgba(0,0,0,0.08)';"> 2769 // <div class="card-body" style="padding: 1.5rem; background: #fff;"> 2770 // <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 10px;"> 2771 // <div style="flex-shrink: 0; width: 32px; height: 32px; background: linear-gradient(135deg, #BBA687 0%, #897962 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; font-weight: 700; font-size: 0.875rem;"><i class="fa-duotone fa-solid fa-circle-info fa-2x" style="--fa-secondary-color: #BBA687;"></i></div> 2772 // <h6 class="card-title mb-0" style="text-align:left; font-weight: 700; font-size: 1.125rem; color: #303030; flex: 1; line-height: 1.4;">${urlHtml ? `<a ${targetAttr} href="${item.url}">${title}</a>` : title}</h6> 2773 // </div> 2774 // <div class="card-text" style="text-align:justify;color: #606060; line-height: 1.6; font-size: 0.9375rem; margin-top: 12px;">${infoHtml}</div> 2775 // </div> 2776 // </div> 2777 // </div> 2778 // `; 2779 2780 // //return ` 2781 // // <div class="col-lg-6 mb-3"> 2782 // // <div class="card shadow-sm h-100"> 2783 // // <div class="card-body"> 2784 // // <div class="event-date"> 2785 // // <div class="header"><i class="fa-duotone fa-solid fa-circle-info fa-1x" style="--fa-primary-color: #BBA687;"></i></div> 2786 // // </div> 2787 // // <div class="event-content text-start"> 2788 // // <div class="event-content-left"> 2789 // // <div class="header">${urlHtml ? `<a ${targetAttr} href="${item.url}">${title}</a>` : title}</div> 2790 // // ${infoHtml} 2791 // // </div> 2792 // // </div> 2793 // // </div> 2794 // // </div> 2795 // // </div> 2796 // // `; 2797 // }).join('')} 2798 // </div> 2799 // `} 2800 // </div> 2801 // </div> 2802 // </div> 2803 // `; 2804 // });
2805 2806 // html += `</div>`; // close accordion 2807 // container.innerHTML = html; 2808 //} 2809 2810 2811 function renderNoPosts() { 2812 const container = document.getElementById('classInformationContainer'); 2813 container.innerHTML = ''; // Clear existing content 2814 container.innerHTML = ` 2815 <div class="text-center py-4"> 2816 <i class="fa-duotone fa-solid fa-circle-info" style="font-size: 2rem; color: #ccc;"></i> 2817 <p class="text-muted mt-2 mb-3">There are currently no Posts posted.</p> 2818 </div> 2819`; 2820 } 2821 2822 function renderPostsError() { 2823 const container = document.getElementById('classInformationContainer'); 2824 container.innerHTML = ''; // Clear existing content 2825 container.innerHTML = ` 2826 <div class="text-center py-4"> 2827 <i class="fa-duotone fa-solid fa-circle-xmark text-danger" style="font-size: 2rem;"></i> 2828 <p class="text-muted mt-2 mb-3">Error loading Posts</p> 2829 <button class="btn btn-sm btn-outline-primary" onclick="loadFrontPageInformation()"> 2830 <i class="fa-duotone fa-solid fa-arrows-rotate me-1"></i>Retry 2831 </button> 2832 </div> 2833`; 2834 } 2835 2836 2837 //#endregion 2838 2839 2840 //#region Announcements 2841 2842 function renderAnnouncements() { 2843 const container = document.getElementById('announcementsContainer'); 2844 container.innerHTML = ''; // Clear existing content 2845 if (announcements.length === 0) { 2846 renderNoAnnouncements(); 2847 return; 2848 } 2849 2850 const html = ` 2851 <div class="row"> 2852 ${announcements.map(announcement => { 2853 return ` 2854 <div class="col-lg-6 mb-3"> 2855 <div class="card shadow-sm h-100"> 2856 <div class="card-body"> 2857 <div class="event-date"> 2858 <div class="header"></div> 2859 </div> 2860 <div class="event-content text-start"> 2861 <div class="event-content-left"> 2862 <div class="header"><a target="${announcement.target}" href="${announcement.url}">${announcement.title}</a></div> 2863 ${announcement.information} 2864 </div> 2865 </div> 2866 </div> 2867 </div> 2868 </div> 2869 `; 2870 }).join('')} 2871 </div> 2872 2873 <div class="row mt-3"> 2874 <div class="col align-self-center"> 2875 <a class="default-btn" href="/HighSchool/Announcements">View More Announcements</a> 2876 </div> 2877 </div> 2878 `; 2879 2880 container.innerHTML = html; 2881 } 2882 2883 2884 function renderNoAnnouncements() { 2885 const container = document.getElementById('announcementsContainer'); 2886 container.innerHTML = ''; // Clear existing content 2887 container.innerHTML = ` 2888 <div class="text-center py-4"> 2889 <i class="fa-duotone fa-solid fa-trumpet" style="font-size: 2rem; color: #ccc;"></i> 2890 <p class="text-muted mt-2 mb-3">There are currently no Announcements posted.</p> 2891 </div> 2892 `; 2893 } 2894 2895 function renderAnnouncementsError() { 2896 const container = document.getElementById('announcementsContainer'); 2897 container.innerHTML = ''; // Clear existing content 2898 container.innerHTML = ` 2899 <div class="text-center py-4"> 2900 <i class="fa-duotone fa-solid fa-circle-xmark text-danger" style="font-size: 2rem;"></i> 2901 <p class="text-muted mt-2 mb-3">Error loading Announcements</p> 2902 <button class="btn btn-sm btn-outline-primary" onclick="loadFrontPageInformation()"> 2903 <i class="fa-duotone fa-solid fa-arrows-rotate me-1"></i>Retry 2904 </button> 2905 </div> 2906 `; 2907 } 2908 2909 2910 //#endregion 2911 2912 2913 2914 2915 2916 //#region Calendar Events 2917 2918 async function loadTop10CalendarEvents() { 2919 2920 const container = document.getElementById('topTenCalendarEventsContainer'); 2921 container.innerHTML = ''; // Clear existing content 2922 2923 container.innerHTML = ` 2924 <div class="text-center py-4"> 2925 <i class="fa fa-spinner fa-spin fa-2x" aria-hidden="true"></i>
2926 <span class="ms-2">Loading events...</span> 2927 </div>`; 2928 2929if (window.location.hostname.endsWith('webappsv3.srsd.net')) { 2930 2931 return; // Exits execution 2932 } 2933 2934 const today = new Date(); 2935 //const startDate = new Date(today.getFullYear(), today.getMonth(), 1); 2936 const startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()); 2937 const endDate = new Date(startDate); 2938 endDate.setMonth(endDate.getMonth() + 1); 2939 2940 2941 //Y050QzErSFEyZnc90 2942 try { 2943 const response = await fetch(`/api/Calendar/events/top10?calendarIDs=NHFvWDJCTXE3Y3M90&start=${startDate.toISOString().split('T')[0]}&end=${endDate.toISOString().split('T')[0]}`, { 2944 method: 'GET', 2945 headers: { 2946 'Content-Type': 'application/json', 2947 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value || '' 2948 } 2949 }); 2950 2951 const result = await response.json(); 2952 2953 if (result.isSuccess && result.result && result.result.events && result.result.events.length > 0) { 2954 top10CalendarEvents = result.result.events; 2955 renderTop10CalendarEvents(); 2956 } else { 2957 renderNoTop10CalendarEvents(); 2958 } 2959 } catch (error) { 2960 console.error('Error loading calendar events:', error); 2961 renderTop10CalendarEventsError(); 2962 } 2963 } 2964 2965 function renderTop10CalendarEvents() { 2966 const container = document.getElementById('topTenCalendarEventsContainer'); 2967 container.innerHTML = ''; // Clear existing content 2968 2969 if (top10CalendarEvents.length === 0) { 2970 renderNoTop10CalendarEvents(); 2971 return; 2972 } 2973 2974 const html = ` 2975 <div class="row"> 2976 ${top10CalendarEvents.map(event => { 2977 const startDate = new Date(event.start); 2978 const day = startDate.getDate();
2979 const month = startDate.toLocaleString('en-US', { month: 'short' }); 2980 2981 // Format time range 2982 let timeDisplay = ''; 2983 if (event.allDay) { 2984 timeDisplay = 'All Day Event'; 2985 } else { 2986 const startTime = startDate.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2987 const endDate = new Date(event.end); 2988 const endTime = endDate.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }); 2989 // Compare just the date parts to determine if the end date differs from the start date 2990 const isSameDay = startDate.getFullYear() === endDate.getFullYear() 2991 && startDate.getMonth() === endDate.getMonth() 2992 && startDate.getDate() === endDate.getDate(); 2993 2994 if (!isSameDay) { 2995 const endDay = endDate.getDate(); 2996 const endMonth = endDate.toLocaleString('en-US', { month: 'short' }); 2997 // Append the end date when it falls on a different day 2998 timeDisplay = `${startTime} - ${endTime} (${endMonth} ${endDay})`; 2999 } else { 3000 timeDisplay = `${startTime} - ${endTime}`; 3001 } 3002 } 3003 3004 return ` 3005 <div class="col-lg-6 mb-3"> 3006 <div class="card shadow-sm h-100"> 3007 <div class="card-body"> 3008 <div class="event-date"> 3009 <h3> 3010 ${day} <span>${month}</span> 3011 </h3> 3012 </div> 3013 <div class="event-content text-start"> 3014 <div class="event-content-left"> 3015 <h4>${event.title}</h4> 3016 <ul> 3017 <li><i class="fa fa-clock"></i>${timeDisplay}</li> 3018 ${event.description ? `<li><i class="fa fa-map-marker"></i>${event.description}</li>` : ''} 3019 </ul> 3020 </div> 3021 </div> 3022 </div> 3023 </div> 3024 </div> 3025 `; 3026 }).join('')} 3027 </div> 3028 <div class="row mt-3"> 3029 <div class="col align-self-center"> 3030 <a class="default-btn" href="/HighSchool/Calendar">View More Events</a> 3031 </div> 3032 </div> 3033 `; 3034 3035 container.innerHTML = html; 3036 } 3037 3038 function renderNoTop10CalendarEvents() { 3039 const container = document.getElementById('topTenCalendarEventsContainer'); 3040 container.innerHTML = ''; // Clear existing content 3041 3042 container.innerHTML = ` 3043 <div class="text-center py-4"> 3044 <i class="fa-duotone fa-solid fa-calendar" style="font-size: 2rem; color: #ccc;"></i> 3045 <p class="text-muted mt-2 mb-3">There are currently no Events posted.</p> 3046 </div> 3047 `; 3048 } 3049 3050 function renderTop10CalendarEventsError() { 3051 const container = document.getElementById('topTenCalendarEventsContainer'); 3052 container.innerHTML = ''; // Clear existing content 3053 3054 container.innerHTML = ` 3055 <div class="text-center py-4"> 3056 <i class="fa-duotone fa-solid fa-circle-xmark text-danger" style="font-size: 2rem;"></i> 3057 <p class="text-muted mt-2 mb-3">Error loading Calendar Events</p> 3058 <button class="btn btn-sm btn-outline-primary" onclick="loadTop10CalendarEvents()"> 3059 <i class="fa-duotone fa-solid fa-arrows-rotate me-1"></i>Retry 3060 </button> 3061 </div> 3062 `; 3063 } 3064 3065 //#endregion 3066 3067 function escapeHtml(text) { 3068 const map = { 3069 '&': '&', 3070 '<': '<', 3071 '>': '>', 3072 '"': '"', 3073 "'": ''' 3074 }; 3075 return text.replace(/[&<>"']/g, m => map[m]); 3076 } 3077 3078 3079 function showImportantInformationModal(items) { 3080 if (!items || !items.length) return; 3081 3082 // Ensure previous modal removed 3083 const existing = document.getElementById('importantInfoModal'); 3084 if (existing) existing.remove(); 3085 3086 // Build modal HTML with professional styling 3087 const modalHtml = ` 3088 <div class="modal fade" id="importantInfoModal" tabindex="-1" aria-labelledby="importantInfoModalLabel" aria-hidden="true"> 3089 <div class="modal-dialog modal-lg modal-dialog-centered modal
3089-dialog-scrollable"> 3090 <div class="modal-content" style="border: none; border-radius: 15px; overflow: hidden; box-shadow: 0 10px 40px rgba(0,0,0,0.2);"> 3091 <div class="modal-header" style="background: linear-gradient(135deg, #BBA687 0%, #897962 100%); color: #000; border: none; padding: 1.5rem 2rem; position: relative;"> 3092 <div style="display: flex; align-items: center; gap: 12px; width: 100%;"> 3093 <i class="fa-duotone fa-solid fa-circle-exclamation fa-2x" style="--fa-primary-color: #000; --fa-secondary-color: #fff; --fa-secondary-opacity: 0.7;"></i> 3094 <h1 class="modal-title" id="importantInfoModalLabel" style="font-weight: 700; font-size: 1.5rem; margin: 0; flex: 1;">Important Information</h1> 3095 </div> 3096 <button type="button" class="btn-close btn-close-dark" data-bs-dismiss="modal" aria-label="Close" style="filter: brightness(0); opacity: 0.8;"></button> 3097 </div> 3098 <div class="modal-body" style="padding: 2rem; background: #f8f9fa;"> 3099 ${items.map((item, index) => { 3100 const title = escapeHtml(item.title || 'Important Information'); 3101 const infoHtml = item.information || ''; 3102 const link = item.url ? `<p class="mt-3 mb-1"><a href="${escapeHtml(item.url)}" target="${escapeHtml(item.target || '_self')}" class="btn btn-sm btn-outline-primary" style="border-color: #BBA687; color: #BBA687; font-weight: 600; padding: 0.375rem 1rem; transition: all 0.3s;" onmouseover="this.style.backgroundColor='#BBA687'; this.style.color='#000';" onmouseout="this.style.backgroundColor='transparent'; this.style.color='#BBA687';"><i class="fa-solid fa-arrow-up-right-from-square me-1"></i>${escapeHtml(item.linkTitle || 'Learn More')}</a></p>` : ''; 3103 //const dates = (item.startDate || item.endDate || item.eventDate) ? `<p class="text-muted small mb-2" style="font-size: 0.85rem; display: flex; align-items: center; gap: 6px;"><i class="fa-regular fa-calendar" style="color: #BBA687;"></i>${escapeHtml(item.startDate || item.eventDate || '')}${item.endDate ? ' â ' + escapeHtml(item.endDate) : ''}</p>` : ''; 3104 const dates = (item.startDate || item.endDate || item.eventDate) ? `<p class="text-muted small mb-2" style="font-size: 0.85rem; display: flex; align-items: center; gap: 6px;"><i class="fa-regular fa-calendar" style="color: #BBA687;"></i>${escapeHtml(item.startDate || item.eventDate || '')}</p>` : ''; 3105 3106 return ` 3107 <div class="card mb-3" style="border: none; border-left: 4px solid #BBA687; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: transform 0.2s, box-shadow 0.2s;" onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 4px 12px rgba(0,0,0,0.12)';" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 8px rgba(0,0,0,0.08)';"> 3108 <div class="card-body" style="padding: 1.5rem; background: #fff;"> 3109 <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 10px;"> 3110 <div style="flex-shrink: 0; width: 32px; height: 32px; background: linear-gradient(135deg, #BBA687 0%, #897962 100%); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #000; font-weight: 700; font-size: 0.875rem;">${index + 1}</div> 3111 <h2 class="card-title mb-0" style="font-weight: 700; font-size: 1.125rem; color: #303030; flex: 1; line-height: 1.4;">${title}</h2> 3112 </div> 3113 ${dates} 3114 <div class="card-text" style="color: #606060; line-height: 1.6; font-size: 0.9375rem; margin-top: 12px;">${infoHtml}</div> 3115 ${link} 3116 </div> 3117 </div> 3118 `; 3119 }).join('')} 3120 </div> 3121 <div class="modal-footer" style="border: none; background: #fff; padding: 1.25rem 2rem; box-shadow: 0 -2px 10px rgba(0,0,0,0.05);"> 3122 <button type="button" class="btn" data-bs-dismiss="modal" style="background: #000; color: #fff; border: none; padding: 0.625rem 2rem; font-weight: 600; border-radius: 6px; transition: all 0.3s; box-shadow: 0 2px 8px rgba(0,0,0,0.15);" onmouseover="this.style.background='#BBA687'; this.style.color='#000';" onmouseout="this.style.background='#000'; this.style.color='#fff';"> 3123 <i class="fa-solid fa-check me-2"></i>Got It 3124 </button> 3125 </div> 3126 </div> 3127 </div> 3128 </div> 3129 `; 3130 3131 document.body.insertAdjacentHTML('beforeend', modalHtml); 3132 3133 // Show Bootstrap modal with fade-in animation 3134 if (typeof bootstrap !== 'undefined') { 3135 const modalEl = document.getElementById('importantInfoModal'); 3136 const modal = new bootstrap.Modal(modalEl, { 3137 backdrop: 'static', 3138 keyboard: true 3139 }); 3140 3141 // Add custom backdrop styling 3142 modalEl.addEventListener('shown.bs.modal', function () { 3143 const backdrop = document.querySelector('.modal-backdrop'); 3144 if (backdrop) { 3145 backdrop.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; 3146 } 3147 }); 3148 3149 // Clean up on hide 3150 modalEl.addEventListener('hidden.bs.modal', function () { 3151 modalEl.remove(); 3152 }); 3153 3154 modal.show(); 3155 } 3156 } 3157 3158 3159 function attachMakePop() { 3160 const onEnter = (ev) => { 3161 const el = ev.currentTarget; 3162 if (!el) return; 3163 el.style.transform = 'translateY(-2px)'; 3164 el.style.boxShadow = '0 4px 12px rgba(0,0,0,0.12)'; 3165 }; 3166 const onLeave = (ev) => { 3167 const el = ev.currentTarget; 3168 if (!el) return; 3169 el.style.transform = 'translateY(0)'; 3170 el.style.boxShadow = '0 2px 8px rgba(0,0,0,0.08)'; 3171 }; 3172 3173 document.querySelectorAll('.makePop').forEach(el => { 3174 // Prevent double-binding 3175 if (el._makePopInit) return; 3176 el._makePopInit = true; 3177 3178 // Use pointer events where available for better touch handling 3179 el.addEventListener('pointerenter', onEnter); 3180 el.addEventListener('pointerleave', onLeave); 3181 3182 // Fallback for older browsers 3183 el.addEventListener('mouseenter', onEnter); 3184 el.addEventListener('mouseleave', onLeave); 3185
3186 // Support touch (touchstart/touchend) to give feedback on mobile 3187 el.addEventListener('touchstart', onEnter, { passive: true }); 3188 el.addEventListener('touchend', onLeave, { passive: true }); 3189 }); 3190 } 3191 3192 window.loadTop10CalendarEvents = loadTop10CalendarEvents; 3193 window.loadFrontPageInformation = loadFrontPageInformation; 3194 3195 async function facebookInit() { 3196 3197 const gridContainer = document.getElementById('facebookGridContainer'); // create this div in your page 3198 let carouselController = null; // holds controller returned by initMobileCarousel 3199 3200 // We'll find all loader nodes (supporting both id and optional class) 3201 function findLoaders() { 3202 const nodes = []; 3203 const byId = document.getElementById('facebookLoader'); 3204 if (byId) nodes.push(byId); 3205 document.querySelectorAll('.facebook-loader').forEach(n => nodes.push(n)); 3206 return nodes; 3207 } 3208 3209 function hideAllLoaders() { 3210 const nodes = findLoaders(); 3211 nodes.forEach(loader => { 3212 try { 3213 loader.style.display = 'none'; 3214 loader.setAttribute('aria-hidden', 'true'); 3215 loader.classList && loader.classList.add('d-none'); 3216 } catch (e) { 3217 // ignore 3218 } 3219 }); 3220 } 3221 3222 function showError(msg) { 3223 hideAllLoaders(); 3224 if (gridContainer) { 3225 gridContainer.innerHTML = `<div class="text-center text-muted py-4">${msg}</div>`; 3226 gridContainer.style.display = 'block'; 3227 } else { 3228 console.warn('[FB] showError: no grid container to show message', msg); 3229 } 3230 } 3231 3232 // Basic HTML-escape to avoid XSS (server should also sanitize) 3233 function escapeHtml(s) { 3234 if (!s) return ''; 3235 return String(s).replace(/[&<>"']/g, function (m) { 3236 return ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[m]; 3237 }); 3238 } 3239 3240 // Minimal linkify (convert URLs to anchors) 3241 function sanitizeAndLinkify(text) { 3242 const esc = escapeHtml(text).replace(/\n/g, '<br/>'); 3243 return esc.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" target="_blank" rel="noopener">$1</a>'); 3244 } 3245 3246 function buildCardHtml(p) { 3247 const message = p.message ? sanitizeAndLinkify(p.message) : ''; 3248 const image = p.fullPicture ? `<div class="facebook-card-media"><img src="${escapeHtml(p.fullPicture)}" alt="" /></div>` : ''; 3249 const date = p.createdTime ? `<time datetime="${escapeHtml(p.createdTime)}">${new Date(p.createdTime).toLocaleDateString()}</time>` : ''; 3250 const permalink = p.permalinkUrl ? `<a class="btn btn-sm btn-outline-primary ms-2" href="${escapeHtml(p.permalinkUrl)}" target="_blank" rel="noopener">View on Facebook</a>` : ''; 3251 return ` 3252<article class="facebook-card"> 3253 ${image} 3254 <div class="facebook-card-body"> 3255 <p class="facebook-card-text">${message}</p> 3256 <div class="facebook-card-meta">${date}${permalink}</div> 3257 </div> 3258</article> 3259`; 3260 } 3261 3262 // initMobileCarousel now returns a controller object so the outer scope can update sizes without re-rendering. 3263 function initMobileCarousel(wrapperEl) { 3264 const wrapper = typeof wrapperEl === 'string' ? gridContainer.querySelector(wrapperEl) : wrapperEl; 3265 if (!wrapper) return null; 3266 const track = wrapper.querySelector('.facebook-carousel-track'); 3267 if (!track) return null; 3268 const slides = Array.from(track.children); 3269 if (!slides.length) return null; 3270 3271 let index = 0; 3272 let isPointerActive = false; 3273 let startX = 0; 3274 let deltaX = 0; 3275 let startOffset = 0; 3276 let rafId = null; 3277 3278 function setSlideWidths() { 3279 const w = Math.max(0, wrapper.clientWidth);
3280 slides.forEach(s => { 3281 s.style.minWidth = w + 'px'; 3282 s.style.maxWidth = w + 'px'; 3283 s.style.boxSizing = 'border-box'; 3284 }); 3285 } 3286 3287 function updateTrackHeight() { 3288 const current = slides[index]; 3289 if (!current) return; 3290 const h = current.offsetHeight; 3291 track.style.height = h + 'px'; 3292 } 3293 3294 function applyTransform(x, animated = true) { 3295 if (animated) track.style.transition = 'transform 300ms ease, height 300ms ease'; 3296 else track.style.transition = 'none'; 3297 track.style.transform = `translateX(-${x}px)`; 3298 } 3299 3300 function updatePosition(animated = true) { 3301 const w = wrapper.clientWidth || 0; 3302 const offset = index * w; 3303 applyTransform(offset, animated); 3304 slides.forEach((s, i) => s.setAttribute('aria-hidden', i !== index)); 3305 // measure height after layout cycle 3306 requestAnimationFrame(updateTrackHeight); 3307 } 3308 3309 function prev() { index = Math.max(0, index - 1); updatePosition(); } 3310 function next() { index = Math.min(slides.length - 1, index + 1); updatePosition(); } 3311 function goTo(i) { index = Math.min(Math.max(0, i), slides.length - 1); updatePosition(); } 3312 function getIndex() { return index; } 3313 3314 // Buttons & dots 3315 const prevBtn = gridContainer.querySelector('.facebook-prev'); 3316 const nextBtn = gridContainer.querySelector('.facebook-next'); 3317 const dotsContainer = gridContainer.querySelector('.facebook-carousel-dots'); 3318 3319 if (prevBtn && !prevBtn._fbInit) { prevBtn._fbInit = true; prevBtn.addEventListener('click', prev); } 3320 if (nextBtn && !nextBtn._fbInit) { nextBtn._fbInit = true; nextBtn.addEventListener('click', next); } 3321 3322 if (dotsContainer) { 3323 dotsContainer.innerHTML = slides.map((_, i) => `<button class="facebook-dot ${i === index ? 'active' : ''}" data-index="${i}" aria-label="Go to slide ${i + 1}"></button>`).join(''); 3324 if (!dotsContainer._fbInit) { 3325 dotsContainer._fbInit = true; 3326 dotsContainer.addEventListener('click', (e) => { 3327 const btn = e.target.closest('.facebook-dot'); 3328 if (!btn) return; 3329 const i = Number(btn.dataset.index) || 0; 3330 goTo(i); 3331 }); 3332 } 3333 } 3334 3335 // Gesture handling on wrapper (pointer events preferred) 3336 function onPointerDown(clientX) { 3337 isPointerActive = true; 3338 startX = clientX; 3339 startOffset = index * wrapper.clientWidth; 3340 deltaX = 0; 3341 track.style.transition = 'none'; 3342 // cancel any pending RAF 3343 if (rafId) { cancelAnimationFrame(rafId); rafId = null; } 3344 } 3345 3346 function onPointerMove(clientX) { 3347 if (!isPointerActive) return; 3348 deltaX = clientX - startX; 3349 const translateX = Math.max(0, startOffset - deltaX); 3350 // apply transform via RAF for smoothness 3351 if (!rafId) { 3352 rafId = requestAnimationFrame(() => { 3353 track.style.transform = `translateX(${-startOffset + deltaX}px)`; 3354 rafId = null; 3355 }); 3356 } 3357 } 3358 3359 function onPointerUp() { 3360 if (!isPointerActive) return; 3361 isPointerActive = false; 3362 const threshold = Math.max(40, wrapper.clientWidth * 0.15); 3363 if (Math.abs(deltaX) > threshold) { 3364 if (deltaX < 0) next(); else prev(); 3365 } else { 3366 updatePosition(); 3367 } 3368 deltaX = 0; 3369 } 3370 3371 // Pointer event listeners (covers mouse + touchscreen on supporting browsers) 3372 wrapper.addEventListener('pointerdown', (e) => { 3373 // only primary button or touch 3374 if (e.pointerType === 'mouse' && e.button !== 0) return; 3375 wrapper.setPointerCapture && wrapper.setPointerCapture(e.pointerId); 3376 onPointerDown(e.clientX); 3377 }, { passive: true });
3378 3379 wrapper.addEventListener('pointermove', (e) => { 3380 onPointerMove(e.clientX); 3381 }, { passive: true }); 3382 3383 wrapper.addEventListener('pointerup', (e) => { 3384 wrapper.releasePointerCapture && wrapper.releasePointerCapture(e.pointerId); 3385 onPointerUp(); 3386 }); 3387 3388 wrapper.addEventListener('pointercancel', () => { 3389 isPointerActive = false; 3390 updatePosition(); 3391 }); 3392 3393 // Touch fallback for older iOS where pointer events may be absent 3394 wrapper.addEventListener('touchstart', (ev) => { 3395 if (ev.touches.length !== 1) return; 3396 onPointerDown(ev.touches[0].clientX); 3397 }, { passive: true }); 3398 3399 wrapper.addEventListener('touchmove', (ev) => { 3400 if (ev.touches.length !== 1) return; 3401 onPointerMove(ev.touches[0].clientX); 3402 }, { passive: true }); 3403 3404 wrapper.addEventListener('touchend', () => { 3405 onPointerUp(); 3406 }); 3407 3408 // keyboard 3409 wrapper.addEventListener('keydown', (e) => { 3410 if (e.key === 'ArrowLeft') prev(); 3411 if (e.key === 'ArrowRight') next(); 3412 }); 3413 3414 // initial sizing & position 3415 setSlideWidths(); 3416 setTimeout(() => { updatePosition(false); }, 50); 3417 3418 // expose controller 3419 return { 3420 updateDimensions: function () { 3421 setSlideWidths(); 3422 updatePosition(false); 3423 }, 3424 getIndex, 3425 goTo, 3426 getCount: () => slides.length 3427 }; 3428 } 3429 3430 function renderPosts(posts) { 3431 hideAllLoaders(); 3432 if (!gridContainer) return; 3433 3434 if (!posts || posts.length === 0) { 3435 gridContainer.innerHTML = `<div class="text-center text-muted py-4">No public posts available.</div>`; 3436 gridContainer.style.display = 'block'; 3437 return; 3438 } 3439 3440 const isMobile = window.innerWidth <= 576; // mobile breakpoint 3441 if (!isMobile) { 3442 // Desktop / tablet: original grid 3443 carouselController = null; 3444 const html = posts.map(p => buildCardHtml(p)).join(''); 3445 gridContainer.innerHTML = `<div class="facebook-grid">${html}</div>`; 3446 gridContainer.style.display = 'block'; 3447 return; 3448 } 3449 3450 // Mobile: single-item carousel 3451 const slidesHtml = posts.map(p => buildCardHtml(p)).join(''); 3452 const carouselHtml = ` 3453<div class="facebook-carousel-wrapper" tabindex="0" aria-roledescription="carousel"> 3454 <div class="facebook-carousel-track"> 3455 ${slidesHtml} 3456 </div> 3457</div> 3458<div class="facebook-carousel-controls"> 3459 <button class="facebook-prev btn btn-outline-secondary" aria-label="Previous">â¹</button> 3460 <div class="facebook-carousel-dots" role="tablist" aria-label="Slide indicators"></div> 3461 <button class="facebook-next btn btn-outline-secondary" aria-label="Next">âº</button> 3462</div> 3463`; 3464 gridContainer.innerHTML = carouselHtml; 3465 gridContainer.style.display = 'block'; 3466 3467 // init carousel interactions and save controller 3468 carouselController = initMobileCarousel('.facebook-carousel-wrapper'); 3469 } 3470 3471 // Fetch posts from server endpoint 3472 try { 3473 const resp = await fetch('/api/facebook/posts?limit=9', { credentials: 'same-origin' }); 3474 if (!resp.ok) { 3475 showError('Failed to load Facebook posts.'); 3476 return; 3477 } 3478 const json = await resp.json(); 3479 if (!json || !json.isSuccess) { 3480 showError('No posts returned.'); 3481 return; 3482 } 3483 3484 // Render once. Do NOT re-render whole carousel on every viewport resize (causes index reset). 3485 renderPosts(json.result || []); 3486 3487 // Only update carousel dimensions on resize / orientation change 3488 let resizeTimer; 3489 window.addEventListener('resize', () => { 3490 clearTimeout(resizeTimer); 3491 resizeTimer = setTimeout(() => { 3492 if (carouselController && typeof carouselController.updateDimensions === 'function') { 3493 carouselController.updateDimensions(); 3494 } 3495 }, 120); 3496 }); 3497 3498 // Also handle visual viewport resize for iOS (hides address bar etc)
3499 if (window.visualViewport) { 3500 let vvTimer; 3501 window.visualViewport.addEventListener('resize', () => { 3502 clearTimeout(vvTimer); 3503 vvTimer = setTimeout(() => { 3504 if (carouselController && typeof carouselController.updateDimensions === 'function') { 3505 carouselController.updateDimensions(); 3506 } 3507 }, 120); 3508 }); 3509 } 3510 3511 } catch (err) { 3512 console.error('Error loading facebook posts', err); 3513 showError('Error loading Facebook posts. Check console for details.'); 3514 } finally { 3515 // As a final safety net also hide any remaining loader nodes. 3516 hideAllLoaders(); 3517 } 3518 } 3519 3520}); 3521 </script>
3521 3522 3523 3524 3525 3526 3527 <!-- Load other scripts --> 3528
3528<script src="/js/accessibility.js?v=b3rzO7OzAETRbR1-e1-H8nVmD95KRHXXCTjRyKXyqcY"></script>
3528 3529
3529<script src="/js/analytics.js?v=ZHx0T-Ev9EpV4aY66LPq4N5yxeoAPpxBqh5vY67hjpE"></script>
3529 3530</body> 3531</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.