/* ==========================================================================
   Sections — layout only. Colors and sizes come from tokens.
   Order matches the document: chrome, hero, marquee, mission,
   awards, categories, veterans, audience, experience, partners,
   submit, team, info, footer.
   ========================================================================== */

/* --- preloader ---
   JS (Task 9) can dismiss this early via .is-done, but the preloader must
   never depend on JS to ESCAPE — a stub script, a blocked bundle or a slow
   connection must not trap the page behind a black screen forever. The
   keyframe below self-dismisses on a timer so JS is an optimisation, not
   a requirement. */
.preloader {
  position: fixed; inset: 0; z-index: var(--z-preload);
  display: grid; place-items: center;
  background: var(--surface-dark);
  transition: opacity var(--dur-base) var(--ease-out-expo), visibility var(--dur-base);
  animation: preloader-dismiss var(--dur-intro) var(--ease-out-expo) forwards;
}
@keyframes preloader-dismiss {
  0%, 60% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}
.preloader.is-done { opacity: 0; visibility: hidden; }
.preloader__count {
  font-family: var(--font-display);
  font-size: var(--step-7);
  font-weight: 400;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* --- nav ---
   mix-blend-mode lives on the brand mark and text links only, not on the
   .nav container itself — the container also holds the solid Submit pill,
   and blending that against scrolled-under content (e.g. the marquee)
   made it read as translucent/discolored instead of a clean, legible CTA. */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-nav);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-m);
  padding: var(--space-s) var(--gutter);
  color: var(--on-dark);
  /* mix-blend-mode difference was unreadable over bright festival photos.
     A real scrim that fades in once you leave the hero is honest and legible
     in both contexts. */
  background: linear-gradient(to bottom, var(--scrim-ink) 0%, transparent 100%);
  transition: transform var(--dur-base) var(--ease-out-expo),
              background var(--dur-base) var(--ease-out-expo),
              color var(--dur-base) var(--ease-out-expo);
}
.nav.is-stuck {
  /* translucent, not solid: the page keeps moving behind the bar. The blur
     is what keeps the links legible over whatever scrolls under them. */
  background: color-mix(in srgb, var(--paper-50) 78%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  backdrop-filter: blur(14px) saturate(1.1);
  color: var(--text);
  border-bottom: 1px solid var(--rule);
}

/* the mark is white art, so the stuck bar needs it inverted to black */
.nav.is-stuck .nav__brand img { filter: invert(1); }
.nav.is-hidden { transform: translateY(-110%); }
.nav__brand img {
  /* atlanta-logo-mark.webp is white artwork on transparency, which is right
     over the dark hero. NO mix-blend-mode here: difference made the stuck
     state invert the mark to black and then blend it against the cream bar,
     which resolves to exactly the cream colour — the logo vanished. */
  width: 3.5rem; height: 3.5rem;
}
.nav__links { display: none; gap: var(--space-m); }
.nav__links a {
  font-size: var(--step--1); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; text-decoration: none;
  color: currentColor;
  opacity: 0.92;
  transition: opacity var(--dur-fast) var(--ease-out-expo);
}
.nav__links a:hover { opacity: 1; }
@media (min-width: 60rem) { .nav__links { display: flex; } }

/* --- button --- */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-m);
  background: var(--accent-fill); color: var(--on-accent);
  font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  text-decoration: none; border: 0; border-radius: 999px;
  transition: background var(--dur-fast) var(--ease-out-expo),
              transform var(--dur-fast) var(--ease-out-expo);
}
.btn:hover { background: var(--accent-hover); }
.btn--sm { padding: var(--space-3xs) var(--space-s); font-size: var(--step--1); }
.btn--lg { padding: var(--space-s) var(--space-xl); font-size: var(--step-1); }

/* --- hero: clean. Festival photography and type. No filmstrips here —
   the strips are the section dividers; the hero is a single quiet statement,
   the way SFJAZZ leads with one full-bleed image. --- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-block: var(--space-3xl) var(--space-2xl);
  overflow: hidden;
  /* the hero keeps its own dark context inside a light page */
  background: var(--surface-dark);
  color: var(--on-dark);
  isolation: isolate;
}

