/* ==========================================================================
   Components — header, buttons, form, projects, collage, footer
   ========================================================================== */

/* --- Site header --------------------------------------------------------- */

.site-header {
  position: relative;
  z-index: 20;
  background: var(--nn-white);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--nn-space-s);
  min-height: var(--nn-header-h);
}

.brand {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-decoration: none;
  color: var(--nn-ink);
}

.brand__mark {
  width: clamp(3.0625rem, 1.87rem + 4.75vw, 4.625rem); /* 49 → 74 */
  height: auto;
  aspect-ratio: 1;
}

.brand__name {
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-nav);
  line-height: var(--nn-lh-nav);
  letter-spacing: var(--nn-track-nav);
}

.site-nav ul {
  display: flex;
  gap: clamp(1rem, 3vw, 3.5rem);
  list-style: none;
  padding: 0;
}

.site-nav a {
  display: block;
  padding-block: 0.5rem;
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-nav);
  line-height: var(--nn-lh-nav);
  letter-spacing: var(--nn-track-nav);
  text-transform: uppercase;
  text-decoration: none;
  border-block-end: 2px solid transparent;
  transition: border-color var(--nn-transition);
}

.site-nav a:hover,
.site-nav a[aria-current="page"] { border-block-end-color: var(--nn-accent); }

/* Sub-pages invert the header: the Figma puts it on a gradient strip with white
   type, where the landing page's header sits on plain white above the hero. */
.site-header--invert {
  background: var(--nn-black) url("../img/web/header-gradient.webp") center / cover no-repeat;
  color: var(--nn-text-invert);
}

.site-header--invert .brand { color: inherit; }

/* Mint reads on the gradient where the periwinkle accent does not. */
.site-header--invert .site-nav a:hover,
.site-header--invert .site-nav a[aria-current="page"] {
  border-block-end-color: var(--nn-accent-alt);
}

/* Mobile menu toggle — hidden once the full nav fits. */
.nav-toggle {
  margin-inline-start: auto;
  display: grid;
  place-items: center;
  width: 2.875rem;
  height: 3rem;
  padding: 0;
  background: none;
  border: 0;
  color: var(--nn-accent-alt);
}

.nav-toggle svg { width: 2rem; height: auto; }
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

@media (max-width: 47.99rem) {
  .site-nav {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    display: none;
    padding: var(--nn-space-s) var(--nn-gutter) var(--nn-space-m);
    background: var(--nn-white);
    border-block-start: 2px solid var(--nn-accent-alt);
  }
  .site-nav[data-open] { display: block; }
  /* The dropdown panel is white on every page, so undo the inverted colour. */
  .site-header--invert .site-nav { color: var(--nn-ink); }
  .site-nav ul { flex-direction: column; gap: var(--nn-space-xs); }
}

@media (min-width: 48rem) {
  .nav-toggle { display: none; }
  .site-nav { margin-inline-start: auto; }
}

/* --- Buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3.8125rem;     /* 61px */
  min-width: 11.4375rem;     /* 183px */
  padding: 0.75rem 1.5rem;
  border: 0;
  border-radius: var(--nn-radius);
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-button);
  line-height: 1.4;
  letter-spacing: 0;
  text-align: center;
  text-decoration: none;
  transition: filter var(--nn-transition), transform var(--nn-transition);
}

.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--nn-accent);     color: var(--nn-accent-ink); }
.btn--alt     { background: var(--nn-accent-alt); color: var(--nn-accent-alt-ink); }

/* --- Contact form -------------------------------------------------------- */

.contact-form {
  width: min(29.375rem, 100%); /* 470px */
  margin-inline: auto;
  display: grid;
  gap: var(--nn-space-s);
  text-align: start;
}

.field { display: grid; gap: 0.5rem; }

.field label {
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-label);
  line-height: var(--nn-lh-tight);
  letter-spacing: var(--nn-track-wide);
  color: var(--nn-text-invert);
}

.field input,
.field textarea {
  width: 100%;
  padding: 0.625rem 0.875rem;
  background: var(--nn-white);
  color: var(--nn-ink);
  border: 0;
  border-radius: var(--nn-radius);
  letter-spacing: var(--nn-track-tight);
}

.field input  { min-height: 2.978rem; }  /* 47.64px */
.field textarea { min-height: 8.767rem; resize: vertical; } /* 140.27px */

.contact-form .btn { justify-self: center; margin-block-start: var(--nn-space-xs); }

/* An author `display` value outranks the UA stylesheet's [hidden] rule, so the
   form has to be hidden explicitly. Removing `hidden` from the markup is all it
   takes to restore it. */
.contact-form[hidden] { display: none; }

/* --- Project rows -------------------------------------------------------- */

.project {
  display: grid;
  gap: var(--nn-space-m);
  align-items: start;
}

.project + .project { margin-block-start: var(--nn-space-xl); }

.project__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 451 / 353;
  object-fit: cover;
}

.project__title {
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-title);
  line-height: var(--nn-lh-tight);
  letter-spacing: var(--nn-track-tight);
  margin-block-end: var(--nn-space-s);
}

.project__org {
  display: block;
  font-weight: 500;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-medium);
}

@media (min-width: 60rem) {
  .project {
    grid-template-columns: minmax(0, 28rem) minmax(0, 1fr);
    gap: var(--nn-space-l);
  }
}

/* --- Photo collage ------------------------------------------------------- */
/* A designed composition, not a grid: the pieces keep their exact relative
   positions by living in a fixed-aspect box and being placed in percentages,
   so the whole arrangement scales as one. */

