@charset "utf-8";
/* ==========================================================================
   SMASH — STEM Madness at Saratoga High
   Built by MSET Cuttlefish 6165. Hand-written CSS, no framework.

   Contents
     01  Fonts
     02  Tokens
     03  Reset & base
     04  Type scale
     05  Layout
     06  Photos
     07  Header & nav
     08  Hero
     09  Vitals (date / time / place block)
     10  Editorial sections
     12  Numbers
     16  Team
     17  FAQ
     19  Footer
     21  Motion & print
   ========================================================================== */

/* ---------- 01  Fonts --------------------------------------------------- */

@font-face {
  font-family: "Bricolage";
  src: url("../fonts/bricolage.woff2") format("woff2");
  font-weight: 200 800;
  font-stretch: 75% 100%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader-italic.woff2") format("woff2");
  font-weight: 200 800;
  font-style: italic;
  font-display: swap;
}

/* ---------- 02  Tokens -------------------------------------------------- */

:root {
  /* Palette. Pulled off the event itself: the aubergine of the smasher frame,
     the orange of a pumpkin, the lilac the sky goes at 5pm in November. */
  --ink: #241833;
  --ink-soft: #4b3b5e;
  --plum: #46255a;
  --violet: #64488c;
  --lilac: #ba8bdb;
  --lilac-pale: #e3b3ff;
  --peach: #ffd5a5;
  --squash: #ffa86b;
  --orange: #f4802a;
  --orange-hot: #e0651a;

  --paper: #fdf6ee;
  --paper-2: #f6e7d6;
  --paper-3: #efd9c4;

  --bg: var(--paper);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --rule: color-mix(in srgb, var(--ink) 16%, transparent);
  --rule-strong: color-mix(in srgb, var(--ink) 32%, transparent);
  --accent: var(--orange);        /* fills only — see --accent-text */
  --accent-text: #a64407;         /* orange dark enough to set type in: 5.7:1 on paper, 5.0:1 on panel */
  --accent-ink: var(--ink);       /* label colour on an --accent fill: 6.4:1 */
  --panel: var(--paper-2);
  --shadow: color-mix(in srgb, var(--plum) 18%, transparent);

  /* Type */
  --display: "Bricolage", ui-sans-serif, "Helvetica Neue", Arial, sans-serif;
  --text: "Newsreader", ui-serif, Georgia, "Times New Roman", serif;

  --step--1: clamp(0.83rem, 0.8rem + 0.15vw, 0.92rem);
  --step-0: clamp(1.06rem, 1rem + 0.3vw, 1.19rem);
  --step-1: clamp(1.3rem, 1.18rem + 0.55vw, 1.6rem);
  --step-2: clamp(1.62rem, 1.4rem + 1.05vw, 2.3rem);
  --step-3: clamp(2.05rem, 1.6rem + 2.1vw, 3.4rem);
  --step-4: clamp(2.6rem, 1.7rem + 4.3vw, 5.4rem);
  --step-5: clamp(3.2rem, 1.5rem + 8vw, 8.5rem);

  /* Rhythm */
  --gutter: clamp(1.15rem, 5vw, 3.5rem);
  --gap: clamp(1.5rem, 3vw, 2.75rem);
  --section: clamp(3.5rem, 8vw, 7.5rem);
  --measure: 38rem;             /* body text and headings; photo captions set their own */

  /* Paper grain. Cheap, tiny, and it stops large flat fields reading plastic. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #191024;
    --fg: #f4e7dc;
    --fg-soft: #c3aec4;
    --rule: color-mix(in srgb, var(--peach) 18%, transparent);
    --rule-strong: color-mix(in srgb, var(--peach) 34%, transparent);
    --accent: var(--squash);
    --accent-text: var(--squash);
    --accent-ink: #2a1330;
    --panel: #241734;
    --paper-2: #241734;
    --paper-3: #31204490;
    --shadow: #0a0410;
  }
}
:root[data-theme="dark"] {
  --bg: #191024;
  --fg: #f4e7dc;
  --fg-soft: #c3aec4;
  --rule: color-mix(in srgb, var(--peach) 18%, transparent);
  --rule-strong: color-mix(in srgb, var(--peach) 34%, transparent);
  --accent: var(--squash);
  --accent-text: var(--squash);
  --accent-ink: #2a1330;
  --panel: #241734;
  --paper-2: #241734;
  --paper-3: #31204490;
  --shadow: #0a0410;
}

/* ---------- 03  Reset & base -------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--text);
  font-size: var(--step-0);
  line-height: 1.62;
  font-variation-settings: "opsz" 18;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Grain sits above the background, below everything else. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--grain);
  opacity: 0.035;
  mix-blend-mode: multiply;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body::before { mix-blend-mode: screen; opacity: 0.05; }
}
:root[data-theme="dark"] body::before { mix-blend-mode: screen; opacity: 0.05; }

body > * { position: relative; z-index: 1; }

img, picture, video, svg { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration-color: var(--rule-strong); text-underline-offset: 0.18em; }
a:hover { text-decoration-color: var(--accent); }

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

::selection { background: var(--lilac-pale); color: var(--ink); }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.7em 1.1em;
  font-family: var(--display);
  font-weight: 700;
  z-index: 999;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

/* ---------- 04  Type scale ---------------------------------------------- */

h1, h2, h3, h4, .display {
  font-family: var(--display);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.022em;
  font-variation-settings: "wdth" 92, "opsz" 48;
  text-wrap: balance;
  margin: 0;
}

h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); line-height: 1.12; letter-spacing: -0.012em; }

