/* Copyright (C) 2026 Muhammed Usmaan Imran
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License.
*/

/* ========================================================================= */
/* DO NOT EDIT - SHARED TEMPLATE: GLOBAL CSS FILE                            */
/* As per Coursework Section 4.1, Student 1 is responsible for this file.    */
/* ALL TEAM MEMBERS MUST USE THIS FILE. Do not put page-specific CSS here.   */
/* Any custom page styles must go in an embedded <style> tag on your HTML.   */
/* ========================================================================= */

/* Pull custom fonts 'Inter' and 'Playfair Display' directly from Google's servers */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:wght@700;900&display=swap');

/* Store exact color codes, font sizes, and animation math in variables so we don't have to retype them. The clamp() math automatically resizes text and spacing based on the screen width */
:root {
  --c-bg: #030508;
  --c-surface-1: rgba(8, 10, 18, 0.97);
  --c-surface-2: rgba(14, 18, 30, 0.6);
  --c-surface-3: rgba(20, 26, 42, 0.45);
  --c-border: rgba(255, 255, 255, 0.08);
  --c-border-hi: rgba(255, 255, 255, 0.16);
  --c-border-gold: rgba(212, 175, 55, 0.35);
  --c-gold: #d4af37;
  --c-gold-dim: #a8892b;
  --c-gold-glow: rgba(212, 175, 55, 0.22);
  --c-gold-soft: rgba(212, 175, 55, 0.08);
  --c-cyan: #22d3ee;
  --c-cyan-glow: rgba(34, 211, 238, 0.15);
  --c-green: #10b981;
  --c-green-glow: rgba(16, 185, 129, 0.18);
  --c-text: #eef2f7;
  --c-muted: #7a8fa6;
  --c-faint: rgba(238, 242, 247, 0.4);
  --font-heading: 'Playfair Display', Georgia, serif;
  --font-body: 'Inter', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
  --fs-display: clamp(3rem, 6vw + 1rem, 7.5rem);
  --fs-hero-sub: clamp(1rem, 1.4vw + 0.4rem, 1.3rem);
  --fs-h2: clamp(1.7rem, 2.5vw + 0.5rem, 2.8rem);
  --fs-h3: clamp(1.1rem, 1.4vw + 0.2rem, 1.65rem);
  --fs-body: clamp(0.9rem, 0.9vw + 0.2rem, 1rem);
  --fs-label: clamp(0.7rem, 0.6vw + 0.15rem, 0.8rem);
  --sp-xs: clamp(0.4rem, 0.8vw, 0.65rem);
  --sp-sm: clamp(0.75rem, 1.4vw, 1rem);
  --sp-md: clamp(1rem, 2vw, 1.5rem);
  --sp-lg: clamp(1.5rem, 3vw, 2.5rem);
  --sp-xl: clamp(2.5rem, 5vw, 5rem);
  --sp-2xl: clamp(4rem, 8vw, 9rem);
  --blur-sm: blur(16px) saturate(160%);
  --blur-md: blur(32px) saturate(190%);
  --blur-lg: blur(48px) saturate(220%);
  --shadow-card: 0 4px 24px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  --shadow-hover: 0 16px 48px rgba(0, 0, 0, 0.85), 0 0 24px var(--c-gold-glow);
  --shadow-glow: 0 0 32px var(--c-gold-glow);
  --radius-sm: 6px;
  --radius-md: 14px;
  --radius-lg: 22px;
  --radius-xl: 36px;
  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --mouse-x: 40%;
  --mouse-y: 40%;
}

/* Force every single element on the page to include its borders and padding inside its total width, and strip all default browser margins */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Make jumping to anchor links smooth instead of instant, and turn on anti-aliasing to make text look sharper on Mac screens */
html {
  scroll-behavior: smooth;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

/* Set up the main page background. Use Flexbox to stack items vertically. Draw 3 massive circular gradients (gold, cyan, gold) that stay glued to the screen when you scroll. The first gradient moves based on where the mouse variables point */
body {
  font-family: var(--font-body);
  background-color: var(--c-bg);
  color: var(--c-text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-image:
    radial-gradient(ellipse 70vw 55vh at var(--mouse-x) var(--mouse-y),
      rgba(212, 175, 55, 0.055) 0%, transparent 65%),
    radial-gradient(ellipse 55vw 65vh at 8% 55%,
      rgba(34, 211, 238, 0.035) 0%, transparent 55%),
    radial-gradient(ellipse 45vw 50vh at 92% 15%,
      rgba(212, 175, 55, 0.04) 0%, transparent 50%);
  background-attachment: fixed;
}

/* Create an invisible layer that sits over the whole screen and paints a 3% opacity static TV noise texture SVG to give the background a grainy look */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='250' height='250'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='250' height='250' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 9990;
}

/* Hack the browser's default scrollbar to make it only 4 pixels wide */
::-webkit-scrollbar {
  width: 4px;
}

/* Paint the track behind the scrollbar black */
::-webkit-scrollbar-track {
  background: #000;
}

/* Paint the actual draggable scrollbar piece dark blue, round the edges, and make it fade to gold when hovered */
::-webkit-scrollbar-thumb {
  background: #1e293b;
  border-radius: 4px;
  transition: background 0.3s;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--c-gold);
}

