/* ---------- fonts ----------
   The heading font face.
*/
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 200 800;
  font-stretch: 75% 100%;
  src: url("/static/fonts/bricolage-grotesque-latin.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext carries š and ž, which we might use in loan words or names */
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 200 800;
  font-stretch: 75% 100%;
  src: url("/static/fonts/bricolage-grotesque-latin-ext.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- layer 1: palette ----------
   Inspiration: Tatooine / Jakku color scheme.
   - paper: #E9CCA4 bleached by two suns
   - ink: shadow under a dune
   - hero ground: desert sky in shadow (at 32%)

   Dark mode only reassigns which step fills which role. */
:root {
  /* sand — the warm half: paper, ink and every text tier */
  --sand-100: #F7F0E3;
  --sand-200: #E3D6C1;
  --sand-300: #BEB5A6;
  --sand-400: #95928B;
  --sand-600: #736550;
  --sand-700: #5C5040;
  --sand-900: #2B2318;

  /* gold — the accent, straight off the source swatch */
  --gold-300: #E5B072;
  --gold-400: #DBA05C;

  /* sky — the cool half: hero, news rail and the night ground */
  --sky-200: #BCC9D8;
  --sky-300: #94A8BF;
  --sky-600: #526884;
  --sky-800: #2C3846;
  --sky-900: #171E26;

  /* channel triplets, for the colors composited at several opacities rather
     than used flat — rgba() needs the channels spelled out. Neither has a flat
     use of its own: the scrim tint is #212A34 and the shadow tint #3A2A18. */
  --sky-850-rgb: 33, 42, 52;
  --sand-shadow-rgb: 58, 42, 24;
  --black-rgb: 0, 0, 0;
}

/* ---------- layer 2: roles ---------- */
:root {
  --paper: var(--sand-100);
  --ink: var(--sand-900);
  --ink-soft: var(--sand-700);
  --ink-faint: var(--sand-600);
  --rail-ink: var(--sky-600);
  --rule: var(--sand-200);
  --accent: var(--gold-400);
  --accent-ink: var(--sand-900);

  /* gold on sand is a narrower step than yellow on cool gray, so the
     highlight needs more of the accent to stay visible */
  --mark-strength: 62%;

  /* the gold is only 2:1 against sand, so it cannot carry the focus ring here
     (WCAG 1.4.11 wants 3:1); ink gives 13.7:1 and the hero overrides this */
  --focus: var(--ink);

  /* the hero band keeps its dark ground in both themes, so these are set once
     and never reassigned below — its text is the light theme's paper color */
  --hero-ground: var(--sky-800);
  --hero-ink: var(--sand-100);
  --hero-soft: var(--sky-200);
  --scrim-rgb: var(--sky-850-rgb);

  --shadow-rgb: var(--sand-shadow-rgb);
  --shadow: 0 1px 2px rgb(var(--shadow-rgb), .07), 0 10px 30px rgb(var(--shadow-rgb), .1);
  --shadow-lift: 0 4px 8px rgb(var(--shadow-rgb), .14), 0 16px 36px rgb(var(--shadow-rgb), .22);

  --display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --body: "Newsreader", Georgia, "Times New Roman", serif;

  /* The type scale for every fixed size.
     Headings are fluid and use clamp() instead;
     --fs-xs is 12.2px, the floor for caption text. */
  --fs-xs: .72rem;
  --fs-sm: .82rem;
  --fs-md: .92rem;
  --fs-base: 1rem;
  --fs-lg: 1.1rem;

  --logo-img: url("/static/logo.svg");
  --shell: 1160px;
  --gutter: clamp(1.25rem, 5vw, 3rem);
}

/* dark: the ground drops to the same sky-blue hue as the hero rather than to a
   neutral or a brown, so night keeps the warm ink / cool ground relationship. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: var(--sky-900);
    --ink: var(--sand-100);
    --ink-soft: var(--sand-300);
    --ink-faint: var(--sand-400);
    --rail-ink: var(--sky-300);
    --rule: var(--sky-800);
    --accent: var(--gold-300);
    --mark-strength: 48%;

    /* on the dark ground the gold clears 3:1 on its own (8.6:1) */
    --focus: var(--accent);

    --shadow-rgb: var(--black-rgb);
    --shadow: 0 1px 2px rgb(var(--shadow-rgb), .3), 0 10px 30px rgb(var(--shadow-rgb), .35);
    --shadow-lift: 0 4px 8px rgb(var(--shadow-rgb), .38), 0 16px 36px rgb(var(--shadow-rgb), .45);
  }
}

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