p { margin: 0 0 1.15em; max-width: var(--measure); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: var(--step-1);
  line-height: 1.44;
  font-variation-settings: "opsz" 32;
  color: var(--fg);
}

.eyebrow {
  font-family: var(--display);
  font-size: var(--step--1);
  font-weight: 700;
  font-variation-settings: "wdth" 100, "opsz" 14;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--fg-soft);
  margin: 0 0 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.7em;
}
.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.mono-note {
  font-family: var(--display);
  font-size: var(--step--1);
  font-variation-settings: "wdth" 100, "opsz" 14;
  letter-spacing: 0.02em;
  color: var(--fg-soft);
}

/* A hand-drawn-feeling highlight behind a few key words. */
.mark {
  background: linear-gradient(
      180deg,
      transparent 58%,
      color-mix(in srgb, var(--squash) 65%, transparent) 58%,
      color-mix(in srgb, var(--squash) 65%, transparent) 94%,
      transparent 94%);
  padding: 0 0.08em;
}


/* ---------- 05  Layout --------------------------------------------------- */

/* One grid, used everywhere. Every section's content starts at the same left
   edge — the reader should never have to hunt for where the column begins.
   There are exactly two content widths: --measure for text, and the shell
   for everything else. Nothing is wider than the shell. */

.shell {
  width: 100%;
  max-width: 70rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section); }
.section--top { padding-top: clamp(2.5rem, 6vw, 5rem); }
.section--rule { border-top: 1px solid var(--rule); }

/* Prose measure. Body copy never gets wider than this and never moves right. */
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.15em; }

/* Section opener: eyebrow, heading and standfirst stacked at the left edge. */
.headline-block {
  max-width: var(--measure);
  margin-bottom: clamp(1.8rem, 4vw, 2.8rem);
}
.headline-block > * + * { margin-top: 0.9rem; }

/* The only two-column pattern on the site: prose left, picture right.
   Always that way round, always the same ratio. */
.with-figure {
  display: grid;
  gap: var(--gap);
  align-items: start;
}
@media (min-width: 62rem) {
  .with-figure {
    grid-template-columns: minmax(0, var(--measure)) minmax(0, 1fr);
    gap: clamp(2rem, 4vw, 3.5rem);
  }
}


.stack > * + * { margin-top: var(--flow, 1.15em); }

/* ---------- 06  Photos --------------------------------------------------- */

.ph {
  margin: 0;
  position: relative;
}
.ph img {
  width: 100%;
  background: var(--ph, var(--paper-3));
  border-radius: 3px;
}
.ph figcaption {
  font-family: var(--display);
  font-size: var(--step--1);
  font-variation-settings: "wdth" 100, "opsz" 14;
  color: var(--fg-soft);
  margin-top: 0.7rem;
  line-height: 1.4;
  max-width: 42ch;
}
.ph figcaption b {
  font-weight: 700;
  color: var(--fg);
}

.ph--frame img {
  box-shadow: 0 1px 0 1px var(--rule), 0 18px 40px -24px var(--shadow);
}