/* three festival photographs, crossfading slowly. CSS only — this must work
   with no JavaScript at all. */
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__shot {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* These are 3:2 group shots in a much wider viewport, so a centre crop
     cuts the faces off at the top. Bias the crop upward to keep heads in. */
  object-position: center 28%;
  opacity: 0;
  animation: hero-cycle var(--dur-hero-cycle) linear infinite;
}
.hero__shot:nth-child(1) { animation-delay: calc(var(--dur-hero-cycle) * -0/3); }
.hero__shot:nth-child(2) { animation-delay: calc(var(--dur-hero-cycle) * -1/3); }
.hero__shot:nth-child(3) { animation-delay: calc(var(--dur-hero-cycle) * -2/3); }

@keyframes hero-cycle {
  0%   { opacity: 0; transform: scale(1.03); }
  6%   { opacity: 1; }
  30%  { opacity: 1; }
  38%  { opacity: 0; }
  100% { opacity: 0; transform: scale(1.08); }
}

/* the scrim: type gets a clean ground on the left, the room still reads on
   the right. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to right, var(--surface-dark) 0%, var(--scrim-ink) 48%, transparent 88%),
    linear-gradient(to top, var(--surface-dark) 4%, transparent 46%);
}


.hero__inner { position: relative; z-index: 3; }
.hero .eyebrow { color: var(--on-dark-muted); }
.hero__title {
  font-family: var(--font-display);
  font-size: var(--step-hero);
  line-height: 0.92;
  text-transform: uppercase;
  margin-block: var(--space-s) var(--space-m);
  color: var(--on-dark);
}
.hero__dates {
  font-family: var(--font-display);
  font-size: var(--step-1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--award-on-dark);
}
.hero__kicker {
  font-size: var(--step-2);
  line-height: 1.3;
  color: var(--on-dark-muted);
  margin-block: var(--space-m) var(--space-l);
  max-width: 26ch;
}

/* --- marquee --- */
.marquee {
  border-block: 1px solid var(--rule-dark);
  padding-block: var(--space-s);
  overflow: hidden;
  background: var(--surface-dark-raised);
}
.marquee__track {
  display: flex; align-items: center; gap: var(--space-m);
  width: max-content;
  will-change: transform;
}
.marquee__track span {
  font-family: var(--font-display);
  font-size: var(--step-2);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--award-on-dark);
  letter-spacing: 0.01em;
}

/* ==========================================================================
   SECTION HEADING RHYTHM — one treatment for every section
   Five sections were using a bare .display class that carries NO font-size,
   so they rendered at the browser's default h2 while others used
   .section__title at --step-5. Combined with the global margin reset, the
   eyebrow, heading and body sat flush against each other. This is what made
   the page read as unstyled even though every section had layout.
   ========================================================================== */

.section h2.display,
.section .section__title {
  font-family: var(--font-display);
  font-size: var(--step-5);
  line-height: 0.95;
  text-transform: uppercase;
  text-wrap: balance;
  margin-bottom: var(--space-m);
  max-width: 20ch;
}
.section .eyebrow { display: block; margin-bottom: var(--space-s); }
.section h2 + p,
.section .section__title + p { margin-top: 0; }
.section__head + * { margin-top: var(--space-2xl); }

/* the submit hook is centred and set slightly tighter than a section title */
.section h2.submit__hook { max-width: 22ch; margin-inline: auto; }

/* ==========================================================================
   SHARED RHYTHM
   One header pattern for every section. This is what was missing: headings
   sat flush against body copy and body copy ran the full window width, so
   nothing had proportion. Every section below uses .section__head.
   ========================================================================== */

.section__head { max-width: 46rem; margin-bottom: var(--space-2xl); }
.section__head .eyebrow { margin-bottom: var(--space-s); }
.section__title {
  font-family: var(--font-display);
  font-size: var(--step-5);
  line-height: 0.95;
  text-transform: uppercase;
  margin-bottom: var(--space-m);
}
.section__lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: var(--measure);
}
.section p { max-width: var(--measure); }
.section__head--center { margin-inline: auto; text-align: center; }
.section__head--center .section__lede { margin-inline: auto; }

/* --- mission --- */
/* no filmstrip between the hero and this section any more, so the copy
   starts higher and the page opens faster. */