/* Paint text with a diagonal white-to-gold gradient by masking the background onto the text shape */
.text-gradient {
  background: linear-gradient(120deg, #fff 5%, var(--c-gold) 95%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
}

/* Paint text with a diagonal cyan-to-light-blue gradient by masking the background onto the text shape */
.text-cyan {
  background: linear-gradient(120deg, var(--c-cyan), #a5f3fc);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
}

/* Shrink an element to exactly 1 pixel and hide it off-screen so blind users using screen readers can hear it, but sighted users won't see it */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Prep elements to be animated. Make them invisible, move them 30 pixels down, and blur them. Setup the math for the animation to take 1 second using a cubic bezier curve */
.reveal,
.reveal-element {
  opacity: 0;
  transform: translateY(30px);
  filter: blur(15px);
  transition: opacity 1s cubic-bezier(0.16, 1, 0.3, 1),
    transform 1s cubic-bezier(0.16, 1, 0.3, 1),
    filter 1s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: opacity, transform, filter;
}

/* When Javascript adds the 'visible' class, make the element 100% visible, snap it back to its original position, and remove the blur */
.reveal.visible,
.reveal-element.visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* Alternate animation starting point: prep element to fly in from the left side while slightly shrunken */
.reveal.from-left {
  transform: translateX(-40px) scale(0.9);
  filter: blur(15px);
}

/* Alternate animation starting point: prep element to fly in from the right side while slightly shrunken */
.reveal.from-right {
  transform: translateX(40px) scale(0.9);
  filter: blur(15px);
}

/* Apply the final visible state for left/right flying elements */
.reveal.from-left.visible,
.reveal.from-right.visible {
  transform: translateX(0) scale(1);
  filter: none;
}

/* Stagger animation start times so elements don't all pop in at once */
.reveal-delay-1,
.delay-1 {
  transition-delay: 0.08s;
}

.reveal-delay-2,
.delay-2 {
  transition-delay: 0.18s;
}

.reveal-delay-3,
.delay-3 {
  transition-delay: 0.3s;
}

.reveal-delay-4,
.delay-4 {
  transition-delay: 0.45s;
}

.reveal-delay-5 {
  transition-delay: 0.62s;
}

/* Trigger a 1.1-second animation called 'pageIn' when the page loads, and leave the page in the final state when done */
.page-fade-in {
  animation: pageIn 1.1s var(--ease-expo) forwards;
}

/* Trigger a 0.5-second animation called 'pageOut' when navigating away */
.page-fade-out {
  animation: pageOut 0.5s var(--ease-in) forwards !important;
}

/* Define the exact math for the 'pageIn' animation: start dark, blurry, and small, then scale up and clear up */
@keyframes pageIn {
  from {
    opacity: 0;
    filter: blur(24px) brightness(0.2);
    transform: scale(0.94);
  }

  to {
    opacity: 1;
    filter: none;
    transform: scale(1);
  }
}

/* Define the exact math for the 'pageOut' animation: fade out, blur, and scale up slightly */
@keyframes pageOut {
  to {
    opacity: 0;
    filter: blur(22px);
    transform: scale(1.05);
  }
}

/* Create a 2-pixel tall line glued to the very top left of the screen. Paint it a cyan-to-gold gradient. JavaScript will change the 'width' percentage to match how far down the user has scrolled */
#scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  z-index: 9999;
  background: linear-gradient(90deg, var(--c-cyan), var(--c-gold));
  box-shadow: 0 0 10px var(--c-gold);
  width: 0%;
  transition: width 0.1s linear;
}

/* Glue the header to the top of the screen (sticky) so it stops when it hits the roof. Make it full width and put it on a high z-index so it sits above everything else */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  width: 100%;
  max-width: 100%;
  padding: clamp(1rem, 2vw, 1.6rem) 0;
  margin: 0 auto;
  border: 1px solid transparent;
  transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

/* When the user scrolls down, Javascript adds this class to shrink the header to 88% width, round the edges like a pill, blur the background behind it (glass effect), and add a glowing drop shadow */
.site-header.header-scrolled {
  background: rgba(3, 5, 8, 0.85);
  backdrop-filter: var(--blur-md);
  -webkit-backdrop-filter: var(--blur-md);
  padding: 0.65rem 0;
  width: 88%;
  max-width: 1040px;
  margin-top: 15px;
  border-radius: var(--radius-xl);
  border: 1px solid var(--c-border-hi);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.85), 0 0 16px var(--c-gold-glow);
}