/* ---------- 07  Header & nav --------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}

.masthead__in {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 3.6rem;
}

.wordmark {
  font-family: var(--display);
  font-size: 0.95rem;
  font-weight: 600;
  font-variation-settings: "wdth" 96, "opsz" 16;
  letter-spacing: 0.02em;
  /* The line box has to be tall enough for the big initials, or they get
     clipped at the top of the viewport on phones where this is line one. */
  line-height: 1.15;
  white-space: nowrap;
  text-decoration: none;
  color: var(--fg);
  margin-right: auto;
}
/* The initials spell the name, so they're set larger. */
.wordmark b {
  font-size: 1.55em;
  font-weight: 800;
  font-variation-settings: "wdth" 88, "opsz" 32;
  color: var(--accent-text);
}

/* The nav used to be display:none below 832px, which meant every visitor who
   arrived by scanning the flyer — i.e. all of them — got a long page with no
   way to jump anywhere. On narrow screens it becomes a scrollable chip row on
   its own line under the wordmark. */
.nav {
  display: flex;
  gap: clamp(0.8rem, 2vw, 1.7rem);
  font-family: var(--display);
  font-size: 0.88rem;
  font-weight: 600;
  font-variation-settings: "wdth" 100, "opsz" 14;
}
.nav a {
  text-decoration: none;
  padding-block: 0.4rem;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--accent-text); }
.nav a[aria-current] {
  color: var(--accent-text);
  border-bottom-color: currentColor;
}
.nav a.nav__pill {
  border: 1.5px solid var(--fg);
  border-radius: 999px;
  padding: 0.38rem 0.9rem;
}
.nav a.nav__pill:hover { background: var(--fg); color: var(--bg); }