.mission { padding-top: var(--space-xl); }
.mission__quote {
  font-family: var(--font-display);
  font-size: var(--step-6);
  line-height: 0.92;
  text-transform: uppercase;
  max-width: 18ch;
  margin-block: var(--space-m) var(--space-2xl);
}
.mission__grid { display: grid; gap: var(--space-2xl); align-items: center; }
@media (min-width: 62rem) {
  .mission__grid { grid-template-columns: 1.1fr 0.9fr; gap: var(--space-3xl); }
}
.mission__body { display: grid; gap: var(--space-m); max-width: var(--measure); color: var(--text-muted); }
.mission__award {
  margin: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-100);
}
.mission__award img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; }
.mission__figure { margin-top: var(--space-2xl); border-radius: var(--radius); overflow: hidden; }
.mission__figure img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }

/* --- awards: copy beside the rotating crystal --- */
.awards { position: relative; }
.awards__grid { position: relative; z-index: 1; display: grid; gap: var(--space-2xl); align-items: center; }
/* the statue is a supporting image beside a longer read now, not the
   centrepiece it was, so the copy takes the larger share */
@media (min-width: 62rem) { .awards__grid { grid-template-columns: 1.35fr 0.65fr; gap: var(--space-3xl); align-items: start; } }
/* the global margin reset means paragraphs sit flush unless a container
   supplies the rhythm — these were running into each other */
.awards__copy > p + p { margin-top: var(--space-m); }
.awards__copy p { color: var(--text-muted); }

.awards__copy .awards__lead {
  font-family: var(--font-display);
  font-size: var(--step-2);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-s);
}
.awards__copy > p.awards__lead + p { margin-top: 0; }
.awards__copy .awards__note {
  margin-top: var(--space-m);
  padding-left: var(--space-s);
  border-left: 2px solid var(--award);
  font-size: var(--step--1);
}
.awards__prizes {
  margin-top: var(--space-l);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--award);
  max-width: none;
}
.awards__stage {
  position: relative;
  aspect-ratio: 4 / 5;
  max-width: 22rem;
  margin-inline: auto;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  /* the statue is gilt on black — a dark plate is what lets it read, and it
     gives the section the focal contrast the light page otherwise lacks */
  background: var(--surface-dark);
}

.awards__image {
  width: 100%; height: 100%;
  /* contain, not cover: the statue is a tall portrait and cropping it to a
     square would cut her head or her plinth off. */
  object-fit: contain;
  padding: var(--space-m);
}

/* --- categories: a card per award, each with its own mark --- */
.categories__list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-s);
  padding: 0; margin: 0; list-style: none;
}
/* twelve categories, four across, three rows */
@media (min-width: 62rem) { .categories__list { grid-template-columns: repeat(4, 1fr); } }
.category {
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: var(--space-xs);
  height: 100%;
  padding: var(--space-m);
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  text-decoration: none;
  transition:
    border-color var(--dur-fast) var(--ease-out-expo),
    transform var(--dur-base) var(--ease-out-expo),
    background var(--dur-fast) var(--ease-out-expo);
}
/* Plain cards. No floating image on hover, no lift — the client wanted the
   twelve categories to just read as a list. A border and colour shift stay so
   the card is still visibly a link, and keyboard focus still lands somewhere
   you can see. */
.category:hover, .category:focus-visible {
  border-color: var(--accent);
}
.category__icon {
  width: clamp(3.5rem, 6vw, 5rem);
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
}
.category__index {
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2em;
  color: var(--text-muted);
}
.category__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.05;
  text-transform: uppercase;
  text-wrap: balance;
}
.category:hover .category__name, .category:focus-visible .category__name { color: var(--accent); }

/* --- veterans: gold-led, set apart from its neighbours --- */
.veterans { background: var(--paper-100); border-block: 1px solid var(--rule); }
.veterans__grid { display: grid; gap: var(--space-2xl); align-items: center; }
@media (min-width: 62rem) { .veterans__grid { grid-template-columns: 0.85fr 1.15fr; gap: var(--space-3xl); } }
.veterans__figure { border-radius: var(--radius); overflow: hidden; }
.veterans__figure img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.veterans__copy .section__title { color: var(--award); }
.veterans__rule {
  margin-top: var(--space-m);
  padding-left: var(--space-s);
  border-left: 2px solid var(--award);
  font-size: var(--step--1);
  color: var(--text-muted);
}

