/* ==========================================================================
   Daniel Domentean, Grant Consulting — styles
   Palette: dark navy · ivory · champagne gold
   ========================================================================== */

@font-face {
  font-family: "Cormorant Garamond";
  src: url("fonts/cormorant-garamond-latin.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Caveat";
  src: url("fonts/caveat-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --navy: #0b1a33;
  --navy-deep: #07122a;
  --navy-soft: #142a4f;
  --ivory: #f4eee0;
  --ivory-70: rgba(244, 238, 224, .72);
  --ivory-45: rgba(244, 238, 224, .45);
  --ivory-15: rgba(244, 238, 224, .15);
  --gold: #d6b672;
  --gold-deep: #b8954f;
  --champagne: #efdcb2;
  --red: #c9564d;

  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --hand: "Caveat", "Segoe Print", "Bradley Hand", cursive;

  --max: 1160px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  /* one continuous background: flat navy with a single soft gold glow in the hero area */
  background:
    radial-gradient(60vw 60vh at 85% 15%, rgba(214, 182, 114, .13), transparent 70%) top / 100% 100vh no-repeat,
    var(--navy);
  color: var(--ivory);
  font-family: var(--sans);
  font-size: clamp(1rem, .96rem + .25vw, 1.125rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 600;
  line-height: 1.08;
  margin: 0 0 1.1rem;
  letter-spacing: -.005em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.7rem, 1.9rem + 3.6vw, 5rem); }
h2 { font-size: clamp(2rem, 1.5rem + 1.6vw, 2.9rem); }
h3 { font-size: 1.25rem; font-weight: 700; margin-bottom: .6rem; }
p  { margin: 0 0 1.1rem; }
a  { color: inherit; }
em { color: var(--champagne); font-style: italic; }

.container {
  width: min(100% - 2 * var(--gutter), var(--max));
  margin-inline: auto;
}
.container.narrow { max-width: 640px; }

/* --- shared bits ----------------------------------------------------- */

.eyebrow {
  font-family: var(--sans);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 1.4rem;
  display: flex;
  align-items: center;
  gap: .9rem;
}
.eyebrow::before {
  content: "";
  width: 2rem;
  height: 1px;
  background: var(--gold);
  flex: none;
}

.btn {
  display: inline-block;
  padding: .95rem 1.7rem;
  background: var(--gold);
  color: var(--navy-deep);
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .04em;
  text-decoration: none;
  border-radius: 2px;
  transition: background .2s ease, transform .2s ease;
}
.btn:hover, .btn:focus-visible { background: var(--champagne); transform: translateY(-1px); }
.btn:focus-visible { outline: 2px solid var(--champagne); outline-offset: 3px; }

/* --- hero ------------------------------------------------------------ */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding-block: clamp(5rem, 12vh, 9rem);
}
.hero .container { max-width: 1100px; margin-inline: max(var(--gutter), (100% - var(--max)) / 2) auto; }
.hero h1 { margin-bottom: 1.6rem; white-space: nowrap; }
.hero .lede {
  max-width: 40rem;
  font-size: clamp(1.05rem, 1rem + .35vw, 1.3rem);
  color: var(--ivory-70);
  margin-bottom: 0;
}
.hero .eyebrow::before { display: none; }

/* --- story: split scrollytelling ------------------------------------- */

.story-wrap {
  --story-pad: clamp(4rem, 8vw, 7rem);
  padding-block: var(--story-pad) clamp(5rem, 10vw, 9rem);
}

/* Vertical drop of the text column while the page is still at the hero.
   Registered so it can transition (the text slides up once the story starts). */
@property --drop {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

@media (min-width: 900px) {
  /* Pull the grid up into the hero so the first sticky note ("Find a grant")
     shows in the hero's lower right. */
  .story-wrap {
    --lift: calc(20vh + 5rem);
    margin-top: calc(-1 * var(--lift));
    padding-top: 0;
  }

  /* Text column layout starts level with the top edge of the hero sticky
     (42/600 of the chart's viewBox; percentage padding resolves against the
     column width, exactly like the SVG scales). Visually it is dropped below the
     hero via a transform until the user starts scrolling or clicks the note, then
     slides up. Both columns end at the grid bottom, so the parallax (which
     aligns column bottoms) makes the last text section and the chart finish at
     roughly the same height. --py is the parallax offset written by script.js. */
  .story-text {
    padding-top: 7%;
    --py: 0px;
    transform: translate3d(0, calc(var(--py) + var(--drop)), 0);
    transition: --drop .9s cubic-bezier(.2, .7, .2, 1);
  }
  .js .story-text { --drop: calc(var(--lift) + var(--story-pad)); }
  .js.has-scrolled .story-text { --drop: 0px; }
  .story-chart {
    --py: 0px;
    transform: translate3d(0, var(--py), 0);
  }
  .story-text article { scroll-margin-top: clamp(3rem, 6vh, 5rem); }
}

.story {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(3rem, 6vw, 6rem);
  align-items: start;
}

.story-text { will-change: transform; }
.story-text article { max-width: 34rem; padding-block: clamp(2.25rem, 4vw, 3.5rem); }
.story-text article:first-child { padding-top: 0; }
.story-text article + article { border-top: 1px solid var(--ivory-15); }
.story-text p { color: var(--ivory-70); }

.split-list { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem 2rem; margin-top: 1.8rem; }
.split-list ul { list-style: none; margin: 0; padding: 0; }
.split-list li {
  position: relative;
  padding-left: 1.2rem;
  margin-bottom: .55rem;
  color: var(--ivory-70);
  font-size: .95rem;
  line-height: 1.5;
}
.split-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: .45rem;
  height: 1px;
  background: var(--gold);
}
.split-list div:first-child h3 { color: var(--champagne); }

.reasons { margin: 1.8rem 0 0; }
.reasons div + div { margin-top: 1.4rem; }
.reasons dt { font-family: var(--serif); font-size: 1.35rem; font-weight: 700; color: var(--champagne); margin-bottom: .25rem; }
.reasons dd { margin: 0; color: var(--ivory-70); font-size: .97rem; }

/* chart column */
.story-chart {
  position: relative;
  will-change: transform;
}
.chart { display: block; width: 100%; height: auto; overflow: visible; }

/* the first note doubles as the "how it works" link */
.note-link { cursor: pointer; outline: none; }
.note-link:hover .note rect:first-child,
.note-link:focus-visible .note rect:first-child { filter: url(#shadow-lift); }
.note-link:focus-visible .note rect:first-child { stroke: var(--champagne); stroke-width: 2; }

/* periodic jiggle on the first note to invite a click — a short wobble, then a
   pause. Stops once the story has started (scroll or click). The inner group's
   local origin is the note's centre, so rotate about it. */
.jiggle { transform-box: view-box; transform-origin: 0 0; }
html:not(.js) .note-link .jiggle,
.js:not(.has-scrolled) .note-link .note.is-in .jiggle {
  animation: jiggle 3.6s ease-in-out 1.4s infinite;
}
@keyframes jiggle {
  0%        { transform: none; }
  4%        { transform: rotate(-4deg) translateY(-3px); }
  8%        { transform: rotate(4deg)  translateY(-2px); }
  12%       { transform: rotate(-3deg) translateY(-1px); }
  16%       { transform: rotate(2deg); }
  20%, 100% { transform: none; }
}

/* sticky notes */
.note { transform-box: view-box; transform-origin: 0 0; }
.note rect { filter: url(#shadow); }
.note rect.strip { filter: none; fill: #000; opacity: .07; }
.note text {
  font-family: var(--hand);
  fill: var(--navy);
  text-anchor: middle;
  dominant-baseline: central;
  user-select: none;
}
.node rect:first-child { fill: url(#g-gold); }
.node text { font-size: 25px; font-weight: 600; }
.hero-sticky text { font-size: 30px; }
.node.small text { font-size: 22px; }
.q rect:first-child { fill: url(#g-ivory); }
.q text { font-size: 17px; font-weight: 500; }
.f rect:first-child { fill: url(#g-ash); }
.f text { font-size: 17px; font-weight: 500; fill: #2a2a2a; }

.or { font-family: var(--hand); font-size: 22px; fill: var(--ivory-70); text-anchor: middle; dominant-baseline: central; }

/* connections */
.link { fill: none; stroke: var(--ivory); stroke-opacity: .8; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.head { fill: none; stroke: var(--ivory); stroke-opacity: .85; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.red .link { stroke: var(--red); stroke-opacity: .9; stroke-width: 1.8; }
.xmark path { fill: none; stroke: var(--red); stroke-width: 2.6; stroke-linecap: round; }
.xmark { transform-box: view-box; transform-origin: 0 0; }

/* --- positioning + reveal states ------------------------------------- */

/* positions live in CSS custom properties so the same transform can animate */
.note, .xmark {
  transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg));
}

/* Hidden states only apply when JS is available (class added in <head>) */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .8s ease, transform .8s cubic-bezier(.2, .7, .2, 1);
}
.js .reveal.is-in { opacity: 1; transform: none; }

.js .note {
  opacity: 0;
  transform: translate(var(--x), var(--y)) rotate(calc(var(--r, 0deg) - 6deg)) scale(.82);
  transition: opacity .45s ease var(--d, 0s), transform .7s cubic-bezier(.2, .8, .2, 1.15) var(--d, 0s);
}
.js .note.is-in {
  opacity: 1;
  transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(1);
}

.hero-sticky { --x: 272px; --s: 1.16; }
.note.hero-sticky {
  transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(var(--s));
}
.js .note.hero-sticky {
  transform: translate(var(--x), var(--y)) rotate(calc(var(--r, 0deg) - 6deg)) scale(calc(.82 * var(--s)));
}
.js .note.hero-sticky.is-in {
  transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(var(--s));
}

.js .xmark {
  opacity: 0;
  transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(.4);
  transition: opacity .3s ease var(--d, 0s), transform .45s cubic-bezier(.2, .8, .2, 1.3) var(--d, 0s);
}
.js .xmark.is-in { opacity: 1; transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(1); }

.js .or { opacity: 0; transition: opacity .5s ease var(--d, 0s); }
.js .or.is-in { opacity: 1; }

.js .conn .link {
  opacity: 0;
  stroke-dasharray: var(--len, 1);
  stroke-dashoffset: var(--len, 1);
  transition: stroke-dashoffset 1.15s cubic-bezier(.4, 0, .3, 1) var(--d, 0s), opacity .2s ease var(--d, 0s);
}
.js .conn.is-in .link { opacity: 1; stroke-dashoffset: 0; }
.js .conn .head {
  opacity: 0;
  transition: opacity .3s ease calc(var(--d, 0s) + 1s);
}
.js .conn.is-in .head { opacity: 1; }

/* --- contact --------------------------------------------------------- */

.contact {
  position: relative;
  text-align: center;
  padding-block: clamp(6rem, 14vw, 11rem);
}
.contact::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: min(60%, 520px);
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: .7;
}
.contact .eyebrow { justify-content: center; }
.contact .eyebrow::before { display: none; }
.contact p { color: var(--ivory-70); }
.contact .btn { margin-top: .8rem; }
.contact .email { margin: 1.4rem 0 0; font-size: .95rem; color: var(--ivory-45); letter-spacing: .02em; }

/* --- footer ---------------------------------------------------------- */

footer {
  border-top: 1px solid var(--ivory-15);
  padding-block: 2rem;
  font-size: .85rem;
  color: var(--ivory-45);
}
footer .container { display: grid; gap: .5rem; grid-template-columns: auto 1fr auto; align-items: baseline; }
footer p { margin: 0; }
footer .brand { font-family: var(--serif); font-size: 1.1rem; color: var(--champagne); letter-spacing: .02em; }
footer .disclaimer { text-align: center; }
footer .copy { text-align: right; white-space: nowrap; }

/* --- responsive ------------------------------------------------------ */

@media (max-width: 899px) {
  .story { grid-template-columns: 1fr; }
  .story-text { position: relative; z-index: 1; }
  .story-text article {
    max-width: none;
    scroll-margin-top: clamp(5rem, 12vh, 7rem);
  }
  .story-chart, .story-text { transform: none !important; }

  /* leave room under the lede for the "Find a grant" sticky-as-button */
  .hero {
    position: relative;
    z-index: 1;
    pointer-events: none;
    align-content: start;
    padding-top: clamp(8rem, 18vh, 11rem);
    padding-bottom: clamp(8rem, 26vh, 12rem);
  }
  .hero .container { pointer-events: auto; }
  .hero h1 { white-space: normal; }
  .hero .eyebrow {
    font-size: .65rem;
    letter-spacing: .14em;
  }
  .hero-sticky { --x: 300px; }
  .contact, footer { position: relative; z-index: 1; }

  /* flowchart is a muted wallpaper — out of flow, no layout space.
     The first note stays full-opacity and clickable until the story starts. */
  .story-chart {
    position: fixed;
    inset: 0;
    z-index: 0;
    width: auto;
    height: auto;
    padding: 0;
    overflow: hidden;
    pointer-events: none;
    will-change: auto;
  }
  .story-chart .chart {
    --bg-y: 0px;
    position: absolute;
    left: 50%;
    top: 70vh;
    width: 100%;
    max-width: none;
    transform: translate3d(-50%, var(--bg-y), 0);
  }
  .story-chart .chart > [aria-hidden] { opacity: .18; }
  .story-chart .note-link {
    pointer-events: auto;
    transition: opacity .8s ease;
  }
  .js.has-scrolled .story-chart .note-link {
    opacity: .18;
    pointer-events: none;
  }
  .js.has-scrolled .story-chart {
    -webkit-mask-image: radial-gradient(ellipse 120% 90% at 70% 40%, #000 25%, transparent 72%);
    mask-image: radial-gradient(ellipse 120% 90% at 70% 40%, #000 25%, transparent 72%);
  }

  footer .container { grid-template-columns: 1fr; text-align: left; }
  footer .disclaimer, footer .copy { text-align: left; white-space: normal; }
}

@media (max-width: 560px) {
  .split-list { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .jiggle { animation: none !important; }
  .story-text { transition: none; }
  .story-chart .note-link { transition: none; }
  .js .reveal, .js .note, .js .xmark, .js .or, .js .conn .link, .js .conn .head {
    opacity: 1;
    transition: none;
  }
  .js .note { transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)); }
  .js .note.hero-sticky { transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)) scale(var(--s)); }
  .js .xmark { transform: translate(var(--x), var(--y)) rotate(var(--r, 0deg)); }
  .js .reveal { transform: none; }
  .js .conn .link { stroke-dasharray: none; stroke-dashoffset: 0; }
}