@media (max-width: 51.99rem) {
  .masthead__in { flex-wrap: wrap; row-gap: 0.1rem; padding-block: 0.35rem; min-height: 3rem; }
  .wordmark { font-size: 0.78rem; }
  .nav {
    order: 3;
    width: 100%;
    gap: 1.1rem;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* let the row bleed to the screen edges so it reads as scrollable */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    mask-image: linear-gradient(90deg, transparent 0, #000 var(--gutter),
                                #000 calc(100% - var(--gutter)), transparent 100%);
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { font-size: 0.82rem; padding-block: 0.3rem; }
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--display);
  font-size: 0.92rem;
  font-weight: 700;
  font-variation-settings: "wdth" 96, "opsz" 16;
  letter-spacing: -0.005em;
  padding: 0.62em 1.05em;
  border: 1.5px solid var(--fg);
  background: transparent;
  color: var(--fg);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.btn:hover { background: var(--fg); color: var(--bg); }
.btn:active { transform: translateY(1px); }

.btn--sm { font-size: 0.82rem; padding: 0.5em 0.9em; }

/* ---------- 08  Hero ----------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  min-height: min(78svh, 42rem);
  display: grid;
  align-content: center;
  text-align: center;
  padding-block: clamp(3.5rem, 12vw, 7rem) clamp(2.5rem, 6vw, 4rem);
  overflow: hidden;
}
.hero > .shell { display: grid; justify-items: center; }

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 62%;
  border-radius: 0;
  background: #667282;
}
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  /* The type is centred now, so the scrim has to hold through the middle of
     the frame, not just the bottom. The photo underneath is a bright crowd. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, #1a0f26 70%, transparent) 0%,
      color-mix(in srgb, #1a0f26 68%, transparent) 45%,
      color-mix(in srgb, #1a0f26 74%, transparent) 75%,
      color-mix(in srgb, #1a0f26 88%, transparent) 100%);
}

.hero h1 {
  color: #fff;
  font-size: var(--step-5);
  font-weight: 800;
  font-variation-settings: "wdth" 78, "opsz" 96;
  letter-spacing: -0.012em;
  line-height: 0.93;
  text-shadow: 0 2px 30px rgba(20, 8, 30, 0.42);
  max-width: none;
}

.hero__tag {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1rem + 1vw, 1.8rem);
  font-weight: 600;
  font-variation-settings: "wdth" 92, "opsz" 28;
  letter-spacing: -0.01em;
  color: #fff;
  text-shadow: 0 1px 14px rgba(20, 8, 30, 0.6);
  margin: 0.9rem 0 0;
  max-width: none;
}
.hero__tag em { font-style: normal; font-weight: 800; color: var(--squash); }

.hero__date {
  font-family: var(--display);
  font-size: var(--step-4);
  font-weight: 800;
  font-variation-settings: "wdth" 80, "opsz" 96;
  letter-spacing: -0.012em;
  line-height: 1;
  color: var(--squash);
  text-shadow: 0 2px 24px rgba(20, 8, 30, 0.5);
  margin: 1.4rem 0 0;
  max-width: none;
}

/* Where and how much, as plain text — the labels were noise. */
.hero__facts {
  list-style: none;
  margin: 1.3rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 2.4rem;
  font-family: var(--display);
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.35rem);
  font-weight: 700;
  font-variation-settings: "wdth" 90, "opsz" 28;
  line-height: 1.12;
  letter-spacing: -0.018em;
  color: #fff;
  text-shadow: 0 1px 14px rgba(20, 8, 30, 0.6);
}
.hero__facts li span {
  display: block;
  font-size: 0.78rem;
  font-weight: 500;
  font-variation-settings: "wdth" 100, "opsz" 14;
  letter-spacing: 0;
  margin-top: 0.2rem;
  text-shadow: 0 1px 10px rgba(20, 8, 30, 0.8);
}

/* Calendar and directions, right under the facts. Outlined in white on the
   scrim; the faint fill keeps them legible over the brighter patches. */
.hero__acts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  margin-top: 1.5rem;
}
.hero .btn {
  border-color: rgba(255, 255, 255, 0.75);
  color: #fff;
  background: rgba(20, 8, 30, 0.28);
  backdrop-filter: blur(4px);
}
.hero .btn:hover { background: #fff; border-color: #fff; color: var(--ink); }


/* ---------- 09  Vitals --------------------------------------------------- */

/* Three short facts in a band under the hero: a small label over each one.
   Dividers are drawn in the gaps, so the text starts on the shell edge
   whether the cells sit in a row or stack. */
.vitals {
  border-block: 1.5px solid var(--fg);
  background: var(--paper-2);
}
.vitals__grid {
  --vitals-gap: clamp(1.5rem, 4vw, 3rem);
  display: grid;
  margin: 0;
}
.vitals__cell {
  position: relative;
  padding-block: clamp(1.1rem, 2.5vw, 1.7rem);
}
.vitals dt {
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  font-variation-settings: "wdth" 100, "opsz" 12;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.4rem;
}
.vitals dd {
  margin: 0;
  max-width: none;
  font-family: var(--display);
  font-size: clamp(1.02rem, 0.95rem + 0.4vw, 1.25rem);
  font-weight: 600;
  font-variation-settings: "wdth" 92, "opsz" 24;
  line-height: 1.25;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
@media (min-width: 52rem) {
  .vitals__grid { grid-template-columns: repeat(3, 1fr); column-gap: var(--vitals-gap); }
  .vitals__cell + .vitals__cell::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(var(--vitals-gap) / -2);
    width: 1px;
    background: var(--rule);
  }
}
@media (max-width: 51.99rem) {
  .vitals__cell + .vitals__cell { border-top: 1px solid var(--rule); }
}

/* ---------- 10  Editorial sections --------------------------------------- */


.pull {
  margin: clamp(2.5rem, 6vw, 4.5rem) 0;
  max-width: var(--measure);
  padding-top: clamp(1.2rem, 3vw, 2rem);
  border-top: 1.5px solid var(--fg);
}
.pull p {
  font-family: var(--display);
  font-size: var(--step-2);
  font-weight: 500;
  font-variation-settings: "wdth" 88, "opsz" 44;
  line-height: 1.12;
  letter-spacing: -0.022em;
  margin: 0;
  max-width: none;
  text-indent: -0.42em;         /* hang the opening quote into the margin */
}
.pull cite {
  display: block;
  font-family: var(--display);
  font-size: 0.8rem;
  font-weight: 600;
  font-style: normal;
  font-variation-settings: "wdth" 100, "opsz" 14;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-soft);
  margin-top: 0.9rem;
}


/* ---------- 12  Numbers -------------------------------------------------- */