/* --- audience --- */
.audience__steps { display: grid; gap: var(--space-l); padding: 0; margin: 0; list-style: none; }
@media (min-width: 55rem) { .audience__steps { grid-template-columns: repeat(3, 1fr); } }
.audience__step { padding-top: var(--space-m); border-top: 2px solid var(--accent); }
.audience__num {
  display: block;
  font-size: var(--step--1); font-variant-numeric: tabular-nums;
  letter-spacing: 0.2em; color: var(--accent); margin-bottom: var(--space-2xs);
}
.audience__step h3 {
  font-family: var(--font-display); font-size: var(--step-2);
  text-transform: uppercase; margin-bottom: var(--space-xs);
}
.audience__step p { color: var(--text-muted); }

/* --- experience: a horizontal rail, never a vertical stack --- */
.experience__rail {
  display: flex; gap: var(--space-s);
  margin-top: var(--space-xl);
  padding-inline: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.experience__rail::-webkit-scrollbar { display: none; }
.rail__item {
  flex: 0 0 auto;
  width: clamp(13rem, 22vw, 20rem);
  margin: 0;
  scroll-snap-align: center;
  border-radius: var(--radius);
  overflow: hidden;
}
.rail__item img { width: 100%; height: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.rail__item:nth-child(4n) { width: clamp(17rem, 30vw, 27rem); }
.rail__item:nth-child(4n) img { aspect-ratio: 16 / 10; }
@media (max-width: 48rem) {
  .experience__rail {
    display: grid; grid-template-columns: 1fr 1fr;
    overflow-x: visible; gap: var(--space-2xs);
  }
  .rail__item, .rail__item:nth-child(4n) { width: auto; }
  .rail__item:nth-child(4n) img { aspect-ratio: 4 / 5; }
}

/* --- partners: Orlando is the parent, and carries the weight --- */
.partners__grid { display: grid; gap: var(--space-l); }
@media (min-width: 55rem) { .partners__grid { grid-template-columns: 1.25fr 1fr; align-items: start; } }
.partner {
  display: block; padding: var(--space-l);
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out-expo), transform var(--dur-base) var(--ease-out-expo);
}
.partner:hover, .partner:focus-visible { border-color: var(--award); transform: translateY(-4px); }
.partner img {
  /* both partner marks are black line art and vanish without a light plate */
  width: 100%; max-width: 20rem; height: auto;
  padding: var(--space-s);
  background: var(--paper-50);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-m);
}
.partner h3 { font-family: var(--font-display); font-size: var(--step-2); text-transform: uppercase; }
.partner p { color: var(--text-muted); margin-block: var(--space-2xs) var(--space-s); }
.partner__link { font-size: var(--step--1); letter-spacing: 0.14em; text-transform: uppercase; color: var(--award); }
.partner--parent { border-color: var(--award); }
.partner--parent h3 { font-size: var(--step-3); }

/* --- submit --- */
.submit { text-align: center; background: var(--paper-100); }
.submit .section__head { margin-inline: auto; text-align: center; }
.submit__hook { font-family: var(--font-display); font-size: var(--step-5); line-height: 0.95; text-transform: uppercase; max-width: 22ch; margin: var(--space-s) auto var(--space-m); }
.submit p { color: var(--text-muted); margin-inline: auto; }
.submit .btn { margin-top: var(--space-l); }
.submit__note { font-size: var(--step--1); margin-top: var(--space-l); opacity: 0.65; }

/* --- team --- */
.team__grid { display: grid; gap: var(--space-l); padding: 0; margin: 0; list-style: none; }
@media (min-width: 40rem) { .team__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .team__grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-l); } }
.team__member { padding-top: var(--space-m); border-top: 2px solid var(--accent); }
/* team is text only — the client removed the headshots */
.team__member h3 { font-family: var(--font-display); font-size: var(--step-1); text-transform: uppercase; }
.team__role { font-size: var(--step--1); letter-spacing: 0.14em; text-transform: uppercase; color: var(--award); margin-bottom: var(--space-xs); }
.team__member p { font-size: var(--step--1); color: var(--text-muted); }
.team__member a { color: var(--text-muted); text-decoration: none; word-break: break-word; }
.team__member a:hover { color: var(--accent); }