/* Center the navigation stuff inside the header, limit its width to 1200px, and push the logo left and links right using space-between */
.nav-container {
  width: min(90%, 1200px);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: width 0.4s ease;
}

/* Group the logo image and title text together side-by-side using flexbox */
.logo-link {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  text-decoration: none;
  color: var(--c-text);
  outline: none;
}

/* Accessibility: draw a gold box around the logo if someone tabs to it with a keyboard */
.logo-link:focus-visible {
  outline: 2px solid var(--c-gold);
  outline-offset: 6px;
  border-radius: 6px;
}

/* Set the logo image height, keep its proportions, and add a fake glowing shadow behind the PNG shape */
.nav-logo {
  height: 46px;
  width: auto;
  object-fit: contain;
  filter: drop-shadow(0 0 8px var(--c-gold-glow));
  transition: height 0.4s cubic-bezier(0.16, 1, 0.3, 1), filter 0.4s ease, transform 0.4s ease;
}

/* When hovering the logo, blow it up 5% and make the gold glow massive */
.nav-logo:hover {
  filter: drop-shadow(0 0 18px rgba(212, 175, 55, 0.75)) brightness(1.1);
  transform: scale(1.05);
}

/* When the header shrinks from scrolling down, shrink the logo image to match */
.site-header.header-scrolled .nav-logo {
  height: 32px;
}

/* Style the text next to the logo with the custom font and bold it */
.site-title {
  font-family: var(--font-heading);
  font-size: clamp(1rem, 1.4vw, 1.45rem);
  font-weight: 700;
  letter-spacing: 0.3px;
  transition: font-size 0.4s ease;
}

/* When the header shrinks, shrink the title text slightly */
.site-header.header-scrolled .site-title {
  font-size: clamp(0.9rem, 1.2vw, 1.2rem);
}

/* Remove bullets from the navigation list and lay the links out horizontally in a row */
.main-nav ul {
  list-style: none;
  display: flex;
  gap: clamp(1rem, 2.5vw, 2rem);
  transition: gap 0.4s ease;
}

/* When the header shrinks, push the links closer together */
.site-header.header-scrolled .main-nav ul {
  gap: clamp(0.8rem, 2vw, 1.5rem);
}

/* Style the navigation links with uppercase letters, tracking spacing, and a tiny bit of padding at the bottom to make room for the hover underline */
.main-nav a {
  color: var(--c-muted);
  text-decoration: none;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  position: relative;
  padding-bottom: 3px;
  transition: color 0.3s ease;
  outline: none;
}

/* Accessibility: draw a gold box around the links if someone tabs to them with a keyboard */
.main-nav a:focus-visible {
  outline: 2px solid var(--c-gold);
  outline-offset: 5px;
  border-radius: 3px;
}

/* Inject an invisible line right below the link text. Set its width to 0 pixels. This sets up the hover animation */
.main-nav a::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 1.5px;
  background: var(--c-gold);
  box-shadow: 0 0 6px var(--c-gold);
  transition: width 0.36s var(--ease-expo);
}

/* Change link text to white when hovered */
.main-nav a:hover {
  color: var(--c-text);
}

/* When hovered, or when marked as the active page, change the invisible line's width from 0% to 100% so it animates drawing a line outwards from the center */
.main-nav a:hover::after,
.main-nav a.active::after {
  width: 100%;
}

/* Make the text white if it's the current active page */
.main-nav a.active {
  color: var(--c-text);
}

/* Completely hide the mobile hamburger menu button on desktop screens */
.nav-toggle {
  display: none;
  background: transparent;
  border: 1px solid var(--c-border-hi);
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  color: var(--c-text);
  font-size: 1.1rem;
  cursor: pointer;
}