.tally {
  display: grid;
  gap: clamp(1.4rem, 3vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  align-items: start;
}
.tally__n {
  font-family: var(--display);
  font-weight: 800;
  font-variation-settings: "wdth" 80, "opsz" 96;
  font-size: clamp(2.8rem, 1.6rem + 4.2vw, 5rem);
  line-height: 0.8;
  letter-spacing: -0.045em;
  color: var(--accent-text);
  display: block;
  font-variant-numeric: tabular-nums;
}
.tally__l {
  display: block;
  font-family: var(--display);
  font-size: 0.86rem;
  font-weight: 600;
  font-variation-settings: "wdth" 100, "opsz" 14;
  line-height: 1.3;
  color: var(--fg-soft);
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
  max-width: 22ch;
}

/* ---------- 16  Team ----------------------------------------------------- */

.orgcard {
  border: 1.5px solid var(--fg);
  border-radius: 5px;
  padding: clamp(1.2rem, 3vw, 2rem);
  background: var(--panel);
}
.orgcard h3 { margin-bottom: 0.5rem; }
.orgcard p { font-size: 0.98rem; color: var(--fg-soft); }
.orgcard dl {
  margin: 1.2rem 0 0;
  display: grid;
  gap: 0.55rem 1rem;
  grid-template-columns: auto 1fr;
  font-size: 0.92rem;
}
.orgcard dt {
  font-family: var(--display);
  font-weight: 700;
  font-variation-settings: "wdth" 100, "opsz" 13;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-soft);
  padding-top: 0.28em;
}
.orgcard dd { margin: 0; }

.teamgrid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  align-items: start;
}

/* ---------- 17  FAQ ------------------------------------------------------ */

.faq { border-top: 1.5px solid var(--fg); }
.faq details {
  border-bottom: 1px solid var(--rule);
}
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: clamp(0.95rem, 2.2vw, 1.35rem) 2.5rem clamp(0.95rem, 2.2vw, 1.35rem) 0;
  font-family: var(--display);
  font-size: clamp(1.02rem, 0.96rem + 0.35vw, 1.22rem);
  font-weight: 600;
  font-variation-settings: "wdth" 92, "opsz" 24;
  letter-spacing: -0.012em;
  line-height: 1.24;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 0.35rem;
  top: 50%;
  translate: 0 -50%;
  font-size: 1.5em;
  font-weight: 400;
  line-height: 1;
  color: var(--accent-text);
  transition: rotate 0.18s ease;
}
.faq details[open] summary::after { rotate: 45deg; }
.faq summary:hover { color: var(--accent-text); }
.faq__a {
  padding: 0 0 1.4rem;                 /* the summary reserves room for the +; the answer needn't */
  color: var(--fg-soft);
  font-size: 0.99rem;
}
.faq__a p { max-width: none; }   /* .faq--col already holds the measure */

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

.footer {
  background: var(--ink);
  color: var(--peach);
  padding-block: clamp(3rem, 7vw, 5.5rem) 2rem;
}
.footer a { color: #fff; }
.footer a:hover { color: var(--squash); }
.footer__cols {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: clamp(1.8rem, 4vw, 2.6rem);
  border-top: 1px solid rgba(255, 213, 165, 0.25);
  font-size: 0.94rem;
}
.footer__h {
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  font-variation-settings: "wdth" 100, "opsz" 12;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--lilac);
  margin: 0 0 0.7rem;
}
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li + li { margin-top: 0.35rem; }
.footer__fine {
  margin-top: clamp(2rem, 5vw, 3rem);
  font-size: 0.8rem;
  color: rgba(255, 213, 165, 0.62);
  max-width: var(--measure);
}

/* ---------- 21  Motion & print ------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .masthead, .slideshow, .footer__cols { display: none; }
  body { background: #fff; color: #000; }
  .hero { min-height: auto; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }
}

/* ---------- 22  Additions ------------------------------------------------ */

/* The date lives in the header, not a call-to-action button. Somebody who
   scanned a QR code off a flyer wants to know *when*, permanently, while they
   scroll — and it keeps this out of wordmark-links-button SaaS-nav territory. */

/* Citation line under a statistic-heavy passage. */
.sources {
  font-family: var(--display);
  font-size: 0.78rem;
  font-variation-settings: "wdth" 100, "opsz" 13;
  line-height: 1.55;
  color: var(--fg-soft);
  border-top: 1px solid var(--rule);
  padding-top: 0.9rem;
  margin-top: 1.6rem;
  max-width: none;
}

/* The "+" on a figure shouldn't be the same weight as the number. */
.tally__n sub {
  font-size: 0.44em;
  vertical-align: baseline;
  bottom: 0;
  font-weight: 600;
  letter-spacing: 0;
  opacity: 0.75;
}

.footer__lead {
  color: var(--peach);
  max-width: var(--measure);
  font-size: var(--step-1);
  line-height: 1.4;
}

