streaming.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> 6 <title>Streaming Library | PROOFOFCONCEPT</title> 7 8 <!-- Meta Tags --> 9 <meta name="description" content="Stream and watch films from PROOFOFCONCEPT's library. Browse our collection of experimental, romance, horror, and interactive films with advanced filtering and search capabilities."> 10 <meta name="keywords" content="streaming, online films, watch movies, experimental cinema, romance films, horror films, interactive films, Canadian cinema, independent films, PROOFOFCONCEPT streaming"> 11 <meta name="author" content="PROOFOFCONCEPT Productions"> 12 <meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"> 13 <meta name="theme-color" content="#EFF0EC"> 14 <meta name="color-scheme" content="light dark"> 15 <meta name="format-detection" content="telephone=no"> 16 <meta name="mobile-web-app-capable" content="yes"> 17 <meta name="apple-mobile-web-app-capable" content="yes"> 18 <meta name="apple-mobile-web-app-status-bar-style" content="default"> 19 <meta name="apple-mobile-web-app-title" content="Streaming Library - PROOFOFCONCEPT"> 20 21 <!-- Favicons --> 22 <link rel="icon" type="image/png" sizes="16x16" href="../assets/favicons/light/favicon-16x16.png" media="(prefers-color-scheme: light)"> 23 <link rel="icon" type="image/png" sizes="16x16" href="../assets/favicons/dark/favicon-16x16.png" media="(prefers-color-scheme: dark)"> 24 <link rel="icon" type="image/png" sizes="32x32" href="../assets/favicons/light/favicon-32x32.png" media="(prefers-color-scheme: light)"> 25 <link rel="icon" type="image/png" sizes="32x32" href="../assets/favicons/dark/favicon-32x32.png" media="(prefers-color-scheme: dark)"> 26 <link rel="icon" type="image/x-icon" href="../assets/favicons/light/favicon.ico" media="(prefers-color-scheme: light)"> 27 <link rel="icon" type="image/x-icon" href="../assets/favicons/dark/favicon.ico" media="(prefers-color-scheme: dark)"> 28 <link rel="icon" type="image/png" sizes="192x192" href="../assets/favicons/light/android-chrome-192x192.png" media="(prefers-color-scheme: light)"> 29 <link rel="icon" type="image/png" sizes="192x192" href="../assets/favicons/dark/android-chrome-192x192.png" media="(prefers-color-scheme: dark)"> 30 <link rel="icon" type="image/png" sizes="512x512" href="../assets/favicons/light/android-chrome-512x512.png" media="(prefers-color-scheme: light)"> 31 <link rel="icon" type="image/png" sizes="512x512" href="../assets/favicons/dark/android-chrome-512x512.png" media="(prefers-color-scheme: dark)"> 32 <link rel="apple-touch-icon" href="../assets/favicons/light/apple-touch-icon.png" media="(prefers-color-scheme: light)"> 33 <link rel="apple-touch-icon" href="../assets/favicons/dark/apple-touch-icon.png" media="(prefers-color-scheme: dark)"> 34 <link rel="manifest" href="../assets/favicons/light/site.webmanifest" media="(prefers-color-scheme: light)"> 35 <link rel="manifest" href="../assets/favicons/dark/site.webmanifest" media="(prefers-color-scheme: dark)"> 36 37 <!-- External Resources --> 38 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" /> 39 <link rel="preload" href="../assets/fonts/superbrigadecond.ttf" as="font" type="font/woff2" crossorigin> 40 41 <!-- Stylesheets --> 42 <link rel="stylesheet" href="../assets/css/main.css"> 43 <style> 44 @font-face { 45 font-family: 'NeueHaasGrotesk'; 46 src: url('../assets/fonts/neuehaasgrotdispround-75bold.otf') format('opentype'); 47 font-weight: 700; 48 font-style: normal; 49 font-display: swap; 50 } 51 @font-face { 52 font-family: 'SuperBrigadeCond'; 53 src: url('../assets/fonts/superbrigadecond.ttf') format('truetype'); 54 font-weight: normal; 55 font-style: normal; 56 font-display: swap; 57 } 58 59 html, body { 60 height: 100%; 61 background: #fff; 62 color: #111; 63 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 64 margin: 0; 65 padding: 0; 66 min-height: 100vh; 67 scroll-behavior: smooth; 68 overflow-x: hidden; 69 scroll-snap-type: y mandatory; 70 cursor: none !important; 71 } 72 73 body { 74 opacity: 1; 75 transition: opacity 0.4s; 76 } 77 78 body.fade { 79 opacity: 0; 80 transition: opacity 0.4s; 81 } 82 83 a, button, *:hover, *:active, *:focus { 84 cursor: none !important; 85 } 86 87 * { 88 box-sizing: border-box; 89 user-select: none !important; 90 -webkit-user-select: none !important; 91 -ms-user-select: none !important; 92 -moz-user-select: none !important; 93 -webkit-user-drag: none !important; 94 touch-action: manipulation; 95 } 96 97 .custom-cursor { 98 position: fixed; 99 width: 20px; 100 height: 20px; 101 background-color: #111; 102 border-radius: 50%; 103 pointer-events: none; 104 z-index: 10003; 105 transition: transform 0.15s, background-color 0.25s; 106 transform: translate(-50%, -50%) scale(1); 107 } 108 109 .custom-cursor.expand { 110 transform: translate(-50%, -50%) scale(2.5); 111 background-color: #11111144; 112 } 113 114 .custom-cursor.cursor-hover { 115 transform: translate(-50%, -50%) scale(1.5); 116 background-color: #111111cc; 117 } 118 119 /* Hide custom cursor on mobile devices */ 120 @media (max-width: 768px) { 121 .custom-cursor { 122 display: none !important; 123 } 124 html, body { 125 cursor: none !important; 126 } 127 * { 128 cursor: none !important; 129 } 130 } 131 132 .main-header { 133 position: fixed; 134 top: 0; 135 left: 0; 136 width: 100vw; 137 background: #000; 138 color: #fff; 139 z-index: 9999; 140 display: flex; 141 flex-direction: row; 142 align-items: center; 143 justify-content: center; 144 padding: 0.4rem 0 0.2rem 0; 145 border-bottom: 1px solid #222; 146 min-height: 35px; 147 } 148 149 .main-header-title { 150 font-family: 'SuperBrigadeCond', sans-serif; 151 font-size: 1.1rem; 152 letter-spacing: 0.05em; 153 text-align: center; 154 font-weight: bold; 155 margin: 0 auto; 156 position: absolute; 157 left: 50%; 158 transform: translateX(-50%); 159 width: auto; 160 } 161 162 .streaming-section { 163 min-height: 100vh; 164 width: 100vw; 165 display: flex; 166 flex-direction: column; 167 align-items: center; 168 justify-content: flex-start; 169 padding-top: 4rem; 170 padding-bottom: 2.7rem; 171 box-sizing: border-box; 172 position: relative; 173 scroll-snap-align: start; 174 } 175 176 .streaming-hero { 177 width: 100vw; 178 padding: 4vw 8vw; 179 text-align: center; 180 margin-bottom: 2vw; 181 } 182 183 .streaming-title { 184 font-family: 'SuperBrigadeCond', sans-serif; 185 font-size: 4vw; 186 font-weight: 900; 187 letter-spacing: -0.01em; 188 margin-bottom: 1vw; 189 line-height: 1.05; 190 color: #111; 191 } 192 193 .streaming-subtitle { 194 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 195 font-size: 1.9vw; 196 font-weight: 700; 197 color: #111; 198 margin-bottom: 2vw; 199 line-height: 1.1; 200 } 201 202 .streaming-description { 203 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 204 font-size: 1.2vw; 205 font-weight: 500; 206 color: #666; 207 max-width: 60vw; 208 margin: 0 auto; 209 line-height: 1.4; 210 } 211 212 .controls-section { 213 width: 100vw; 214 padding: 0 8vw; 215 margin-bottom: 3vw; 216 } 217 218 .search-filters-container { 219 display: flex; 220 flex-direction: column; 221 gap: 1.5vw; 222 background: #f8f8f8; 223 padding: 1.5vw; 224 border-radius: 1vw; 225 border: 1px solid #e0e0e0; 226 } 227 228 .search-container { 229 display: flex; 230 align-items: center; 231 gap: 1vw; 232 } 233 234 .search-input { 235 flex: 1; 236 padding: 0.8vw 1.2vw; 237 border: 2px solid #e0e0e0; 238 border-radius: 0.5vw; 239 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 240 font-size: 1vw; 241 background: #fff; 242 color: #111; 243 transition: border-color 0.2s, box-shadow 0.2s; 244 } 245 246 .search-input:focus { 247 outline: none; 248 border-color: #111; 249 box-shadow: 0 0 0 3px rgba(17, 17, 17, 0.1); 250 } 251 252 .search-input::placeholder { 253 color: #999; 254 } 255 256 .search-btn { 257 background: #111; 258 color: #fff; 259 border: none; 260 padding: 0.8vw 1.2vw; 261 border-radius: 0.5vw; 262 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 263 font-size: 1vw; 264 font-weight: 700; 265 cursor: pointer; 266 transition: background 0.2s, transform 0.2s; 267 } 268 269 .search-btn:hover { 270 background: #333; 271 transform: translateY(-1px); 272 } 273 274 .filters-container { 275 display: flex; 276 flex-wrap: wrap; 277 gap: 1.5vw; 278 align-items: center; 279 } 280 281 .filter-group { 282 display: flex; 283 align-items: center; 284 gap: 0.8vw; 285 } 286 287 .filter-label { 288 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 289 font-size: 0.9vw; 290 font-weight: 700; 291 color: #111; 292 text-transform: uppercase; 293 letter-spacing: 0.05em; 294 } 295 296 .filter-select { 297 padding: 0.6vw 1vw; 298 border: 2px solid #e0e0e0; 299 border-radius: 0.5vw; 300 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 301 font-size: 0.9vw; 302 background: #fff; 303 color: #111; 304 cursor: pointer; 305 transition: border-color 0.2s, background 0.2s; 306 min-width: 120px; 307 } 308 309 .filter-select:focus { 310 outline: none; 311 border-color: #111; 312 background: #fafafa; 313 } 314 315 .filter-select:hover { 316 border-color: #ccc; 317 background: #fafafa; 318 } 319 320 .movies-grid { 321 width: 100vw; 322 padding: 0 8vw; 323 display: grid; 324 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 325 gap: 2vw; 326 margin-bottom: 4vw; 327 } 328 329 .movie-card { 330 background: #fff; 331 border-radius: 1.5vw; 332 overflow: hidden; 333 box-shadow: 0 4px 20px rgba(0,0,0,0.08); 334 border: 1px solid #f0f0f0; 335 transition: all 0.3s ease; 336 cursor: pointer; 337 } 338 339 .movie-card:hover { 340 transform: translateY(-8px); 341 box-shadow: 0 12px 40px rgba(0,0,0,0.15); 342 border-color: #111; 343 } 344 345 .movie-image { 346 width: 100%; 347 height: 12vw; 348 min-height: 140px; 349 max-height: 180px; 350 overflow: hidden; 351 position: relative; 352 } 353 354 .movie-image img { 355 width: 100%; 356 height: 100%; 357 object-fit: cover; 358 transition: transform 0.3s ease; 359 } 360 361 .movie-card:hover .movie-image img { 362 transform: scale(1.05); 363 } 364 365 .movie-status { 366 position: absolute; 367 top: 1vw; 368 right: 1vw; 369 background: #111; 370 color: #fff; 371 padding: 0.3vw 0.8vw; 372 border-radius: 0.3vw; 373 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 374 font-size: 0.7vw; 375 font-weight: 700; 376 text-transform: uppercase; 377 letter-spacing: 0.05em; 378 } 379 380 .movie-status.coming-soon { 381 background: #666; 382 } 383 384 .movie-info { 385 padding: 2vw; 386 } 387 388 .movie-title { 389 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 390 font-size: 1.4vw; 391 font-weight: 700; 392 color: #111; 393 margin-bottom: 0.5vw; 394 line-height: 1.2; 395 } 396 397 .movie-genre { 398 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 399 font-size: 0.9vw; 400 color: #666; 401 margin-bottom: 1vw; 402 } 403 404 .movie-duration { 405 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 406 font-size: 0.8vw; 407 color: #999; 408 font-weight: 500; 409 } 410 411 .back-btn { 412 display: block; 413 margin: 2.5rem auto 0 auto; 414 background: #111; 415 color: #fff; 416 border: 2px solid #111; 417 border-radius: 0.8vw; 418 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 419 font-size: 1.1rem; 420 font-weight: 800; 421 padding: 0.8rem 2rem; 422 box-shadow: 0 4px 16px rgba(0,0,0,0.15); 423 cursor: pointer; 424 text-decoration: none; 425 transition: all 0.3s ease; 426 opacity: 1; 427 position: relative; 428 z-index: 10; 429 text-transform: uppercase; 430 letter-spacing: 0.05em; 431 } 432 433 .back-btn:hover { 434 background: #fff; 435 color: #111; 436 border: 2px solid #111; 437 opacity: 1; 438 transform: translateY(-2px); 439 box-shadow: 0 6px 20px rgba(0,0,0,0.2); 440 } 441 442 /* Movie Modal Styles */ 443 .movie-modal { 444 position: fixed; 445 top: 0; 446 left: 0; 447 width: 100vw; 448 height: 100vh; 449 background: rgba(0, 0, 0, 0.9); 450 z-index: 10001; 451 display: none; 452 align-items: center; 453 justify-content: center; 454 padding: 2vw; 455 box-sizing: border-box; 456 } 457 458 .movie-modal.active { 459 display: flex; 460 } 461 462 .modal-content { 463 background: #fff; 464 border-radius: 2vw; 465 max-width: 70vw; 466 max-height: 80vh; 467 overflow-y: auto; 468 position: relative; 469 animation: modalSlideIn 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); 470 } 471 472 @keyframes modalSlideIn { 473 from { 474 opacity: 0; 475 transform: translateY(30px) scale(0.95); 476 } 477 to { 478 opacity: 1; 479 transform: translateY(0) scale(1); 480 } 481 } 482 483 .modal-header { 484 padding: 2vw; 485 border-bottom: 1px solid #e0e0e0; 486 display: flex; 487 justify-content: space-between; 488 align-items: center; 489 } 490 491 .modal-title { 492 font-family: 'SuperBrigadeCond', sans-serif; 493 font-size: 2.5vw; 494 font-weight: 900; 495 color: #111; 496 } 497 498 .modal-close { 499 background: none; 500 border: none; 501 font-size: 2vw; 502 color: #666; 503 cursor: pointer; 504 padding: 0.5vw; 505 border-radius: 50%; 506 transition: all 0.2s; 507 } 508 509 .modal-close:hover { 510 background: #f0f0f0; 511 color: #111; 512 } 513 514 .modal-body { 515 padding: 2vw; 516 } 517 518 .modal-image { 519 width: 100%; 520 height: 20vw; 521 min-height: 200px; 522 border-radius: 1vw; 523 overflow: hidden; 524 margin-bottom: 2vw; 525 } 526 527 .modal-image img { 528 width: 100%; 529 height: 100%; 530 object-fit: cover; 531 } 532 533 .modal-actions-top { 534 display: flex; 535 gap: 1vw; 536 justify-content: flex-start; 537 margin-bottom: 2vw; 538 } 539 540 .action-btn { 541 background: #111; 542 color: #fff; 543 border: none; 544 padding: 0.8vw 1.5vw; 545 border-radius: 0.5vw; 546 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 547 font-size: 0.9vw; 548 font-weight: 700; 549 cursor: pointer; 550 transition: all 0.2s; 551 text-transform: uppercase; 552 letter-spacing: 0.05em; 553 min-width: 120px; 554 } 555 556 .action-btn:hover { 557 background: #333; 558 transform: translateY(-2px); 559 } 560 561 .action-btn:disabled { 562 background: #ccc; 563 cursor: not-allowed; 564 transform: none; 565 } 566 567 .action-btn.trailer { 568 background: #666; 569 } 570 571 .action-btn.trailer:hover { 572 background: #888; 573 } 574 575 .modal-description { 576 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 577 font-size: 1.1vw; 578 line-height: 1.6; 579 color: #333; 580 margin-bottom: 2vw; 581 } 582 583 .modal-details { 584 display: grid; 585 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 586 gap: 2vw; 587 margin-bottom: 2vw; 588 } 589 590 .detail-item { 591 display: flex; 592 flex-direction: column; 593 gap: 0.5vw; 594 } 595 596 .detail-label { 597 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 598 font-size: 0.9vw; 599 font-weight: 700; 600 color: #666; 601 text-transform: uppercase; 602 letter-spacing: 0.05em; 603 } 604 605 .detail-value { 606 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 607 font-size: 1vw; 608 color: #111; 609 font-weight: 600; 610 } 611 612 .modal-actions { 613 display: flex; 614 gap: 1vw; 615 justify-content: center; 616 padding-top: 2vw; 617 border-top: 1px solid #e0e0e0; 618 } 619 620 .play-btn { 621 background: #111; 622 color: #fff; 623 border: none; 624 padding: 1vw 2vw; 625 border-radius: 0.5vw; 626 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 627 font-size: 1.1vw; 628 font-weight: 700; 629 cursor: pointer; 630 transition: all 0.2s; 631 text-transform: uppercase; 632 letter-spacing: 0.05em; 633 } 634 635 .play-btn:hover { 636 background: #333; 637 transform: translateY(-2px); 638 } 639 640 .play-btn:disabled { 641 background: #ccc; 642 cursor: not-allowed; 643 transform: none; 644 } 645 646 /* Additional modal sections */ 647 .modal-section { 648 margin-bottom: 2vw; 649 padding-top: 2vw; 650 border-top: 1px solid #e0e0e0; 651 } 652 653 .modal-section-header { 654 font-family: 'SuperBrigadeCond', sans-serif; 655 font-size: 1.5vw; 656 font-weight: 900; 657 margin-bottom: 1.5vw; 658 letter-spacing: 0.01em; 659 color: #111; 660 } 661 662 .genre-tags { 663 display: flex; 664 flex-wrap: wrap; 665 gap: 0.5vw; 666 margin-bottom: 1vw; 667 } 668 669 .genre-tag { 670 display: inline-block; 671 background: #111; 672 color: #fff; 673 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 674 font-size: 0.7vw; 675 font-weight: 700; 676 padding: 0.3vw 0.8vw; 677 margin: 0.2vw 0.4vw 0.2vw 0; 678 border-radius: 0.3vw; 679 text-transform: uppercase; 680 letter-spacing: 0.03em; 681 } 682 683 .image-gallery { 684 display: grid; 685 grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); 686 gap: 1vw; 687 margin-bottom: 1vw; 688 } 689 690 .gallery-image { 691 width: 100%; 692 height: 12vw; 693 min-height: 120px; 694 border-radius: 0.5vw; 695 overflow: hidden; 696 cursor: pointer; 697 transition: transform 0.2s; 698 } 699 700 .gallery-image:hover { 701 transform: scale(1.05); 702 } 703 704 .gallery-image img { 705 width: 100%; 706 height: 100%; 707 object-fit: cover; 708 } 709 710 .credits-grid { 711 display: grid; 712 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 713 gap: 1.5vw; 714 } 715 716 .credit-category { 717 margin-bottom: 1vw; 718 } 719 720 .credit-title { 721 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 722 font-size: 0.8vw; 723 font-weight: 700; 724 color: #666; 725 margin-bottom: 0.3vw; 726 text-transform: uppercase; 727 letter-spacing: 0.05em; 728 } 729 730 .credit-content { 731 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 732 font-size: 0.9vw; 733 font-weight: 600; 734 color: #111; 735 line-height: 1.4; 736 } 737 738 .you-may-like-grid { 739 display: grid; 740 grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); 741 gap: 1.5vw; 742 } 743 744 .related-film-card { 745 background: #f8f8f8; 746 border-radius: 0.8vw; 747 overflow: hidden; 748 border: 1px solid #e0e0e0; 749 transition: all 0.2s ease; 750 cursor: pointer; 751 } 752 753 .related-film-card:hover { 754 transform: translateY(-4px); 755 box-shadow: 0 8px 25px rgba(0,0,0,0.12); 756 border-color: #111; 757 } 758 759 .related-film-image { 760 width: 100%; 761 height: 10vw; 762 min-height: 100px; 763 overflow: hidden; 764 } 765 766 .related-film-image img { 767 width: 100%; 768 height: 100%; 769 object-fit: cover; 770 transition: transform 0.2s ease; 771 } 772 773 .related-film-card:hover .related-film-image img { 774 transform: scale(1.05); 775 } 776 777 .related-film-title { 778 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 779 font-size: 0.9vw; 780 font-weight: 700; 781 color: #111; 782 padding: 1vw; 783 text-align: center; 784 line-height: 1.2; 785 } 786 787 /* Streaming Player Styles */ 788 .streaming-player { 789 position: fixed; 790 top: 0; 791 left: 0; 792 width: 100vw; 793 height: 100vh; 794 background: #000; 795 z-index: 10002; 796 display: none; 797 flex-direction: column; 798 } 799 800 .streaming-player.active { 801 display: flex; 802 } 803 804 .player-header { 805 background: rgba(0, 0, 0, 0.8); 806 padding: 1vw 2vw; 807 display: flex; 808 justify-content: space-between; 809 align-items: center; 810 z-index: 10; 811 } 812 813 .player-title { 814 font-family: 'SuperBrigadeCond', sans-serif; 815 font-size: 1.5vw; 816 color: #fff; 817 font-weight: 900; 818 } 819 820 .player-close { 821 background: none; 822 border: none; 823 color: #fff; 824 font-size: 1.5vw; 825 cursor: pointer; 826 padding: 0.5vw; 827 } 828 829 .player-content { 830 flex: 1; 831 display: flex; 832 align-items: center; 833 justify-content: center; 834 position: relative; 835 } 836 837 .video-placeholder { 838 width: 80%; 839 height: 60%; 840 background: #111; 841 border-radius: 1vw; 842 display: flex; 843 align-items: center; 844 justify-content: center; 845 color: #fff; 846 font-family: 'NeueHaasGrotesk', Helvetica, Arial, sans-serif; 847 font-size: 2vw; 848 text-align: center; 849 padding: 2vw; 850 } 851 852 .play-icon { 853 font-size: 4vw; 854 margin-bottom: 1vw; 855 opacity: 0.7; 856 } 857 858 /* Mobile Responsive Styles */ 859 @media (max-width: 900px) { 860 .streaming-title { font-size: 2.5rem; } 861 .streaming-subtitle { font-size: 1.5rem; } 862 .streaming-description { font-size: 1.1rem; max-width: 90vw; } 863 .controls-section { padding: 0 4vw; } 864 .search-filters-container { padding: 1.5rem; } 865 .search-input, .search-btn { 866 font-size: 1rem; 867 padding: 0.8rem 1.2rem; 868 } 869 .filter-label { font-size: 0.9rem; } 870 .filter-select { font-size: 0.9rem; padding: 0.4rem 0.8rem; } 871 .movies-grid { 872 padding: 0 4vw; 873 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 874 gap: 1.5rem; 875 } 876 .movie-image { height: 18vw; min-height: 120px; } 877 .movie-title { font-size: 1.2rem; } 878 .movie-genre { font-size: 0.9rem; } 879 .movie-duration { font-size: 0.8rem; } 880 .modal-title { font-size: 2rem; } 881 .modal-image { height: 30vw; min-height: 180px; } 882 .modal-description { font-size: 1.1rem; } 883 .action-btn { font-size: 1rem; padding: 0.8rem 1.5rem; } 884 .modal-section-header { font-size: 1.8rem; } 885 .genre-tag { font-size: 0.8rem; padding: 0.4rem 0.8rem; } 886 .gallery-image { height: 15vw; min-height: 100px; } 887 .related-film-image { height: 12vw; min-height: 80px; } 888 } 889 890 @media (max-width: 600px) { 891 .streaming-section { padding-top: 2.5rem; } 892 .streaming-hero { padding: 2rem 4vw; } 893 .streaming-title { font-size: 2rem; } 894 .streaming-subtitle { font-size: 1.3rem; } 895 .streaming-description { font-size: 1rem; } 896 .controls-section { padding: 0 4vw; margin-bottom: 2rem; } 897 .search-filters-container { padding: 1rem; } 898 .search-container { flex-direction: column; gap: 1rem; } 899 .search-input, .search-btn { width: 100%; } 900 .filters-container { flex-direction: column; align-items: stretch; gap: 1rem; } 901 .filter-group { justify-content: space-between; } 902 .movies-grid { 903 padding: 0 4vw; 904 grid-template-columns: 1fr; 905 gap: 1rem; 906 } 907 .movie-image { height: 40vw; min-height: 180px; } 908 .movie-info { padding: 1.5rem; } 909 .movie-title { font-size: 1.3rem; } 910 .modal-content { max-width: 95vw; max-height: 95vh; } 911 .modal-header { padding: 1.5rem; } 912 .modal-title { font-size: 1.8rem; } 913 .modal-body { padding: 1.5rem; } 914 .modal-image { height: 40vw; min-height: 160px; } 915 .modal-description { font-size: 1rem; } 916 .modal-details { grid-template-columns: 1fr; gap: 1rem; } 917 .detail-label { font-size: 0.8rem; } 918 .detail-value { font-size: 0.9rem; } 919 .modal-actions-top { flex-direction: column; gap: 1rem; } 920 .action-btn { width: 100%; font-size: 1rem; padding: 1rem; } 921 .player-title { font-size: 1.2rem; } 922 .video-placeholder { width: 95%; height: 70%; font-size: 1.5rem; } 923 .play-icon { font-size: 3rem; } 924 .modal-section-header { font-size: 1.5rem; } 925 .genre-tag { font-size: 0.7rem; padding: 0.3rem 0.6rem; } 926 .gallery-image { height: 20vw; min-height: 80px; } 927 .related-film-image { height: 15vw; min-height: 60px; } 928 .related-film-title { font-size: 0.9rem; padding: 0.8rem; } 929 } 930 </style> 931 </head> 932 <body> 933 <div class="custom-cursor" id="cursor"></div> 934 935 <header class="main-header"> 936 <a href="../index.html" class="main-header-title" style="text-decoration: none; color: inherit;">PROOFOFCONCEPT</a> 937 <div class="hamburger-icon"> 938 <i class="fas fa-bars"></i> 939 </div> 940 </header> 941 942 <!-- Side Menu --> 943 <div class="side-menu" id="side-menu"> 944 <div class="side-menu-header"> 945 <div class="side-menu-close"> 946 <i class="fas fa-times"></i> 947 </div> 948 </div> 949 <nav class="side-menu-nav"> 950 <a href="../films/streaming.html" class="side-menu-link">WATCH</a> 951 <a href="../blog/" class="side-menu-link">READ</a> 952 <a href="../pages/store.html" class="side-menu-link">SHOP</a> 953 <div class="menu-spacer"></div> 954 <a href="../pages/contribute.html" class="side-menu-link">CONTRIBUTE</a> 955 <a href="../pages/digifest" class="side-menu-link">DIGIFEST</a> 956 <div class="menu-spacer"></div> 957 <a href="../pages/about" class="side-menu-link">ABOUT</a> 958 <a href="../pages/faq" class="side-menu-link">FAQ</a> 959 </nav> 960 <div class="side-menu-footer"> 961 <div class="side-menu-bottom-nav"> 962 <a href="../pages/terms" class="side-menu-link side-menu-bottom-link">TERMS OF USE</a> 963 <a href="../pages/privacy" class="side-menu-link side-menu-bottom-link">PRIVACY POLICY</a> 964 </div> 965 <div class="side-menu-social"> 966 <a href="mailto:contact@proof-of-concept.ca" class="side-menu-social-link"> 967 <i class="fas fa-envelope"></i> 968 </a> 969 <a href="https://instagram.com/proof__concept" target="_blank" class="side-menu-social-link"> 970 <i class="fab fa-instagram"></i> 971 </a> 972 <a href="https://x.com/proof__concept" target="_blank" class="side-menu-social-link"> 973 <i class="fab fa-x-twitter"></i> 974 </a> 975 <a href="https://github.com/PROOFOFCONCEPT-Productions" target="_blank" class="side-menu-social-link"> 976 <i class="fab fa-github"></i> 977 </a> 978 </div> 979 </div> 980 </div> 981 982 <!-- Side Menu Overlay --> 983 <div class="side-menu-overlay" id="side-menu-overlay"></div> 984 985 <main class="streaming-section" id="main-section"> 986 <div class="streaming-hero"> 987 <h1 class="streaming-title">Streaming Library</h1> 988 </div> 989 990 <div class="controls-section"> 991 <div class="search-filters-container"> 992 <div class="search-container"> 993 <input type="text" class="search-input" id="search-input" placeholder="Search for films, directors, or genres..."> 994 <button class="search-btn" id="search-btn"> 995 <i class="fas fa-search"></i> 996 </button> 997 </div> 998 999 <div class="filters-container"> 1000 <div class="filter-group"> 1001 <label class="filter-label">Genre:</label> 1002 <select class="filter-select" id="genre-filter"> 1003 <option value="">All Genres</option> 1004 <option value="romance">Romance</option> 1005 <option value="horror">Horror</option> 1006 <option value="experimental">Experimental</option> 1007 <option value="interactive">Interactive</option> 1008 <option value="drama">Drama</option> 1009 <option value="poetry">Poetry</option> 1010 </select> 1011 </div> 1012 1013 <div class="filter-group"> 1014 <label class="filter-label">Status:</label> 1015 <select class="filter-select" id="status-filter"> 1016 <option value="">All</option> 1017 <option value="watch-now">Watch Now</option> 1018 <option value="coming-soon">Coming Soon</option> 1019 </select> 1020 </div> 1021 1022 <div class="filter-group"> 1023 <label class="filter-label">Sort By:</label> 1024 <select class="filter-select" id="sort-filter"> 1025 <option value="title">Title</option> 1026 <option value="genre">Genre</option> 1027 <option value="duration">Duration</option> 1028 <option value="newest">Newest First</option> 1029 <option value="oldest">Oldest First</option> 1030 </select> 1031 </div> 1032 </div> 1033 </div> 1034 </div> 1035 1036 <div class="movies-grid" id="movies-grid"> 1037 <!-- Movie cards will be populated by JavaScript --> 1038 </div> 1039 1040 </main> 1041 1042 <!-- Movie Modal --> 1043 <div class="movie-modal" id="movie-modal"> 1044 <div class="modal-content"> 1045 <div class="modal-header"> 1046 <h2 class="modal-title" id="modal-title">Film Title</h2> 1047 <button class="modal-close" id="modal-close">×</button> 1048 </div> 1049 <div class="modal-body"> 1050 <div class="modal-image"> 1051 <img id="modal-image" src="" alt="Film still"> 1052 </div> 1053 1054 <div class="modal-actions-top"> 1055 <button class="action-btn" id="watch-btn">Watch Now</button> 1056 <button class="action-btn trailer" id="trailer-btn">Trailer</button> 1057 </div> 1058 1059 <p class="modal-description" id="modal-description">Film description will appear here.</p> 1060 1061 <div class="modal-details"> 1062 <div class="detail-item"> 1063 <span class="detail-label">Director</span> 1064 <span class="detail-value" id="modal-director">-</span> 1065 </div> 1066 <div class="detail-item"> 1067 <span class="detail-label">Genre</span> 1068 <span class="detail-value" id="modal-genre">-</span> 1069 </div> 1070 <div class="detail-item"> 1071 <span class="detail-label">Duration</span> 1072 <span class="detail-value" id="modal-duration">-</span> 1073 </div> 1074 <div class="detail-item"> 1075 <span class="detail-label">Status</span> 1076 <span class="detail-value" id="modal-status">-</span> 1077 </div> 1078 </div> 1079 1080 <!-- Genre Tags Section --> 1081 <div class="modal-section"> 1082 <h3 class="modal-section-header">Genres</h3> 1083 <div class="genre-tags" id="modal-genre-tags"> 1084 <!-- Genre tags will be populated by JavaScript --> 1085 </div> 1086 </div> 1087 1088 <!-- Image Gallery Section --> 1089 <div class="modal-section"> 1090 <h3 class="modal-section-header">Gallery</h3> 1091 <div class="image-gallery" id="modal-gallery"> 1092 <!-- Gallery images will be populated by JavaScript --> 1093 </div> 1094 </div> 1095 1096 <!-- Credits Section --> 1097 <div class="modal-section"> 1098 <h3 class="modal-section-header">Cast & Crew</h3> 1099 <div class="credits-grid" id="modal-credits"> 1100 <!-- Credits will be populated by JavaScript --> 1101 </div> 1102 </div> 1103 1104 <!-- Film Details Section --> 1105 <div class="modal-section"> 1106 <h3 class="modal-section-header">Film Details</h3> 1107 <div class="credits-grid" id="modal-film-details"> 1108 <!-- Film details will be populated by JavaScript --> 1109 </div> 1110 </div> 1111 1112 <!-- You May Like Section --> 1113 <div class="modal-section"> 1114 <h3 class="modal-section-header">You May Like</h3> 1115 <div class="you-may-like-grid" id="modal-related-films"> 1116 <!-- Related films will be populated by JavaScript --> 1117 </div> 1118 </div> 1119 </div> 1120 </div> 1121 </div> 1122 1123 <!-- Streaming Player --> 1124 <div class="streaming-player" id="streaming-player"> 1125 <div class="player-header"> 1126 <h3 class="player-title" id="player-title">Film Title</h3> 1127 <button class="player-close" id="player-close">×</button> 1128 </div> 1129 <div class="player-content"> 1130 <div class="video-placeholder"> 1131 <div> 1132 <div class="play-icon">▶</div> 1133 <div>Video Player</div> 1134 <div style="font-size: 1vw; margin-top: 1vw; opacity: 0.7;">Streaming functionality coming soon</div> 1135 </div> 1136 </div> 1137 </div> 1138 </div> 1139 1140 <script> 1141 // Custom cursor functionality 1142 const cursor = document.getElementById("cursor"); 1143 document.addEventListener("mousemove", e => { 1144 cursor.style.top = e.clientY + "px"; 1145 cursor.style.left = e.clientX + "px"; 1146 }); 1147 document.addEventListener("mousedown", () => { 1148 cursor.classList.add("expand"); 1149 }); 1150 document.addEventListener("mouseup", () => { 1151 cursor.classList.remove("expand"); 1152 }); 1153 1154 const allLinks = document.querySelectorAll('a, button'); 1155 allLinks.forEach(link => { 1156 link.addEventListener('mouseenter', () => { 1157 cursor.classList.add('cursor-hover'); 1158 }); 1159 link.addEventListener('mouseleave', () => { 1160 cursor.classList.remove('cursor-hover'); 1161 }); 1162 }); 1163 1164 // Movie data 1165 const movies = [ 1166 { 1167 id: 'love1', 1168 title: 'love.1', 1169 genre: 'Romance, Experimental, Poetry', 1170 duration: '1 minute', 1171 status: 'watch-now', 1172 image: '../assets/images/love/image1.jpg', 1173 description: 'A beautiful visual poem film about love themes, adapted to the modern-day as an Instagram Reel. 116 images in 1 minute, directed by Jack O\'Keeffe with music by Franz Liszt.', 1174 director: 'Jack O\'Keeffe', 1175 available: true, 1176 genres: ['Romance', 'Experimental', 'Poetry'], 1177 gallery: [ 1178 '../assets/images/love/image1.jpg', 1179 '../assets/images/love/image2.jpg', 1180 '../assets/images/love/image3.jpg', 1181 '../assets/images/love/image4.jpg' 1182 ], 1183 credits: { 1184 'Director': 'Jack O\'Keeffe', 1185 'Producer': 'PROOFOFCONCEPT Productions', 1186 'Music': 'Franz Liszt', 1187 'Inspiration': 'Jean-Luc Godard, Anna Karina', 1188 'Format': 'Instagram Reel', 1189 'Images': '116 images' 1190 }, 1191 filmDetails: { 1192 'Runtime': '1 minute', 1193 'Language': 'English', 1194 'Production': 'Independent', 1195 'Country': 'Canada', 1196 'Year': '2025', 1197 'Format': 'Digital' 1198 }, 1199 relatedFilms: ['lovers', 'community', 'horror'] 1200 }, 1201 { 1202 id: 'lovers', 1203 title: 'The Lovers', 1204 genre: 'Interactive, Romance, Drama, Horror', 1205 duration: '7-9 minutes', 1206 status: 'coming-soon', 1207 image: '../assets/images/lovers/image1.jpg', 1208 description: 'A story about two people, who may or may not be in a relationship, and the events surrounding them. An interactive film exploring unconventional love stories with horror elements.', 1209 director: 'Jack O\'Keeffe', 1210 available: false, 1211 genres: ['Interactive', 'Romance', 'Drama', 'Horror'], 1212 gallery: [ 1213 '../assets/images/lovers/image1.jpg', 1214 '../assets/images/lovers/image2.jpg', 1215 '../assets/images/lovers/image3.jpg' 1216 ], 1217 credits: { 1218 'Director': 'Jack O\'Keeffe', 1219 'Producer': 'PROOFOFCONCEPT Productions', 1220 'Lead Actors': 'TBA', 1221 'Cinematography': 'TBA', 1222 'Editing': 'TBA', 1223 'Interactive Design': 'TBA' 1224 }, 1225 filmDetails: { 1226 'Runtime': '7-9 minutes', 1227 'Language': 'English', 1228 'Production': 'Independent', 1229 'Country': 'Canada', 1230 'Year': '2026', 1231 'Format': 'Interactive Cinema' 1232 }, 1233 relatedFilms: ['love1', 'community', 'horror'] 1234 }, 1235 { 1236 id: 'community', 1237 title: '#COMMUNITYFILM', 1238 genre: 'Experimental, Community, Documentary', 1239 duration: 'TBA', 1240 status: 'coming-soon', 1241 image: '../assets/images/community/image1.jpg', 1242 description: 'An experimental community film project that explores the collective experience and shared narratives of diverse communities.', 1243 director: 'Jack O\'Keeffe', 1244 available: false, 1245 genres: ['Experimental', 'Community', 'Documentary'], 1246 gallery: [ 1247 '../assets/images/community/image1.jpg', 1248 '../assets/images/community/image2.jpg', 1249 '../assets/images/community/image3.jpg' 1250 ], 1251 credits: { 1252 'Director': 'Jack O\'Keeffe', 1253 'Producer': 'PROOFOFCONCEPT Productions', 1254 'Community Coordinator': 'TBA', 1255 'Documentary Style': 'Experimental', 1256 'Subject Matter': 'Community Stories' 1257 }, 1258 filmDetails: { 1259 'Runtime': 'TBA', 1260 'Language': 'English', 1261 'Production': 'Independent', 1262 'Country': 'Canada', 1263 'Year': 'TBA', 1264 'Format': 'Documentary' 1265 }, 1266 relatedFilms: ['love1', 'lovers', 'horror'] 1267 }, 1268 { 1269 id: 'horror', 1270 title: 'HORROR', 1271 genre: 'Horror, Experimental, Thriller', 1272 duration: 'TBA', 1273 status: 'coming-soon', 1274 image: '../assets/images/horror.jpg', 1275 description: 'A psychological horror film that pushes the boundaries of conventional horror cinema through experimental storytelling and innovative techniques.', 1276 director: 'Jack O\'Keeffe', 1277 available: false, 1278 genres: ['Horror', 'Experimental', 'Thriller'], 1279 gallery: [ 1280 '../assets/images/horror.jpg' 1281 ], 1282 credits: { 1283 'Director': 'Jack O\'Keeffe', 1284 'Producer': 'PROOFOFCONCEPT Productions', 1285 'Horror Elements': 'Psychological', 1286 'Style': 'Experimental', 1287 'Subgenre': 'Thriller' 1288 }, 1289 filmDetails: { 1290 'Runtime': 'TBA', 1291 'Language': 'English', 1292 'Production': 'Independent', 1293 'Country': 'Canada', 1294 'Year': 'TBA', 1295 'Format': 'Feature Film' 1296 }, 1297 relatedFilms: ['love1', 'lovers', 'community'] 1298 } 1299 ]; 1300 1301 // DOM elements 1302 const moviesGrid = document.getElementById('movies-grid'); 1303 const searchInput = document.getElementById('search-input'); 1304 const searchBtn = document.getElementById('search-btn'); 1305 const genreFilter = document.getElementById('genre-filter'); 1306 const statusFilter = document.getElementById('status-filter'); 1307 const sortFilter = document.getElementById('sort-filter'); 1308 const movieModal = document.getElementById('movie-modal'); 1309 const modalClose = document.getElementById('modal-close'); 1310 const streamingPlayer = document.getElementById('streaming-player'); 1311 const playerClose = document.getElementById('player-close'); 1312 1313 // Current filtered movies 1314 let filteredMovies = [...movies]; 1315 1316 // Initialize the page 1317 function init() { 1318 renderMovies(); 1319 setupEventListeners(); 1320 } 1321 1322 // Render movies in the grid 1323 function renderMovies() { 1324 moviesGrid.innerHTML = ''; 1325 1326 filteredMovies.forEach(movie => { 1327 const movieCard = createMovieCard(movie); 1328 moviesGrid.appendChild(movieCard); 1329 }); 1330 } 1331 1332 // Create a movie card element 1333 function createMovieCard(movie) { 1334 const card = document.createElement('div'); 1335 card.className = 'movie-card'; 1336 card.dataset.movieId = movie.id; 1337 1338 const statusClass = movie.status === 'coming-soon' ? 'coming-soon' : ''; 1339 1340 card.innerHTML = ` 1341 <div class="movie-image"> 1342 <img src="${movie.image}" alt="${movie.title}"> 1343 <div class="movie-status ${statusClass}">${movie.status === 'coming-soon' ? 'Coming Soon' : 'Watch Now'}</div> 1344 </div> 1345 <div class="movie-info"> 1346 <h3 class="movie-title">${movie.title}</h3> 1347 <p class="movie-genre">${movie.genre}</p> 1348 <p class="movie-duration">${movie.duration}</p> 1349 </div> 1350 `; 1351 1352 card.addEventListener('click', () => openMovieModal(movie)); 1353 return card; 1354 } 1355 1356 // Open movie modal 1357 function openMovieModal(movie) { 1358 document.getElementById('modal-title').textContent = movie.title; 1359 document.getElementById('modal-image').src = movie.image; 1360 document.getElementById('modal-image').alt = movie.title; 1361 document.getElementById('modal-description').textContent = movie.description; 1362 document.getElementById('modal-director').textContent = movie.director; 1363 document.getElementById('modal-genre').textContent = movie.genre; 1364 document.getElementById('modal-duration').textContent = movie.duration; 1365 document.getElementById('modal-status').textContent = movie.status === 'coming-soon' ? 'Coming Soon' : 'Available Now'; 1366 1367 // Populate genre tags 1368 const genreTagsContainer = document.getElementById('modal-genre-tags'); 1369 genreTagsContainer.innerHTML = ''; 1370 if (movie.genres) { 1371 movie.genres.forEach(genre => { 1372 const tag = document.createElement('span'); 1373 tag.className = 'genre-tag'; 1374 tag.textContent = genre; 1375 genreTagsContainer.appendChild(tag); 1376 }); 1377 } 1378 1379 // Populate image gallery 1380 const galleryContainer = document.getElementById('modal-gallery'); 1381 galleryContainer.innerHTML = ''; 1382 if (movie.gallery) { 1383 movie.gallery.forEach(imageSrc => { 1384 const galleryImage = document.createElement('div'); 1385 galleryImage.className = 'gallery-image'; 1386 const img = document.createElement('img'); 1387 img.src = imageSrc; 1388 img.alt = `${movie.title} still`; 1389 galleryImage.appendChild(img); 1390 galleryContainer.appendChild(galleryImage); 1391 }); 1392 } 1393 1394 // Populate credits 1395 const creditsContainer = document.getElementById('modal-credits'); 1396 creditsContainer.innerHTML = ''; 1397 if (movie.credits) { 1398 Object.entries(movie.credits).forEach(([role, person]) => { 1399 const creditCategory = document.createElement('div'); 1400 creditCategory.className = 'credit-category'; 1401 creditCategory.innerHTML = ` 1402 <div class="credit-title">${role}</div> 1403 <div class="credit-content">${person}</div> 1404 `; 1405 creditsContainer.appendChild(creditCategory); 1406 }); 1407 } 1408 1409 // Populate film details 1410 const filmDetailsContainer = document.getElementById('modal-film-details'); 1411 filmDetailsContainer.innerHTML = ''; 1412 if (movie.filmDetails) { 1413 Object.entries(movie.filmDetails).forEach(([detail, value]) => { 1414 const detailItem = document.createElement('div'); 1415 detailItem.className = 'credit-category'; 1416 detailItem.innerHTML = ` 1417 <div class="credit-title">${detail}</div> 1418 <div class="credit-content">${value}</div> 1419 `; 1420 filmDetailsContainer.appendChild(detailItem); 1421 }); 1422 } 1423 1424 // Populate related films 1425 const relatedFilmsContainer = document.getElementById('modal-related-films'); 1426 relatedFilmsContainer.innerHTML = ''; 1427 if (movie.relatedFilms) { 1428 movie.relatedFilms.forEach(filmId => { 1429 const relatedFilm = movies.find(m => m.id === filmId); 1430 if (relatedFilm) { 1431 const relatedCard = document.createElement('div'); 1432 relatedCard.className = 'related-film-card'; 1433 relatedCard.innerHTML = ` 1434 <div class="related-film-image"> 1435 <img src="${relatedFilm.image}" alt="${relatedFilm.title}"> 1436 </div> 1437 <div class="related-film-title">${relatedFilm.title}</div> 1438 `; 1439 relatedCard.addEventListener('click', () => { 1440 closeMovieModal(); 1441 setTimeout(() => openMovieModal(relatedFilm), 100); 1442 }); 1443 relatedFilmsContainer.appendChild(relatedCard); 1444 } 1445 }); 1446 } 1447 1448 // Setup action buttons 1449 const watchBtn = document.getElementById('watch-btn'); 1450 const trailerBtn = document.getElementById('trailer-btn'); 1451 1452 if (movie.available) { 1453 watchBtn.disabled = false; 1454 watchBtn.textContent = 'Watch Now'; 1455 watchBtn.onclick = () => openStreamingPlayer(movie); 1456 } else { 1457 watchBtn.disabled = true; 1458 watchBtn.textContent = 'Coming Soon'; 1459 } 1460 1461 // Trailer button (placeholder for now) 1462 trailerBtn.onclick = () => { 1463 alert('Trailer functionality coming soon!'); 1464 }; 1465 1466 movieModal.classList.add('active'); 1467 document.body.style.overflow = 'hidden'; 1468 } 1469 1470 // Close movie modal 1471 function closeMovieModal() { 1472 movieModal.classList.remove('active'); 1473 document.body.style.overflow = 'auto'; 1474 } 1475 1476 // Open streaming player 1477 function openStreamingPlayer(movie) { 1478 document.getElementById('player-title').textContent = movie.title; 1479 streamingPlayer.classList.add('active'); 1480 document.body.style.overflow = 'hidden'; 1481 closeMovieModal(); 1482 } 1483 1484 // Close streaming player 1485 function closeStreamingPlayer() { 1486 streamingPlayer.classList.remove('active'); 1487 document.body.style.overflow = 'auto'; 1488 } 1489 1490 // Filter and search movies 1491 function filterMovies() { 1492 const searchTerm = searchInput.value.toLowerCase(); 1493 const selectedGenre = genreFilter.value.toLowerCase(); 1494 const selectedStatus = statusFilter.value; 1495 const sortBy = sortFilter.value; 1496 1497 filteredMovies = movies.filter(movie => { 1498 const matchesSearch = movie.title.toLowerCase().includes(searchTerm) || 1499 movie.genre.toLowerCase().includes(searchTerm) || 1500 movie.director.toLowerCase().includes(searchTerm); 1501 const matchesGenre = !selectedGenre || movie.genre.toLowerCase().includes(selectedGenre); 1502 const matchesStatus = !selectedStatus || movie.status === selectedStatus; 1503 1504 return matchesSearch && matchesGenre && matchesStatus; 1505 }); 1506 1507 // Sort movies 1508 switch (sortBy) { 1509 case 'title': 1510 filteredMovies.sort((a, b) => a.title.localeCompare(b.title)); 1511 break; 1512 case 'genre': 1513 filteredMovies.sort((a, b) => a.genre.localeCompare(b.genre)); 1514 break; 1515 case 'duration': 1516 filteredMovies.sort((a, b) => a.duration.localeCompare(b.duration)); 1517 break; 1518 case 'newest': 1519 // For now, just reverse the order since we don't have dates 1520 filteredMovies.reverse(); 1521 break; 1522 case 'oldest': 1523 // Keep original order 1524 break; 1525 } 1526 1527 renderMovies(); 1528 } 1529 1530 // Setup event listeners 1531 function setupEventListeners() { 1532 searchInput.addEventListener('input', filterMovies); 1533 searchBtn.addEventListener('click', filterMovies); 1534 genreFilter.addEventListener('change', filterMovies); 1535 statusFilter.addEventListener('change', filterMovies); 1536 sortFilter.addEventListener('change', filterMovies); 1537 1538 modalClose.addEventListener('click', closeMovieModal); 1539 playerClose.addEventListener('click', closeStreamingPlayer); 1540 1541 // Close modal when clicking outside 1542 movieModal.addEventListener('click', (e) => { 1543 if (e.target === movieModal) { 1544 closeMovieModal(); 1545 } 1546 }); 1547 1548 // Close player when clicking outside 1549 streamingPlayer.addEventListener('click', (e) => { 1550 if (e.target === streamingPlayer) { 1551 closeStreamingPlayer(); 1552 } 1553 }); 1554 1555 // Close modal/player with Escape key 1556 document.addEventListener('keydown', (e) => { 1557 if (e.key === 'Escape') { 1558 if (streamingPlayer.classList.contains('active')) { 1559 closeStreamingPlayer(); 1560 } else if (movieModal.classList.contains('active')) { 1561 closeMovieModal(); 1562 } 1563 } 1564 }); 1565 } 1566 1567 // Initialize when DOM is loaded 1568 document.addEventListener('DOMContentLoaded', init); 1569 1570 // Fade in on load 1571 document.body.classList.add('fade'); 1572 window.addEventListener('DOMContentLoaded', () => { 1573 document.body.classList.remove('fade'); 1574 }); 1575 1576 // Fade out on link click 1577 document.querySelectorAll('a').forEach(link => { 1578 if (link.hostname === window.location.hostname) { 1579 link.addEventListener('click', function(e) { 1580 if (link.target === '_blank' || link.href.includes('#')) return; 1581 e.preventDefault(); 1582 document.body.classList.add('fade'); 1583 setTimeout(() => { 1584 window.location = link.href; 1585 }, 400); 1586 }); 1587 } 1588 }); 1589 1590 // Newsletter form handling 1591 document.getElementById('newsletter-form').addEventListener('submit', function(e) { 1592 e.preventDefault(); 1593 const email = this.querySelector('.newsletter-input').value; 1594 const button = this.querySelector('.newsletter-button'); 1595 const input = this.querySelector('.newsletter-input'); 1596 1597 // Here you would typically send the email to your backend 1598 // For now, we'll show a smooth button transition 1599 1600 // Disable the input and button 1601 input.disabled = true; 1602 button.disabled = true; 1603 1604 // Smoothly transition button to "Thank you" 1605 button.textContent = 'Thank you!'; 1606 button.classList.add('thank-you'); 1607 1608 // Clear the form 1609 input.value = ''; 1610 1611 // Button stays as "Thank you" until page refresh 1612 // Form remains disabled to prevent multiple submissions 1613 }); 1614 </script> 1615 1616 <!-- INFO Section --> 1617 <section class="info-section"> 1618 <div class="info-content"> 1619 <div class="info-left"> 1620 <h2 class="info-header">ABOUT</h2> 1621 <p class="info-paragraph">PROOFOFCONCEPT is a multidisciplinary media studio focused on unconventional approaches to film which integrate new ideas and state-of-the-art technology, immersing the viewer into the media experience.</p> 1622 </div> 1623 1624 <div class="info-center"> 1625 <h2 class="info-header">INFO</h2> 1626 <div class="info-links"> 1627 <a href="../blog/" class="info-link">Articles</a> 1628 <a href="../pages/privacy" class="info-link">Privacy Policy</a> 1629 <a href="../pages/about" class="info-link">About</a> 1630 <a href="../pages/faq" class="info-link">FAQ</a> 1631 </div> 1632 </div> 1633 1634 <!-- Newsletter Signup --> 1635 <div class="info-newsletter"> 1636 <h2 class="info-header">STAY UPDATED</h2> 1637 <form class="newsletter-form" id="newsletter-form"> 1638 <input type="email" class="newsletter-input" placeholder="Enter your email" required> 1639 <button type="submit" class="newsletter-button">Subscribe</button> 1640 </form> 1641 </div> 1642 1643 <div class="info-right"> 1644 <h2 class="info-header">CONTACT</h2> 1645 <div class="info-email"><a href="mailto:contact@proof-of-concept.ca">contact@proof-of-concept.ca</a></div> 1646 <div class="info-icons"> 1647 <a href="mailto:contact@proof-of-concept.ca" class="info-icon" title="Email" aria-label="Email"> 1648 <i class="fa-solid fa-envelope"></i> 1649 </a> 1650 <a href="https://instagram.com/proof__concept" class="info-icon" title="Instagram" aria-label="Instagram" target="_blank"> 1651 <i class="fa-brands fa-instagram"></i> 1652 </a> 1653 <a href="https://x.com/proof__concept" class="info-icon" title="X (Twitter)" aria-label="X (Twitter)" target="_blank"> 1654 <i class="fa-brands fa-x-twitter"></i> 1655 </a> 1656 <a href="https://github.com/PROOFOFCONCEPT-Productions" class="info-icon" title="GitHub" aria-label="GitHub" target="_blank"> 1657 <i class="fa-brands fa-github"></i> 1658 </a> 1659 </div> 1660 </div> 1661 </div> 1662 </section> 1663 1664 <!-- Scripts --> 1665 <script src="../assets/js/main.js"></script> 1666 </body> 1667 </html>