/* Mobile Breakpoint: When the screen drops below 720px width, kill the horizontal layout and activate mobile styles */
@media (max-width: 720px) {
  /* Turn the hamburger menu button back on */
  .nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* Hide the main navigation links, rip them out of the normal layout, and prep them to drop down from the header later */
  .main-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: var(--sp-md);
    background: rgba(3, 5, 8, 0.97);
    backdrop-filter: var(--blur-md);
    border-bottom: 1px solid var(--c-border);
  }

  /* When Javascript adds the 'open' class to the nav, unhide it */
  .main-nav.open {
    display: block;
  }

  /* Change the flex layout from a horizontal row to a vertical column stacked list */
  .main-nav ul {
    flex-direction: column;
    gap: var(--sp-sm);
  }
}

/* Glue the back-to-top button to the bottom right corner of the screen. Make it a circle, add a glass blur effect behind it, and push it down 16 pixels while dropping its opacity to 0 so it's invisible by default */
#back-to-top {
  position: fixed;
  bottom: clamp(1.5rem, 3vw, 2.5rem);
  right: clamp(1.5rem, 3vw, 2.5rem);
  z-index: 998;
  width: 48px;
  height: 48px;
  background: rgba(14, 18, 30, 0.7);
  backdrop-filter: var(--blur-md);
  -webkit-backdrop-filter: var(--blur-md);
  border: 1px solid var(--c-border-gold);
  border-radius: 50%;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.6), 0 0 14px var(--c-gold-glow);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transform: translateY(16px) scale(0.85);
  pointer-events: none;
  transition: opacity 0.45s var(--ease-expo), transform 0.45s var(--ease-expo), box-shadow 0.3s ease;
  color: var(--c-gold);
  font-size: 1.1rem;
}

/* When Javascript detects scrolling and adds the 'visible' class, fade the button to 100% opacity, pop it back to its normal position, and enable clicking */
#back-to-top.visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* On hover, blow up the shadow and change the background color slightly */
#back-to-top:hover {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.8), 0 0 26px var(--c-gold-glow);
  border-color: var(--c-gold);
  background: rgba(20, 26, 42, 0.85);
}

/* Size and color the SVG arrow icon inside the button */
#back-to-top svg {
  width: 18px;
  height: 18px;
  stroke: var(--c-gold);
  stroke-width: 2.2;
  fill: none;
}

/* Setup the massive home page intro section. Force it to be exactly 100% of the screen height and use flexbox to trap everything perfectly in the center */
.hero-section {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: var(--sp-xl) clamp(1rem, 5vw, 3rem);
  position: relative;
  overflow: hidden;
}

/* Dump massive background text behind the hero content. Center it exactly using absolute positioning and translate math, and set pointer-events to none so the mouse clicks right through it */
.hero-watermark {
  position: absolute;
  font-size: clamp(14vw, 22vw, 30vw);
  font-weight: 900;
  font-family: var(--font-heading);
  color: rgba(212, 175, 55, 0.028);
  pointer-events: none;
  user-select: none;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

/* Style the tiny gold kicker text that sits above the main heading. Use flexbox to align it horizontally */
.hero-kicker {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--c-gold);
  margin-bottom: var(--sp-sm);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Inject physical 28-pixel lines on the left and right sides of the kicker text using pseudo-elements */
.hero-kicker::before,
.hero-kicker::after {
  content: '';
  display: block;
  width: 28px;
  height: 1px;
  background: var(--c-gold);
  opacity: 0.6;
}

/* Style the massive main title. Lock its max width to 14 characters so it automatically wraps lines at the perfect spot */
.hero-section h1 {
  font-family: var(--font-heading);
  font-size: var(--fs-display);
  line-height: 1.04;
  letter-spacing: -0.025em;
  max-width: 14ch;
  margin-bottom: var(--sp-md);
}

/* Style the paragraph below the title. Lock its width to 52 characters to keep the line length comfortable for reading */
.hero-section>p {
  color: var(--c-muted);
  font-size: var(--fs-hero-sub);
  max-width: 52ch;
  line-height: 1.75;
}

/* Define the wrapper for grid areas, limiting the width to 1140px and centering it horizontally */
.bento-section {
  padding: 0 clamp(1rem, 3vw, 2rem) var(--sp-xl);
  max-width: 1140px;
  margin: 0 auto;
}

/* Center the section title text */
.bento-header {
  text-align: center;
  margin-bottom: var(--sp-lg);
}

/* Apply specific fonts to the bento heading */
.bento-header h2 {
  font-family: var(--font-heading);
  font-size: var(--fs-h2);
  margin-bottom: var(--sp-xs);
}

/* Apply muted color to the bento sub-paragraph */
.bento-header p {
  color: var(--c-muted);
  font-size: var(--fs-body);
}

/* Build a complex CSS Grid layout with 4 columns and 2 rows. Name the areas like puzzle pieces so we can drop specific cards into specific slots */
.content-link-grid {
  display: grid;
  gap: clamp(0.65rem, 1.2vw, 1.1rem);
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(2, clamp(190px, 24vw, 275px));
  grid-template-areas:
    "feat feat mid  mid"
    "feat feat sm1  sm2";
}

/* Force the 1st card into the 'feat' area (takes up 2 rows and 2 columns) */
.content-link-tile:nth-child(1) {
  grid-area: feat;
}

/* Force the 2nd card into the 'mid' area (takes up 1 row, 2 columns) */
.content-link-tile:nth-child(2) {
  grid-area: mid;
}

/* Force the 3rd card into the 'sm1' area (takes up 1 row, 1 column) */
.content-link-tile:nth-child(3) {
  grid-area: sm1;
}

/* Force the 4th card into the 'sm2' area (takes up 1 row, 1 column) */
.content-link-tile:nth-child(4) {
  grid-area: sm2;
}

/* Tablet Breakpoint: Redraw the puzzle pieces for screens under 900px so cards stack differently */
@media (max-width: 900px) {
  .content-link-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: auto;
    grid-template-areas:
      "feat feat"
      "mid  mid"
      "sm1  sm2";
  }
}