/* One lever for the whole page: every size below is in rem, so this moves them
   together and there is no per-element scale to keep in sync.
   Rem respects browser font-size setting better than px.
   Media queries are unaffected — rem inside a media query always resolves against
   the initial 16px, never against this, so no breakpoint shifts. */
:root { font-size: 1.0625rem; }

body {
  margin: 0;
  font-family: var(--body);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

h1, h2, h3 {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.02em;
  text-wrap: balance;
}

p { margin: 0; }

/* main container */
.shell {
  /* width:100% is load-bearing: without it, margin-inline:auto shrink-wraps
     the shell to its content inside the flex-column hero instead of filling */
  width: 100%;
  max-width: var(--shell);
  padding-inline: var(--gutter);
  margin-inline: auto;
}

/* The small tracked label that marks the top of a section — the front page's two
   columns each carry one, so they share a rule rather than matching by hand. */
.eyebrow,
.rail h2 {
  font-family: var(--display);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .16em;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

/* ---------- site header ---------- */
.topbar {
  position: relative;
  z-index: 10;
  border-bottom: 1px solid var(--rule);
}

.site-head {
  display: flex;
  gap: 1.5rem;
  align-items: center;
  justify-content: space-between;
  padding-block: .3rem;
}

.brand {
  display: block;
  text-decoration: none;
  --logo-h: 2.4rem;
}

/* the logo is a solid silhouette, so it is masked rather than drawn:
   it then takes currentColor and stays correct on paper, on ink and over the photo */
.brand-logo {
  display: block;
  width: calc(var(--logo-h) * 1.2478);
  height: var(--logo-h);
  background-color: currentColor;
  -webkit-mask: var(--logo-img) center / contain no-repeat;
  mask: var(--logo-img) center / contain no-repeat;
}

/* The link bar. Both <nav> elements on the site are one — the main menu and the
   footer menu — so this styles the element and the footer overrides what differs.
   The chips carry their own inline padding, which is why the gap can stay tight. */
nav {
  display: flex;
  gap: .35rem;
  align-items: center;
  font-family: var(--display);
  font-size: var(--fs-md);
  font-weight: 600;
}

/* the block padding keeps both sizes clear of the 24px target minimum (2.5.8),
   and the inline padding gives the hover chip its ground */
nav a {
  padding: .35rem .6rem;
  text-decoration: none;
  border-radius: 6px;
}

nav a:hover { background: color-mix(in srgb, currentColor 10%, transparent); }

/* ---------- inner pages ---------- */

/* A shell with a reading width.
   The gutter is added back in, so the 68ch applies to
   the text itself rather than to text-plus-padding. */
.prose {
  --shell: calc(68ch + var(--gutter) * 2);

  padding-block: clamp(2.5rem, 6vw, 4rem);
}

/* the base rules zero every margin,
   add some spacing between siblings. */
.prose > * + * { margin-top: 1.25rem; }

/* the middle term is rem + vw: a bare vw ignores the
   reader's font-size preference everywhere inside the fluid band */
.prose h1 { font-size: clamp(1.9rem, 1.3rem + 2.6vw, 2.6rem); }
.prose h2 { font-size: clamp(1.4rem, 1.1rem + 1.3vw, 1.75rem); }
.prose h3 { font-size: var(--fs-lg); }

/* put some space above headings to separate them from the previous paragraph. */
.prose > h2 { margin-top: 2.5rem; }
.prose > h3 { margin-top: 2rem; }

/* the announcement date belongs to the headline above it, not to the body */
.prose > time {
  display: block;
  margin-top: .6rem;
  font-family: var(--display);
  font-size: var(--fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  letter-spacing: .07em;
}

/* Every list in the column, Markdown's own included. */
:where(.prose) :where(ul, ol) {
  /* :where() holds this at zero specificity, so .news and .events can drop the
     indent with their own padding. */
  padding-left: 1.4rem;

  /* Zero specificity also makes this lose to .prose > * + * above; written as
     .prose ul it would outrank the flow rule and leave the heading flush
     against the list. */
  margin-block: 0;
}

/* Toned down from the browser's full-ink underline to keep the column calm, but
   not far past 3:1 — fainter and it stops reading as a link (WCAG 1.4.11). */
.prose a,
.photo-credit a,
.news-title {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
  text-underline-offset: 3px;
  transition: text-decoration-color .15s ease;
}

.prose a:hover,
.photo-credit a:hover,
.news a:hover .news-title { text-decoration-color: currentColor; }

/* Backtick spans in the announcements, so far only email addresses. A mono face
   marks them as literal text to copy; it is stepped down because mono x-heights
   run large beside Georgia. The chip tint is the one the nav hover uses. */
.prose code {
  padding: .1em .35em;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88em;
  background: color-mix(in srgb, currentColor 7%, transparent);
  border-radius: 4px;
}

/* The announcement list, shared by /tiedotteet/ and later the front-page rail.
   The link wraps both date and title so the whole row is clickable, which is
   why it clears its own underline and .news-title carries one instead
   (rule order is significant here). */
.news {
  display: grid;
  gap: 1.1rem;
  padding: 0;

  /* the .prose rule above zeroes this on /tiedotteet/, but in the rail the list
     is a grid item and the browser's own margin would double the gap */
  margin-block: 0;
  list-style: none;
}

.news a {
  display: grid;
  gap: .25rem;
  padding: .1rem 0;
  text-decoration: none;
}

.news time {
  font-family: var(--display);
  font-size: var(--fs-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--rail-ink);
  letter-spacing: .07em;
}

.news-title {
  font-size: var(--fs-base);
  line-height: 1.45;
  color: var(--ink);
}

/* the convention index: one link per row, so it drops the markers and lets the
   line spacing carry the list */
.events {
  display: grid;
  gap: .35rem;
  padding: 0;
  list-style: none;
}

/* ---------- front page hero ---------- */

/* the dark band the header sits on, and the ground under the photograph.
   It stays dark in both themes, so the focus ring is reassigned here.
   position: relative makes it the containing block for the photo. */
.hero {
  --focus: var(--hero-ink);

  position: relative;
  display: flex;
  flex-direction: column;
  color: var(--hero-ink);
  background: var(--hero-ground);
}

/* the paper hairline would glare on the dark ground */
.hero .topbar { border-bottom-color: rgb(255 255 255 / 10%); }

/* The logo outgrows the bar and hangs below it. The negative margin must keep the
   brand's outer height under the nav's, or the logo sets how tall the bar is. */
.hero .brand {
  --logo-h: 4rem;

  margin-bottom: -1.75rem;
}

/* The photo is positioned, so the copy has to be positioned too to sit above it.
   The copy and the event card share this row; the card drops below on narrow
   screens, and without one the copy is alone and space-between does nothing. */
.hero-body {
  position: relative;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 1.35rem 2.5rem;
  align-items: flex-end;
  justify-content: space-between;
  padding-block: clamp(1.6rem, 3.5vw, 2.6rem);
  margin-top: auto;
}

.hero-copy {
  display: grid;
  gap: .85rem;
}

.hero-headline {
  font-size: clamp(2.6rem, 1.8rem + 3.5vw, 4.2rem);
  font-weight: 800;
  letter-spacing: -.035em;
}

.hero-tagline {
  max-width: 38ch;
  font-size: clamp(1rem, .9rem + .45vw, 1.2rem);
  line-height: 1.45;
  color: var(--hero-soft);
}

/* holds "science fiction-" together across the hyphen */
.nowrap { white-space: nowrap; }

/* with the photo out of flow there is no content to hold the band open */
.hero-photo { min-height: clamp(330px, 46vh, 450px); }

/* object-position sits above center: the frame's interest is in the upper half */
.hero-photo .photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 44%;
}

/* The copy sits at the lower left, so the wash is heaviest there and thins out
   toward the top and the right. It follows .photo in the markup and neither
   carries a z-index, so source order alone puts it over the frame. */
.hero-photo .scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgb(var(--scrim-rgb), .97) 4%, rgb(var(--scrim-rgb), .88) 30%, rgb(var(--scrim-rgb), .45) 62%, rgb(var(--scrim-rgb), .22) 88%, rgb(var(--scrim-rgb), .18) 100%),
    linear-gradient(to right, rgb(var(--scrim-rgb), .86) 0%, rgb(var(--scrim-rgb), .35) 45%, transparent 72%);
}