/* Two honest columns beat four invented ones. */
.footer__cols { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }

/* The FAQ shares the prose measure rather than centring itself on the page. */
.faq--col { max-width: var(--measure); }
/* A figure given its own breathing room between two blocks of text. */
.ph--band { margin-block: clamp(2rem, 5vw, 3.5rem); }

/* Full width, own aspect ratio kept. For group photos, where cropping would
   cut people out of the frame. */
.ph--full { margin-block: clamp(2rem, 5vw, 3.5rem); }

/* A full-width establishing shot: cropped wide so a 4:3 frame doesn't take
   over an entire screen on desktop. Never use on a photo of people lined up. */
.ph--band img {
  aspect-ratio: 2 / 1;
  object-fit: cover;
  object-position: 50% 45%;
}
@media (max-width: 46rem) {
  .ph--band img { aspect-ratio: 4 / 3; }
}

/* ---------- 23  Clips ---------------------------------------------------- */

/* Short silent loops of each machine doing its job. Muted + playsinline so
   iOS plays them inline rather than going fullscreen. */
.clips {
  display: grid;
  gap: var(--gap);
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
}
@media (min-width: 48rem)  { .clips { grid-template-columns: repeat(3, 1fr); } }

.clip { margin: 0; }
.clip video {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 3px;
  background: var(--paper-3);
  box-shadow: 0 1px 0 1px var(--rule), 0 18px 40px -24px var(--shadow);
}
.clip figcaption {
  font-family: var(--display);
  font-size: var(--step--1);
  font-variation-settings: "wdth" 100, "opsz" 14;
  color: var(--fg-soft);
  margin-top: 0.7rem;
  line-height: 1.4;
}
.clip figcaption b { color: var(--fg); font-weight: 700; }

/* Someone who has asked for less motion gets a still with a play button. */
@media (prefers-reduced-motion: reduce) {
  .clip video { outline: none; }
}

/* ---------- 24  Back to top --------------------------------------------- */

/* Appears once you're a screen or so down. On a page people scroll through
   once, getting back to the date and the calendar button shouldn't mean
   flicking all the way up. */
.totop {
  position: fixed;
  right: clamp(0.9rem, 3vw, 2rem);
  bottom: clamp(0.9rem, 3vw, 2rem);
  z-index: 60;
  width: 2.9rem;
  height: 2.9rem;
  display: grid;
  place-items: center;
  font-size: 1.1rem;
  line-height: 1;
  border: 1.5px solid var(--fg);
  border-radius: 50%;
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  translate: 0 0.5rem;
  transition: opacity 0.18s, translate 0.18s, background 0.15s, color 0.15s;
}
.totop[data-on] { opacity: 1; visibility: visible; translate: 0 0; }
.totop:hover { background: var(--fg); color: var(--bg); }
.totop svg { display: block; }
@media print { .totop { display: none; } }

/* ---------- 13b  Ribbons ------------------------------------------------- */

/* Half the album per row, drifting in opposite directions. Each row holds its
   set of photos twice, so translating by exactly one set plus one gap lands on
   an identical frame and the loop never seams.

   Thumbnails are deliberately small: the point is a moving wall of the whole
   album, not four photos you can study. */
.ribbon {
  --ribbon-gap: clamp(0.35rem, 0.9vw, 0.6rem);
  overflow: hidden;
  display: grid;
  gap: var(--ribbon-gap);
}
.ribbon__row {
  display: flex;
  gap: var(--ribbon-gap);
  width: max-content;
  will-change: transform;
  animation-duration: 360s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
/* top: the wall travels toward the right edge */
.ribbon__row--ltr { animation-name: ribbon-ltr; }
/* bottom: and this one back toward the left */
.ribbon__row--rtl { animation-name: ribbon-rtl; animation-duration: 400s; }

.ribbon__row > * { flex: none; }
.ribbon__set {
  display: flex;
  gap: var(--ribbon-gap);
}
.ribbon .ph { flex: none; }
.ribbon img {
  height: clamp(11rem, 29vw, 20.5rem);
  width: auto;
  max-width: none;
  border-radius: 2px;
  background: var(--ph, var(--paper-3));
}

/* Shift by one set + one gap. Row width is 2 sets + 1 gap, so -50% is one set
   plus HALF a gap — the extra half-gap is what closes the seam. */
@keyframes ribbon-ltr {
  from { transform: translateX(calc(-50% - var(--ribbon-gap) / 2)); }
  to   { transform: translateX(0); }
}
@keyframes ribbon-rtl {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - var(--ribbon-gap) / 2)); }
}