/* Mobile Breakpoint: Destroy the grid structure entirely and stack all cards vertically in a single column */
@media (max-width: 560px) {
  .content-link-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "feat" "mid" "sm1" "sm2";
  }
}

/* Base style for the grid cards. Setup variables for mouse tracking, add a glass blur background, push content to the bottom using flexbox, and hide anything that spills out */
.content-link-tile {
  --tx: 50%;
  --ty: 50%;
  background: var(--c-surface-2);
  backdrop-filter: var(--blur-sm);
  -webkit-backdrop-filter: var(--blur-sm);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: clamp(1.2rem, 2.5vw, 2rem);
  text-decoration: none;
  color: var(--c-text);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  position: relative;
  overflow: hidden;
  transition: transform 0.45s var(--ease-expo), border-color 0.3s, box-shadow 0.35s;
  outline: none;
}

/* Inject an invisible gold gradient line inside the very top of the card. This will animate on hover */
.content-link-tile::before {
  content: '';
  position: absolute;
  top: 0;
  left: 10%;
  right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--c-gold), transparent);
  opacity: 0.25;
  transition: opacity 0.35s, left 0.35s, right 0.35s;
}

/* Inject an invisible radial gradient layer over the entire card. The center of this circle is mapped to the tx and ty variables so Javascript can make it follow the mouse */
.content-link-tile::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at var(--tx) var(--ty),
      rgba(212, 175, 55, 0.13) 0%,
      rgba(212, 175, 55, 0.04) 40%,
      transparent 70%);
  opacity: 0;
  transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
  border-radius: inherit;
}

/* When the card is hovered, pop it up 5 pixels, make the border gold, and add a heavy shadow */
.content-link-tile:hover,
.content-link-tile:focus-visible {
  transform: translateY(-5px) scale(1.012);
  border-color: var(--c-border-gold);
  box-shadow: var(--shadow-hover);
}

/* Make the mouse-tracking radial gradient visible on hover */
.content-link-tile:hover::after,
.content-link-tile:focus-visible::after {
  opacity: 1;
}

/* Animate the invisible top line to stretch out wider and become opaque on hover */
.content-link-tile:hover::before,
.content-link-tile:focus-visible::before {
  opacity: 0.9;
  left: 5%;
  right: 5%;
}

/* Accessibility: draw a gold box around the card if navigating by keyboard */
.content-link-tile:focus-visible {
  outline: 2px solid var(--c-gold);
  outline-offset: 3px;
}

/* Draw a custom grid-paper background pattern specifically for the first 'feat' card using repeating linear gradients */
.content-link-tile:nth-child(1) {
  background:
    linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
    repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(255, 255, 255, 0.018) 40px),
    repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(255, 255, 255, 0.018) 40px),
    var(--c-surface-2);
}

/* Style the heading inside the grid cards */
.content-link-tile h3 {
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  margin-bottom: var(--sp-xs);
  line-height: 1.2;
}

/* Style the paragraph inside the grid cards */
.content-link-tile p {
  font-size: var(--fs-body);
  color: var(--c-muted);
  line-height: 1.6;
  margin-bottom: var(--sp-sm);
}