/* Add a more opaque navbar background
   to make sure text is readable,
   and also give the site a bit of structure with a visible top nav bar. */
.hero-photo .topbar {
  background: rgb(var(--scrim-rgb), .88);
  border-bottom-color: rgb(255 255 255 / 16%);
}

/* ---------- next-event callout ---------- */

.next-event-link {
  display: inline-flex;
  gap: clamp(1rem, 3vw, 2rem);
  align-items: center;
  max-width: 100%;
  padding: .95rem 1.15rem .95rem 1.35rem;
  color: var(--accent-ink);
  text-decoration: none;
  background: var(--accent);
  border-radius: 12px;
  box-shadow: var(--shadow);
  transition: transform .18s ease, box-shadow .18s ease;
}

.next-event-link:hover {
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
}

.next-event-link-label {
  display: block;
  margin-bottom: .15rem;
  font-family: var(--display);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .16em;
  opacity: .8;
}

.next-event-link-name {
  font-family: var(--display);
  font-size: clamp(1.05rem, .93rem + .55vw, 1.3rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.015em;
}

.next-event-link-meta {
  font-size: var(--fs-md);
  line-height: 1.3;
  opacity: .82;
}

.next-event-link-arrow {
  flex: none;
  font-family: var(--display);
  font-size: 1.3rem;
  line-height: 1;
  transition: transform .18s ease;
}

.next-event-link:hover .next-event-link-arrow { transform: translateX(3px); }

/* ---------- front page body ---------- */

/* the info column and the news rail, one above the other until there is room */
.main {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

@media (width >= 56rem) {
  .main { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); }
}

.info {
  display: grid;
  gap: 1.5rem;
  align-content: start;
}

.info h2 { font-size: clamp(1.6rem, 1.33rem + 1.2vw, 2.15rem); }

.info .eyebrow { color: var(--ink-faint); }

/* the floor is what nearly every screen gets; the fluid term only bites on wide desktops */
.lead {
  max-width: 60ch;
  font-size: clamp(1.16rem, 1.1rem + .27vw, 1.28rem);
  line-height: 1.6;
}

.lead mark {
  padding: 0 .12em;
  color: inherit;
  background: color-mix(in srgb, var(--accent) var(--mark-strength), transparent);
}

.points {
  display: grid;
  gap: 1.4rem;
  max-width: 62ch;
  padding: 0;
  margin: .35rem 0 0;
  list-style: none;
}

/* the bullet spans both rows, so the heading and the sentence share one edge */
.points li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .2rem .95rem;
}