/* No drift: drop the duplicate set and hand back an ordinary scroller, so the
   photos past the edge stay reachable. */
@media (prefers-reduced-motion: reduce) {
  .ribbon {
    overflow-x: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--rule-strong) transparent;
  }
  .ribbon__row { animation-name: none; }
  .ribbon__set[aria-hidden="true"] { display: none; }
}

/* ---------- 13c  Slideshow ----------------------------------------------- */

/* One photo at a time, cycling, in place of a strip you had to drag sideways.
   Two modes, so the thing works either way:

   Without JS — and for anyone who asked for less motion — the track is an
   ordinary scroll-snap carousel: one photo per view, swipe or scroll for the
   next, nothing moving on its own.

   With JS the slides stack into one grid cell and cross-fade on a timer, and
   site.js writes in the two arrows. Every photo in a slideshow is 4:3;
   anything else got left out rather than cropped to fit. */

.slideshow {
  /* How long each photo stays up, and how long it takes to hand over. CSS
     owns both: site.js reads --hold off the element to set its interval. */
  --hold: 4s;
  --fade: 0.8s;
  position: relative;
  margin-top: var(--gap);
}
.slideshow__track {
  display: flex;
  gap: clamp(0.6rem, 1.6vw, 1.1rem);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-strong) transparent;
}
.slideshow__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
}
.slideshow__slide img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
/* A 16:9 photo in this frame loses a quarter of its width. Centred, that crop
   cuts into whatever is happening at the right-hand edge; this keeps it. */
.slideshow__slide--crop-right img { object-position: 78% center; }

/* Stacked mode. The outgoing slide keeps its visibility for the length of the
   fade, then drops out of the layer and the accessibility tree entirely. */
.slideshow[data-ready] .slideshow__track {
  display: grid;
  gap: 0;
  overflow: hidden;
}
.slideshow[data-ready] .slideshow__slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade) ease, visibility 0s linear var(--fade);
}
.slideshow[data-ready] .slideshow__slide[data-on] {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--fade) ease;
}

/* Arrows sit on the photo itself rather than under it, so the controls don't
   push the next section down and don't read as part of the page furniture. */
.slideshow__arrow {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 50%;
  cursor: pointer;
  /* A white disc reads on any photo; the shadow does the separating on the
     bright ones. */
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.22), 0 6px 16px rgba(0, 0, 0, 0.26);
  transition: background 0.15s ease, scale 0.15s ease;
}
.slideshow__arrow:hover { background: #fff; scale: 1.06; }
.slideshow__arrow svg { display: block; }
.slideshow__arrow--prev { left: clamp(0.5rem, 1.5vw, 1rem); }
.slideshow__arrow--next { right: clamp(0.5rem, 1.5vw, 1rem); }

/* Position dots along the bottom of the frame. Each is a full-size button
   (a 0.55rem dot alone is too small a target) drawn with ::before. */
.slideshow__dots {
  position: absolute;
  left: 50%;
  bottom: 0.6rem;
  translate: -50% 0;
  z-index: 2;
  display: flex;
  gap: 0.1rem;
  padding: 0.15rem 0.35rem;
  border-radius: 999px;
  background: rgba(20, 8, 30, 0.6);
  backdrop-filter: blur(4px);
}
.slideshow__dot {
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.slideshow__dot::before {
  content: "";
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  border: 1.5px solid #fff;
  transition: background 0.2s ease, transform 0.2s ease;
}
.slideshow__dot:hover::before { transform: scale(1.2); }
.slideshow__dot[aria-current]::before { background: #fff; }

/* ---------- 25  Smashing · booths, side by side -------------------------- */

.what-grid {
  display: grid;
  gap: clamp(2.2rem, 5vw, 4rem);
  align-items: start;
}
/* No subgrid: aligning the two slideshows would stretch the shorter lede's
   row to the taller one and leave dead space under its last line. Each
   column flows on its own; the slideshows may sit a line apart. */
@media (min-width: 52rem) { .what-grid { grid-template-columns: 1fr 1fr; } }
.what-col h2 {
  font-size: var(--step-2);
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.what-col .lede { margin: 0.75rem 0 0; font-size: var(--step-0); }
.what-col .slideshow { max-width: none; margin-top: 1.1rem; }