/* Style the tiny gold arrow link at the bottom of the card and setup transitions for the gap distance between the text and arrow */
.tile-arrow {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--c-gold);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: gap 0.3s var(--ease-expo), letter-spacing 0.3s ease;
}

/* When the card is hovered, push the arrow further away from the text by increasing the gap */
.content-link-tile:hover .tile-arrow {
  gap: 0.65rem;
  letter-spacing: 2.5px;
}

/* Setup a standard flexbox grid to hold normal cards. Use flex-wrap so they drop to the next line if the screen gets too small */
.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 2vw, 1.75rem);
  justify-content: center;
  padding: var(--sp-xl) clamp(1rem, 4vw, 2rem);
}

/* Basic styling for normal cards: glass background, rounded corners, hidden overflow, and transition settings */
.card {
  background: var(--c-surface-2);
  backdrop-filter: var(--blur-sm);
  -webkit-backdrop-filter: var(--blur-sm);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  transition: transform 0.45s var(--ease-expo), border-color 0.3s, box-shadow 0.35s;
  position: relative;
  overflow: hidden;
}

/* Inject an invisible gold gradient line inside the very top of the standard card */
.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 10%;
  right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--c-gold), transparent);
  opacity: 0.3;
  transition: opacity 0.35s;
}

/* On hover, tint the border gold and add a heavy shadow */
.card:hover {
  border-color: rgba(212, 175, 55, 0.4);
  box-shadow: var(--shadow-hover);
}

/* On hover, make the invisible top gold line visible */
.card:hover::before {
  opacity: 1;
}

/* Add specific padding to cards marked as padded, and clamp their width so they don't grow too fat on huge screens or too skinny on phones */
.card.padded {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  width: clamp(280px, 30vw, 370px);
}

/* Force images inside padded cards to be exactly 200px tall and crop the edges automatically using object-fit cover to prevent stretching */
.card.padded img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  margin-bottom: var(--sp-md);
  border: 1px solid var(--c-border);
  transition: filter 0.4s ease, transform 0.5s var(--ease-expo);
}

/* On hover, physically scale the image up by 3% and increase its brightness and contrast */
.card:hover img {
  transform: scale(1.03);
  filter: brightness(1.08) contrast(1.04);
}

/* Typography settings for card headers */
.card.padded h3 {
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  margin-bottom: var(--sp-sm);
}

/* Typography settings for card paragraphs */
.card.padded p {
  font-size: var(--fs-body);
  line-height: 1.75;
  color: var(--c-muted);
}

/* If a card is using 3D tilt javascript, turn off mouse interactions for its child text/images so the Javascript math calculating the mouse position on the raw card doesn't glitch */
.tilt-card img,
.tilt-card h3,
.tilt-card p,
.tilt-card ul {
  pointer-events: none;
}

/* Remove default browser bullets for specific mission lists */
.mission-list {
  list-style: none;
  margin-top: var(--sp-sm);
  padding: 0;
}

/* Indent the list items to make room for custom bullet icons */
.mission-list li {
  position: relative;
  padding-left: 1.1rem;
  margin-bottom: 0.5rem;
  font-size: var(--fs-body);
  color: var(--c-muted);
  line-height: 1.6;
}

/* Inject a gold chevron arrow icon exactly at the left edge of each list item to replace standard bullets */
.mission-list li::before {
  content: '›';
  position: absolute;
  left: 0;
  color: var(--c-gold);
  font-weight: 700;
}

/* Build a custom button. Setup for the magnetic hover effect by hiding overflow so the expanding circle doesn't bleed out of the button shape */
.magnetic-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.65rem, 1.4vw, 0.9rem) clamp(1.4rem, 2.8vw, 2rem);
  background: transparent;
  color: var(--c-text);
  border: 1px solid var(--c-border-gold);
  border-radius: 50px;
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  overflow: hidden;
  transition: color 0.35s, border-color 0.35s, box-shadow 0.35s;
  outline: none;
}

/* Elevate the text physically over the hidden background animation using z-index */
.magnetic-btn .btn-text {
  position: relative;
  z-index: 2;
  pointer-events: none;
  transition: transform 0.28s var(--ease-expo);
}

/* Inject a hidden gold circle perfectly centered inside the button and shrink its size down to 0 using scale(0). This is the circle that will explode outwards on hover */
.magnetic-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 250px;
  height: 250px;
  background: radial-gradient(circle, var(--c-gold) 0%, transparent 65%);
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.5s var(--ease-expo);
  z-index: 0;
  border-radius: 50%;
  opacity: 0.88;
}