/* --- info --- */
.info { border-top: 1px solid var(--rule); }
.info__grid { display: grid; gap: var(--space-l); }
@media (min-width: 40rem) { .info__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .info__grid { grid-template-columns: repeat(4, 1fr); } }
.info__item h3 { margin-bottom: var(--space-2xs); }
.info__value { font-family: var(--font-display); font-size: var(--step-2); text-transform: uppercase; margin-bottom: var(--space-xs); }
.info__item p { font-size: var(--step--1); color: var(--text-muted); }
.info__item--pending .info__value { color: var(--award); }

/* --- footer --- */
.footer { padding-block: var(--space-2xl); border-top: 1px solid var(--rule-dark); background: var(--surface-dark); color: var(--on-dark); }
.footer__grid { display: grid; gap: var(--space-m); justify-items: start; }
@media (min-width: 55rem) { .footer__grid { grid-template-columns: auto 1fr auto; align-items: center; } }
.footer__logo { width: 4.5rem; height: 4.5rem; }
.footer__links { display: grid; gap: var(--space-2xs); }
.footer__links a { color: var(--on-dark-muted); text-decoration: none; font-size: var(--step--1); }
.footer__links a:hover { color: var(--accent-on-dark); }
.footer__legal { font-size: var(--step--1); color: var(--on-dark-muted); opacity: 0.6; }

/* ==========================================================================
   FILMSTRIP DIVIDER — the motif between every section
   Real filmstrip geometry: sprocket rails top and bottom, festival frames
   between them, scrolling. Decorative only; alternates direction.
   ========================================================================== */

.divider {
  --strip-h: clamp(5rem, 9vw, 7.5rem);
  --slant: -3.2deg;
  --rail: calc(var(--strip-h) * 0.17);
  --hole-w: 0.62rem;
  --hole-period: 1.55rem;
  position: relative;
  /* taller than the strip so the rotated ends never expose the page behind */
  height: calc(var(--strip-h) + 5.5rem);
  overflow: hidden;
  background: transparent;
}

/* the strip runs at an angle: low on the left, rising to the right */
.divider .filmstrip {
  position: absolute;
  left: -8%; width: 116%;
  top: 50%;
  height: var(--strip-h);
  transform: translateY(-50%) rotate(var(--slant));
  background: var(--surface-dark);
  border-block: 1px solid var(--rule-dark);
}
.divider--reverse { --slant: -3.2deg; }

/* the two perforated rails */
.divider .filmstrip::before,
.divider .filmstrip::after {
  content: "";
  position: absolute; left: 0; right: 0;
  height: var(--rail);
  z-index: 2;
  background-color: var(--surface-dark);
  background-image: repeating-linear-gradient(
    to right,
    var(--on-dark-muted) 0 var(--hole-w),
    transparent var(--hole-w) var(--hole-period)
  );
  background-position: center;
  background-size: auto calc(var(--rail) * 0.46);
  background-repeat: repeat-x;
  opacity: 0.85;
}
.divider .filmstrip::before { top: 0; }
.divider .filmstrip::after { bottom: 0; }

.divider .filmstrip__track {
  position: absolute;
  top: var(--rail); bottom: var(--rail);
  left: 0;
  display: flex;
  gap: 0.18rem;
  width: max-content;
  animation: filmstrip-scroll var(--dur-strip-slow) linear infinite;
  will-change: transform;
}
.divider--reverse .filmstrip__track { animation-direction: reverse; }

@keyframes filmstrip-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.divider .filmstrip__frame {
  flex: 0 0 auto;
  height: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.divider .filmstrip__frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.82;
}

@media (prefers-reduced-motion: reduce) {
  .divider .filmstrip__track { animation: none; }
  .marquee__track { animation: none; }
  /* the hero must not be left on a fully transparent keyframe: pin the first
     photograph visible and stop cycling. */
  .hero__shot { animation: none; opacity: 0; transform: none; }
  .hero__shot:nth-child(1) { opacity: 1; }
}

/* --- 404 --- */
.notfound { min-height: 70svh; display: grid; align-items: center; }
.notfound .section__title { margin-bottom: var(--space-m); }
.notfound a { color: var(--accent); }