.collage {
  position: relative;
  width: 100%;
  max-width: 90rem; /* 1440px — the design frame; percentages below assume it */
  margin-inline: auto;
  aspect-ratio: var(--collage-ratio, 402 / 617);
  margin-block: var(--nn-space-xl);
}

.collage img {
  position: absolute;
  width: var(--w);
  height: var(--h);
  left: var(--x);
  top: var(--y);
  object-fit: cover;
}

@media (min-width: 60rem) {
  .collage { --collage-ratio: 1440 / 577; }
}

/* --- Decorative art ------------------------------------------------------ */
/* Stars and moons are pure ornament: they carry no meaning, are hidden from
   assistive tech, and drop out on narrow screens where they would collide. */

.deco {
  position: absolute;
  pointer-events: none;
  user-select: none;
  z-index: 1;
}

@media (max-width: 47.99rem) {
  .deco[data-deco="desktop-only"] { display: none; }
}

/* A couple of pieces only have room once the viewport is wider than the content
   band. The container caps at 1240px and centres, so below roughly 1800px the
   right-hand margin is too narrow and the art crosses into the body copy. */
@media (max-width: 112.49rem) {
  .deco[data-deco="wide-only"] { display: none; }
}

/* --- Footer -------------------------------------------------------------- */

.site-footer {
  padding-block: var(--nn-section) var(--nn-space-xl);
  text-align: center;
}

/* Each logo carries its own dimensions in the Figma — heights vary from 62px to
   110px — so sizing them to a shared height distorts the wide ones and overflows
   the row. Instead each keeps its designed width, and one scale factor per row
   drives the whole set. The factor was checked against both frames: row 1 scales
   0.547–0.560 between mobile and desktop, row 2 scales 0.465–0.471, so a single
   value per row is faithful to within a pixel. */

.partners {
  /* "px per design px": 0.554 at 402, 1.0 at 1440. */
  --logo-unit: clamp(0.554px, 0.3813px + 0.04297vw, 1px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: calc(28.75 * var(--logo-unit));
  list-style: none;
  padding: 0;
}

.partners--funders {
  --logo-unit: clamp(0.467px, 0.2606px + 0.05135vw, 1px);
  gap: calc(30 * var(--logo-unit));
  margin-block-start: var(--nn-space-l);
}

/* The width goes on the list item, not the image: the <li> is the flex item, so
   sizing the image instead left its parent's width depending on the image while
   the image's own `max-width: 100%` depended on the parent — a cycle that
   collapsed them all to zero. */
.partners li {
  flex: 0 0 auto;
  width: calc(var(--logo-w) * var(--logo-unit));
}

/* Most logos link to the partner's site. The Figma has no hover state for
   these, so this is an invented one — kept deliberately quiet. */
.partners a {
  display: block;
  transition: opacity var(--nn-transition);
}

.partners a:hover { opacity: 0.65; }

.partners img {
  width: 100%;
  height: auto;
}

/* Widths straight from the Figma "Desktop - 1" frame. */
.partners [data-logo="ccube"]        { --logo-w: 103; }
.partners [data-logo="dansklive"]    { --logo-w: 103; }
.partners [data-logo="hafnarhaus"]   { --logo-w: 84; }
.partners [data-logo="hyperisland"]  { --logo-w: 191; }
.partners [data-logo="kfp"]          { --logo-w: 94; }
.partners [data-logo="nsf"]          { --logo-w: 83; }
.partners [data-logo="stpln"]        { --logo-w: 118; }
.partners [data-logo="studenterhus"] { --logo-w: 93; }
.partners [data-logo="turkis"]       { --logo-w: 95; }
.partners [data-logo="arvsfonden"]   { --logo-w: 226; }
.partners [data-logo="erasmus"]      { --logo-w: 270; }
.partners [data-logo="helsinki"]     { --logo-w: 136; }

.copyright {
  margin-block-start: var(--nn-space-xl);
  color: var(--nn-muted);
  line-height: var(--nn-lh-wide);
}

/* --- Contact CTA panel --------------------------------------------------- */
/* Shared by both pages; only the heading text differs. */

.cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: var(--nn-section);
  color: var(--nn-text-invert);
  text-align: center;
  background: var(--nn-black);
}

.cta__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cta__heading {
  font-family: var(--nn-font-display);
  font-weight: 700;
  font-variation-settings: "SEIS" var(--nn-seis), "wght" var(--nn-wght-bold);
  font-size: var(--nn-size-cta);
  line-height: var(--nn-lh-tight);
  letter-spacing: var(--nn-track-wide);
  text-wrap: balance;
}

.cta__sub {
  margin-block-start: var(--nn-space-xs);
  font-size: var(--nn-size-ctasub);
  line-height: var(--nn-lh-tight);
  letter-spacing: var(--nn-track-wide);
  text-wrap: balance;
}

.cta .contact-form { margin-block-start: var(--nn-space-l); }

/* The CTA's two stars. These belong here rather than in a page stylesheet — the
   panel is shared by every page, and when they lived in home.css the About page
   loaded the images with no offsets, so both stacked in the same corner. */
.cta .deco--star6 { left: 2%;  top: 8%;    width: clamp(4rem, 13vw, 13.97rem); rotate: 51.79deg; }
.cta .deco--star8 { right: 5%; bottom: 12%; width: clamp(3.5rem, 9vw, 8.125rem); }
.cta .cta__mailto { margin-block-start: var(--nn-space-l); }