/* On hover, change the button border to solid gold, the text to black, and add a heavy gold glow to the whole box */
.magnetic-btn:hover {
  color: #000;
  border-color: var(--c-gold);
  box-shadow: 0 0 26px var(--c-gold-glow);
}

/* On hover, blow up the hidden gold circle inside the button so it fills the entire button shape */
.magnetic-btn:hover::before {
  transform: translate(-50%, -50%) scale(1.15);
}

/* Accessibility: draw a white box around the button if someone tabs to it with a keyboard */
.magnetic-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 4px;
}

/* Base styles for the image gallery squares. Hide overflow to trap the image zoom effect inside the border */
.gallery-item {
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: all 0.45s var(--ease-expo);
}

/* On hover, pop the whole square up 7 pixels and scale it up slightly */
.gallery-item:hover {
  border-color: var(--c-border-gold);
  transform: translateY(-7px) scale(1.015);
  box-shadow: var(--shadow-hover);
}

/* Pin the title text to the bottom of the image using absolute positioning and draw a black gradient behind it so white text is readable against bright images. Start slightly faded */
.item-label {
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.95));
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 2rem 1rem 0.85rem;
  font-weight: 600;
  color: #fff;
  text-align: center;
  opacity: 0.85;
  transition: opacity 0.3s;
}

/* Turn text to 100% opacity on hover */
.gallery-item:hover .item-label {
  opacity: 1;
}

/* Create an invisible dark screen that covers the entire browser window to lock out interactions behind the popup modal. Set opacity 0 and kill pointer events so it's disabled by default */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: var(--blur-md);
  -webkit-backdrop-filter: var(--blur-md);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 3000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s;
}

/* When Javascript fires the 'active' class, fade in the dark screen and enable mouse clicks on it to trap the user */
.modal-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

/* Build the actual popup window. Push it down 24 pixels and shrink it slightly so it can animate springing upwards when opened */
.modal-content {
  background: var(--c-surface-1);
  border: 1px solid var(--c-border-gold);
  border-radius: var(--radius-lg);
  width: min(92%, 750px);
  max-height: 90vh;
  overflow-y: auto;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  transform: scale(0.94) translateY(24px);
  transition: transform 0.5s var(--ease-expo);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.9), 0 0 28px var(--c-gold-glow);
}

/* When Javascript fires the active class on the parent, animate the popup to full scale and snap it exactly to center */
.modal-overlay.active .modal-content {
  transform: scale(1) translateY(0);
}

/* Build the specific action cards for Student 2's simulator. Setup relative positioning to trap the click effects */
.ais-action-card {
  background: var(--c-surface-3);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.2rem, 2vw, 1.75rem);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform 0.4s var(--ease-expo), border-color 0.3s, box-shadow 0.3s;
  outline: none;
}

/* Inject an invisible gold glow at the exact bottom center of the card. This will fire when the user clicks to select the action */
.ais-action-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 100%, rgba(212, 175, 55, 0.12), transparent 70%);
  opacity: 0;
  transition: opacity 0.35s;
}

/* When Javascript detects a click and applies the 'selected' class, highlight the border, add heavy glow, and physically lock the card 4 pixels higher */
.ais-action-card.selected {
  border-color: var(--c-border-gold);
  box-shadow: 0 0 22px var(--c-gold-glow), 0 8px 24px rgba(0, 0, 0, 0.5);
  transform: translateY(-4px);
}

/* Turn on the hidden bottom glow effect when the card is selected */
.ais-action-card.selected::after {
  opacity: 1;
}

/* If the card is hovered BUT NOT clicked yet, give it a tiny 3-pixel bump to show it's clickable */
.ais-action-card:hover:not(.selected) {
  border-color: var(--c-border);
  transform: translateY(-3px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

/* Accessibility: draw a gold box around the card if navigating by keyboard */
.ais-action-card:focus-visible {
  outline: 2px solid var(--c-gold);
  outline-offset: 4px;
}

/* Setup the global bottom footer block. Force it to stick to the bottom of the page even if there's no content using margin-top: auto */
.site-footer {
  background: rgba(2, 3, 6, 0.99);
  backdrop-filter: var(--blur-sm);
  border-top: 1px solid var(--c-border);
  padding: var(--sp-xl) 0 var(--sp-md);
  margin-top: auto;
  color: var(--c-muted);
}

/* Center the footer content, limit its width to 1200px, and use flexbox to space the columns out. Wrap them onto new lines for mobile screens */
.footer-container {
  width: min(90%, 1200px);
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-lg);
  padding-bottom: var(--sp-lg);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

/* Typography styles for the footer column titles */
.footer-container h3 {
  font-family: var(--font-heading);
  color: var(--c-text);
  margin-bottom: var(--sp-sm);
  font-size: 1.15rem;
}

/* Typography styles for the student data block */
.student-info p {
  margin-bottom: 0.45rem;
  font-size: var(--fs-body);
  line-height: 1.6;
}

/* Remove default bullets from footer lists */
.footer-links ul {
  list-style: none;
}

/* Add space between footer list items */
.footer-links li {
  margin-bottom: 0.65rem;
}

/* Set link colors and prep them for hover animations */
.footer-links a {
  color: var(--c-muted);
  text-decoration: none;
  font-size: var(--fs-body);
  transition: color 0.25s, letter-spacing 0.25s;
  outline: none;
}

/* On hover, paint the links gold and stretch the text slightly by increasing letter tracking */
.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--c-gold);
  letter-spacing: 0.5px;
}