.point-bullet {
  grid-row: span 2;
  width: .62rem;
  height: .62rem;
  margin-top: .5rem;
  background: var(--accent);
  border-radius: 2px;
}

.points h3 {
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: -.005em;
}

.points p {
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--ink-soft);
}

/* the rule divides the two columns, and moves overhead when they stack */
.rail {
  display: grid;
  gap: 1.1rem;
  align-content: start;
}

@media (width >= 56rem) {
  .rail {
    padding-left: clamp(1.75rem, 3vw, 2.75rem);
    border-left: 1px solid var(--rule);
  }
}

@media (width < 56rem) {
  .rail {
    padding-top: 2rem;
    border-top: 1px solid var(--rule);
  }
}

/* the rail runs on --rail-ink, the sky blue, rather than the warm --ink-faint:
   it gives the quiet column its own register without adding any weight */
.rail h2 { color: var(--rail-ink); }

.rail-more {
  justify-self: start;

  /* the line box alone is 23px; padding clears the 24px target minimum (2.5.8) */
  padding-block: .3rem;
  font-family: var(--display);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
}

.rail-more:hover { color: var(--ink); }

/* ---------- site footer ---------- */
.site-foot {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem 2.5rem;
  align-items: baseline;
  padding-block: 1.5rem 2.5rem;
  font-size: var(--fs-md);
  color: var(--ink-soft);
  border-top: 1px solid var(--rule);
}

.site-foot p { max-width: 46ch; }

/* footer nav menu variant */
.foot-links {
  flex-wrap: wrap;
  margin-left: auto;
  font-size: var(--fs-sm);
}

.foot-links a:hover { color: var(--ink); }

/* the hero photo's credit. flex-basis gives it a row of its own below the blurb
   and the links, rather than a third column competing with them. */
.photo-credit {
  flex-basis: 100%;

  /* a single line, so the body's 1.65 only adds leading above it */
  line-height: 1.4;
  color: var(--ink-faint);
}

@media (width <= 30rem) {
  .site-head { flex-wrap: wrap; gap: .75rem; }

  /* scoped to the header: the footer is a <nav> too, and its margin-left is auto
     — an unscoped rule here would drag the footer links off the right edge */
  .site-head nav { margin-left: -.6rem; font-size: var(--fs-sm); }

  /* the head wraps to two rows here, so the overhang would land on the nav */
  .hero .brand { --logo-h: 2.8rem; margin-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}