/* Center the tiny copyright text at the absolute bottom and fade its opacity */
.footer-bottom {
  text-align: center;
  padding-top: var(--sp-md);
  font-size: 0.8rem;
  opacity: 0.35;
}

/* Set the window frame for parallax images. The image inside will scroll at a different speed than the frame itself. Hide anything that spills out */
.parallax-img-container {
  width: 100%;
  height: clamp(240px, 32vw, 390px);
  overflow: hidden;
  border-radius: var(--radius-md);
  border: 1px solid var(--c-border);
  margin: var(--sp-md) 0;
  box-shadow: var(--shadow-card);
}

/* Force the actual parallax image to be 130% taller than its container frame and shift it up. Javascript will move this Y-axis math as the user scrolls to create the 3D effect */
.parallax-img-target {
  width: 100%;
  height: 130%;
  object-fit: cover;
  transform: translateY(-15%);
  will-change: transform;
}

/* Override rules for the popup modal image to force it to show the entire picture without cropping, maxing out at 42% of the screen height */
#modalImageTarget {
  height: auto !important;
  max-height: 42vh;
  object-fit: contain !important;
  background: rgba(0, 0, 0, 0.45);
}

.feedback-bg {
    position: relative;
    background:
        radial-gradient(circle at 12% 18%, rgba(255, 215, 120, 0.14), transparent 20%),
        radial-gradient(circle at 88% 20%, rgba(88, 224, 255, 0.12), transparent 18%),
        radial-gradient(circle at 50% 78%, rgba(255, 215, 120, 0.08), transparent 24%),
        linear-gradient(180deg, #050910 0%, #08111d 50%, #050910 100%);
}

.feedback-bg::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -1;
    background:
        linear-gradient(135deg, rgba(255, 215, 120, 0.06) 0%, transparent 32%),
        linear-gradient(315deg, rgba(88, 224, 255, 0.06) 0%, transparent 30%);
    clip-path: polygon(8% 8%, 28% 18%, 18% 42%, 4% 34%);
}

.feedback-bg::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -1;
    background:
        linear-gradient(225deg, rgba(255, 215, 120, 0.05) 0%, transparent 28%),
        linear-gradient(45deg, rgba(88, 224, 255, 0.05) 0%, transparent 24%);
    clip-path: polygon(72% 10%, 94% 18%, 86% 40%, 66% 28%);
}



/* AIS Dynamic Visual State */
.ais-visual-state {
    position: fixed;
    inset: 0;
    z-index: -1;
    background-color: #030508; 
}

.state-vid {
    position: absolute; /* Stack them on top of each other */
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0; /* Completely hidden by default */
    transition: opacity 0.8s ease-in-out; /* Smooth crossfade */
    pointer-events: none;
}

/* Only the active video shows up */
.state-vid.active {
    opacity: 0.4; 
}

body.square-bg {
  position: relative;
}

body.square-bg::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background:
    linear-gradient(135deg, rgba(255, 215, 120, 0.06) 0%, transparent 32%),
    linear-gradient(315deg, rgba(88, 224, 255, 0.06) 0%, transparent 30%);
  clip-path: polygon(8% 8%, 28% 18%, 18% 42%, 4% 34%);
  opacity: 0.9;
}

body.square-bg .main-content::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background:
    linear-gradient(225deg, rgba(255, 215, 120, 0.05) 0%, transparent 28%),
    linear-gradient(45deg, rgba(88, 224, 255, 0.05) 0%, transparent 24%);
  clip-path: polygon(72% 10%, 94% 18%, 86% 40%, 66% 28%);
  opacity: 0.9;
}
