/* ============================================================
   WESTSIDE STUCO
   Palette comes from the wolf logo. Periwinkle is the brand
   color, everything else is an accent used in small amounts.

   This site is LIGHT ONLY, on purpose. Do not add a
   prefers-color-scheme dark block. An earlier draft had one and
   anyone whose device was set to dark saw a site that was never
   designed. If you want a dark theme, design it deliberately.
   ============================================================ */

:root {
  color-scheme: light;

  --paper:     #FFFFFF;
  --soft:      #F7F8FC;
  --surface:   #FFFFFF;
  --text:      #2F3142;
  --muted:     #6E7186;
  --line:      #E6E7F0;
  --line-soft: #EFF0F6;

  --peri:      #5C63A6;
  --peri-br:   #8189E0;
  --peri-soft: #EEEFFB;
  --peri-text: #474D8A;

  --rose:      #F2617C;
  --rose-soft: #FEECF0;
  --rose-text: #C23050;

  --mint:      #21BE9B;
  --mint-soft: #E2F7F2;
  --mint-text: #0E7A63;

  --sun:       #FFC93F;
  --sun-soft:  #FFF4D9;
  --sun-mark:  #FFE9A8;
  --sun-text:  #8A6100;

  --shadow:      0 1px 2px rgba(47,49,66,.04), 0 6px 20px -10px rgba(47,49,66,.14);
  --shadow-lift: 0 2px 4px rgba(47,49,66,.05), 0 14px 32px -14px rgba(47,49,66,.20);
  /* Deliberately stronger than --shadow-lift. The hover state has to be
     unmistakable on a white page, where a soft shadow reads as nothing. */
  --shadow-hover: 0 6px 14px rgba(47,49,66,.08), 0 24px 48px -20px rgba(47,49,66,.38);

  --step-0: 1rem;
  --step-1: 1.1875rem;
  --step-2: 1.5rem;
  --step-3: 2.125rem;
  --step-4: 2.875rem;

  --gutter: clamp(1rem, 4vw, 3.5rem);
  --maxw: 1180px;
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
[hidden] { display: none !important; }

h1, h2 {
  font-family: "Bricolage Grotesque", "Figtree", ui-sans-serif, system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  text-wrap: balance;
  margin: 0;
}
h3, h4 {
  font-family: "Figtree", ui-sans-serif, system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.2;
  margin: 0;
}
p { margin: 0; }
a { color: inherit; }

.mono {
  font-family: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--peri);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 8px 0;
  font-weight: 600;
  z-index: 100;
}
.skip:focus { left: 0; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- header: full nav bar, collapsed behind Menu on phones ---------- */
.topbar {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 40;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topbar__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 72px;
  flex-wrap: wrap;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-right: auto;
  text-decoration: none;
  color: inherit;
}
.brand__mark { width: 46px; height: 46px; border-radius: 50%; flex: none; }
.brand__name {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.025em;
  line-height: 1.1;
  display: block;
}
.brand__sub { font-size: 0.75rem; color: var(--muted); line-height: 1.2; display: block; }

.nav { display: flex; gap: 0.125rem; align-items: center; flex-wrap: wrap; }
.nav a {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  padding: 0.5rem 0.75rem;
  border-radius: 100px;
  white-space: nowrap;
  transition: background-color .12s ease, color .12s ease;
}
.nav a:hover { color: var(--peri-text); background: var(--peri-soft); }
.nav a[aria-current="page"] { color: #fff; background: var(--peri); }

@media (max-width: 1080px) {
  .topbar__inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.625rem;
    padding-block: 0.875rem;
    min-height: 0;
  }
  .brand { margin-right: 0; }
  .nav { width: 100%; gap: 0.25rem; }
  .nav a { font-size: 0.875rem; padding: 0.4375rem 0.6875rem; }
}

/* Phone menu. Only collapses once js/nav.js has added .nav-js, so the
   links stay visible if JavaScript is off. */
.navtoggle { display: none; }
@media (max-width: 760px) {
  .nav-js .topbar__inner { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .nav-js .brand { margin-right: auto; }
  .nav-js .navtoggle {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1.125rem;
    border: 1px solid var(--line);
    border-radius: 100px;
    background: var(--paper);
    color: var(--text);
    font: 600 0.9375rem/1 "Figtree", sans-serif;
    cursor: pointer;
  }
  .nav-js .topbar.is-open .navtoggle { background: var(--peri-soft); color: var(--peri-text); border-color: transparent; }
  .nav-js .nav { display: none; }
  .nav-js .topbar.is-open .nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.375rem;
    padding-bottom: 0.25rem;
  }
  .nav-js .topbar.is-open .nav a { font-size: 0.9375rem; padding: 0.75rem 1rem; }
}

/* ---------- sections ---------- */
.section { padding-block: clamp(2.75rem, 6vw, 5rem); }
.section--tight { padding-block: clamp(1.75rem, 4vw, 2.75rem); }
.section + .section { border-top: 1px solid var(--line-soft); }

.band-soft { background: var(--soft); border-block: 1px solid var(--line); }
.band-peri { background: var(--peri-soft); border-block: 1px solid var(--line); }
.band-soft + .section, .band-peri + .section { border-top: 0; }

.lede { font-size: var(--step-1); color: var(--muted); max-width: 62ch; }
.pagehead h1 { font-size: var(--step-4); margin-bottom: 1rem; }

/* ---------- hero ---------- */
.hero {
  position: relative;
  isolation: isolate;
  background: var(--paper);
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}
#herocanvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: -1;
}
.hero__inner {
  padding-block: clamp(3.25rem, 10vw, 6rem);
  display: grid;
  justify-items: center;
  text-align: center;
  gap: 1.5rem;
}
.hero__mark {
  width: clamp(92px, 13vw, 124px);
  height: auto;
  border-radius: 50%;
  box-shadow: var(--shadow-lift);
}
.hero h1 {
  /* three lines now, so a lower ceiling than the two line version */
  font-size: clamp(2.5rem, 10.5vw, 6.5rem);
  line-height: 0.9;
  letter-spacing: -0.05em;
  text-transform: uppercase;
  color: var(--peri);
}
.hero h1 span { display: block; }

.fivewords {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.125rem;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: clamp(0.6875rem, 1.6vw, 0.9375rem);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  max-width: 44rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.fivewords li { display: inline-flex; align-items: center; gap: 1.125rem; }
.fivewords li::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--rose);
}
.fivewords li:last-child::after { display: none; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  padding: 0.6875rem 1.375rem;
  border-radius: 100px;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform .12s ease, background-color .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--peri); color: #fff; }
.btn--primary:hover { background: var(--peri-br); }
.btn--ghost { background: var(--surface); color: var(--text); border-color: var(--line); }
.btn--ghost:hover { background: var(--soft); border-color: var(--peri); color: var(--peri-text); }

/* ---------- section heads: ONE title per section ---------- */
.head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.75rem;
}
.head h2 { font-size: var(--step-3); }
.calnote { color: var(--muted); font-size: 0.9375rem; margin: -0.75rem 0 1.25rem; }
/* Events page: "See photos" jumps past the event list to the photo recap */
.pagehead__jump { margin-top: 1.25rem; }
#photos { scroll-margin-top: 5.5rem; } /* clear the sticky header */
.textlink {
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--peri-text);
  text-decoration: none;
  white-space: nowrap;
}
.textlink:hover { text-decoration: underline; }
.flag {
  display: inline-block;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.3125rem 0.625rem;
  border-radius: 100px;
  background: var(--sun-soft);
  color: var(--sun-text);
  font-weight: 600;
}

/* ---------- who we are, vision ---------- */
.define {
  display: grid;
  grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: start;
}
.define h2 { font-size: var(--step-3); }
.define p { font-size: clamp(1.0625rem, 2vw, 1.3125rem); line-height: 1.55; max-width: 58ch; }

.vision {
  display: grid;
  gap: 1.5rem;
  justify-items: center;
  text-align: center;
  max-width: 52rem;
  margin-inline: auto;
}
/* The title has to clearly outrank the quote. Previously both sat at
   roughly the same size in the same weight, so the heading read as the
   first line of the statement rather than as a title. */
.vision h2 {
  font-size: clamp(2rem, 5.5vw, 3.5rem);
  line-height: 1;
}
.vision blockquote {
  position: relative;
  isolation: isolate;
  margin: 0;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: clamp(1.125rem, 2.8vw, 1.75rem);
  line-height: 1.35;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.vision blockquote em {
  font-style: normal;
  background: linear-gradient(var(--sun-mark), var(--sun-mark)) no-repeat 0 0 / 100% 100%;
  padding: 0 0.22em;
  border-radius: 4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* Big faint opening quote behind the statement. */
.vision blockquote::before {
  content: "\201C";
  position: absolute;
  z-index: -1;
  top: -0.3em;
  left: -0.15em;
  font-size: clamp(6rem, 13vw, 9rem);
  font-weight: 800;
  line-height: 1;
  color: var(--peri);
  opacity: 0.14;
  pointer-events: none;
}

/* Word by word blur in, armed by js/vision.js. Without the script the
   statement and its highlights render as they are. */
.vision--armed .vw {
  display: inline-block;
  opacity: 0;
  filter: blur(8px);
  transform: translateY(0.3em);
  transition: opacity .6s ease, filter .6s ease, transform .6s cubic-bezier(.22,.61,.36,1);
  transition-delay: calc(var(--i) * 45ms);
}
.vision--in .vw { opacity: 1; filter: none; transform: none; }
.vision--armed blockquote em {
  background-size: 0% 100%;
  transition: background-size .7s cubic-bezier(.65,0,.35,1);
  transition-delay: calc(var(--words) * 45ms + 350ms);
}
.vision--in blockquote em { background-size: 100% 100%; }

/* ---------- cards ---------- */
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.25rem; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.5rem;
}
.card h3 { font-size: var(--step-1); margin-bottom: 0.5rem; }
.card p { font-size: 0.9375rem; color: var(--muted); }

/* ---------- slideshow ---------- */
.show__frame {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.slide { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); min-height: 340px; }
.slide__photo {
  position: relative;
  min-height: 260px;
  display: grid;
  place-items: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  padding: 1rem;
}
.slide__photo[data-tone="1"] { background: var(--peri-soft); color: var(--peri-text); }
.slide__photo[data-tone="2"] { background: var(--mint-soft); color: var(--mint-text); }
.slide__photo[data-tone="3"] { background: var(--sun-soft);  color: var(--sun-text); }
.slide__photo[data-tone="4"] { background: var(--rose-soft); color: var(--rose-text); }
.slide__img { display: block; width: 100%; height: 100%; min-height: 260px; aspect-ratio: 3 / 2; object-fit: cover; }
.slide__body { padding: clamp(1.5rem, 3vw, 2.25rem); align-self: center; }
.slide__month {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--peri-text);
  font-weight: 700;
}
.slide__body h3 { font-size: var(--step-2); margin: 0.5rem 0 0.75rem; }
.slide__body p { color: var(--muted); font-size: 0.9375rem; max-width: 42ch; }

.show__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}
.dots { display: flex; gap: 0.5rem; }
.dot {
  width: 34px; height: 5px;
  border: 0; padding: 0;
  border-radius: 100px;
  background: var(--line);
  cursor: pointer;
}
.dot[aria-current="true"] { background: var(--peri); }

.arrows { display: flex; gap: 0.5rem; }
.arrow {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
  font-size: 1.125rem;
  line-height: 1;
  font-weight: 700;
}
.arrow:hover { background: var(--peri-soft); color: var(--peri-text); border-color: var(--peri); }

/* ---------- calendar ---------- */
.calbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}
.calbar__month {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: var(--step-2);
  letter-spacing: -0.03em;
}
.calgrid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}
.caldow {
  background: var(--soft);
  color: var(--muted);
  padding: 0.625rem 0.25rem;
  text-align: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
}
.calday {
  background: var(--surface);
  min-height: 94px;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.75rem;
}
.calday--out { background: var(--soft); }
.calday__n {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  color: var(--muted);
  font-weight: 600;
}
.calday--out .calday__n { opacity: .4; }
.calday--today .calday__n {
  background: var(--peri);
  color: #fff;
  border-radius: 50%;
  width: 1.375rem;
  height: 1.375rem;
  display: grid;
  place-items: center;
}
.calpill {
  display: block;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.25;
  border-radius: 6px;
  padding: 0.3125rem 0.4375rem;
  background: var(--peri-soft);
  color: var(--peri-text);
}
.calpill[data-cat="dues"]    { background: var(--sun-soft);  color: var(--sun-text); }
.calpill[data-cat="service"] { background: var(--mint-soft); color: var(--mint-text); }
.calpill[data-cat="tickets"] { background: var(--rose-soft); color: var(--rose-text); }
.calpill[data-cat="general"] { background: var(--peri-soft); color: var(--peri-text); }
.calpill[data-cat="school"]  { background: var(--rose-soft); color: var(--rose-text); }

.calempty {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.9375rem;
  background: var(--soft);
  border: 1px dashed var(--line);
  border-radius: 14px;
  margin-top: 1rem;
}
.callist { display: grid; gap: 0.75rem; margin-top: 1.25rem; }

/* A seven column grid is unusable on a phone, so drop to the list only. */
@media (max-width: 680px) { .calgrid { display: none; } }

/* ---------- events ---------- */
.events { display: grid; gap: 0.75rem; }
.event {
  display: grid;
  grid-template-columns: 74px minmax(0,1fr) auto;
  gap: 1.25rem;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1rem 1.25rem;
}
.datechip {
  text-align: center;
  border-right: 1px solid var(--line);
  padding-right: 1rem;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}
.datechip__m { display: block; font-size: 0.6875rem; letter-spacing: 0.1em; color: var(--peri-text); font-weight: 700; }
.datechip__d { display: block; font-size: 1.5rem; font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; }
/* Multi-day events show "26–30"; smaller so five characters fit the chip */
.datechip__d--range { font-size: 1rem; line-height: 1.65; letter-spacing: -0.05em; white-space: nowrap; }
.event__title { font-size: var(--step-1); font-weight: 700; letter-spacing: -0.015em; }
.event__meta {
  font-size: 0.875rem;
  color: var(--muted);
  margin-top: 0.1875rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.875rem;
}

.tag {
  display: inline-block;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.3125rem 0.625rem;
  border-radius: 100px;
  background: var(--soft);
  color: var(--muted);
  font-weight: 600;
}
.tag--spirit  { background: var(--peri-soft); color: var(--peri-text); }
.tag--service { background: var(--mint-soft); color: var(--mint-text); }
.tag--dues    { background: var(--sun-soft);  color: var(--sun-text); }
.tag--tickets { background: var(--rose-soft); color: var(--rose-text); }
.tag--general { background: var(--peri-soft); color: var(--peri-text); }
.tag--school  { background: var(--rose-soft); color: var(--rose-text); }

.monthhead {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: var(--step-2);
  letter-spacing: -0.03em;
  margin: 2rem 0 1rem;
  padding-bottom: 0.625rem;
  border-bottom: 1px solid var(--line);
}
.monthhead:first-of-type { margin-top: 0; }

/* ---------- team ---------- */
.sponsor {
  display: grid;
  grid-template-columns: 150px minmax(0,1fr);
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: center;
  background: var(--peri-soft);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: clamp(1.25rem, 3vw, 2rem);
}
.sponsor__photo {
  aspect-ratio: 1;
  max-width: 100%;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  display: grid;
  place-items: center;
  text-align: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.75rem;
  object-fit: cover;
}
.sponsor__role {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--peri-text);
}
.sponsor__name {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: clamp(1.75rem, 4.5vw, 2.5rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin-top: 0.375rem;
}
/* :not([class]) so this only hits the plain blurb paragraph. Without it
   this rule outranks .sponsor__name and .sponsor__role on specificity
   and silently shrinks them to body size. */
.sponsor p:not([class]) { margin-top: 0.625rem; font-size: 0.9375rem; color: var(--muted); max-width: 46ch; }

.people { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1rem; }
.person {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}
.person__photo {
  aspect-ratio: 4 / 5;
  max-width: 100%;
  display: grid;
  place-items: center;
  background: var(--soft);
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.5rem;
  object-fit: cover;
}
.person--exec .person__photo { background: var(--peri-soft); color: var(--peri-text); }
.person--sr   .person__photo { background: var(--rose-soft); color: var(--rose-text); }
.person--jr   .person__photo { background: var(--mint-soft); color: var(--mint-text); }
.person--so   .person__photo { background: var(--sun-soft);  color: var(--sun-text); }
.person--fr   .person__photo { background: var(--soft);      color: var(--muted); }
.person__body { padding: 0.9375rem 1rem 1.125rem; }
.person__role {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--peri-text);
  font-weight: 700;
}
.person__name { font-weight: 700; font-size: 1.0625rem; margin-top: 0.3125rem; letter-spacing: -0.02em; line-height: 1.2; }
.person__note { font-size: 0.8125rem; color: var(--muted); margin-top: 0.375rem; }

.repblock { margin-bottom: 2rem; }
.repblock h3 {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.025em;
  margin-bottom: 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.875rem;
}
.repblock h3::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.repnames { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; padding: 0; list-style: none; }
.repnames li {
  border-radius: 100px;
  padding: 0.4375rem 0.9375rem;
  font-size: 0.9375rem;
  font-weight: 600;
}
.repnames li:nth-child(4n+1) { background: var(--peri-soft); color: var(--peri-text); }
.repnames li:nth-child(4n+2) { background: var(--mint-soft); color: var(--mint-text); }
.repnames li:nth-child(4n+3) { background: var(--sun-soft);  color: var(--sun-text); }
.repnames li:nth-child(4n)   { background: var(--rose-soft); color: var(--rose-text); }

/* ---------- notices ---------- */
.notice {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  background: var(--sun-soft);
  color: var(--sun-text);
  border: 1px solid color-mix(in srgb, var(--sun) 45%, transparent);
  border-radius: 12px;
  padding: 0.875rem 1.125rem;
  font-size: 0.875rem;
  margin-bottom: 1.75rem;
}

/* ---------- posts ---------- */
.posts { display: grid; gap: 1rem; }
.post {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: 158px minmax(0,1fr);
  gap: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1.75rem 1.875rem 1.75rem 2.125rem;
  transition:
    transform .2s cubic-bezier(.22,.61,.36,1),
    box-shadow .2s cubic-bezier(.22,.61,.36,1),
    border-color .15s ease,
    background-color .15s ease;
}

/* A colored spine down the left, keyed to what the post is about. */
.post::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 5px;
  background: var(--peri);
}
.post--spirit::before  { background: var(--peri); }
.post--dues::before    { background: var(--sun); }
.post--service::before { background: var(--mint); }
.post--general::before { background: var(--rose); }

.post:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-hover);
  border-color: var(--peri-br);
  background: color-mix(in srgb, var(--peri-soft) 35%, var(--surface));
}
.post__date {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.8125rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  padding-top: 0.25rem;
  font-weight: 600;
}
.post h3 { font-size: var(--step-2); margin-bottom: 0.5rem; }
.post p { color: var(--muted); max-width: 66ch; }
.post__tags { display: flex; gap: 0.5rem; margin-top: 0.875rem; flex-wrap: wrap; }

/* ---------- gallery ---------- */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0.75rem; }
.shot {
  position: relative;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  cursor: zoom-in;
  padding: 0;
  display: grid;
  align-content: end;
  text-align: left;
  font: inherit;
  background: var(--peri-soft);
  color: var(--peri-text);
}
.shot:nth-child(4n+2) { background: var(--mint-soft); color: var(--mint-text); }
.shot:nth-child(4n+3) { background: var(--sun-soft);  color: var(--sun-text); }
.shot:nth-child(4n)   { background: var(--rose-soft); color: var(--rose-text); }
.shot__cap { position: relative; padding: 0.875rem 1rem; font-size: 0.875rem; font-weight: 700; line-height: 1.3; }
.shot__cap span {
  display: block;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 0.25rem;
  font-weight: 500;
  opacity: .8;
}
.shot:hover { border-color: var(--peri); }

/* A <dialog> is hidden by the browser via dialog:not([open]){display:none}.
   Setting display here unconditionally overrides that and leaves the
   dialog permanently on screen with no way to close it. Scope the
   display to [open] so the browser can still hide it. */
.lightbox:not([open]) { display: none; }

.lightbox[open] {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgba(47,49,66,.55);
  backdrop-filter: blur(4px);
  border: 0;
  max-width: 100%;
  max-height: 100%;
  width: 100%;
  height: 100%;
}
.lightbox::backdrop { background: rgba(47,49,66,.55); }
.lightbox__panel {
  background: var(--surface);
  border-radius: 18px;
  max-width: 640px;
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
}
.lightbox__img {
  aspect-ratio: 3 / 2;
  max-width: 100%;
  background: var(--peri-soft);
  color: var(--peri-text);
  display: grid;
  place-items: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  object-fit: cover;
}
.lightbox__meta { padding: 1.25rem 1.5rem 1.5rem; }
.lightbox__meta h3 { font-size: var(--step-1); }
.lightbox__meta p { font-size: 0.875rem; color: var(--muted); margin-top: 0.375rem; }

/* ---------- forms ---------- */
.form { display: grid; gap: 1.125rem; }
.field { display: grid; gap: 0.4375rem; }
.field > label { font-size: 0.875rem; font-weight: 600; }
.field__hint { font-size: 0.8125rem; color: var(--muted); }

input, select, textarea {
  font: inherit;
  font-size: 0.9375rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.6875rem 0.875rem;
  width: 100%;
}
input:hover, select:hover, textarea:hover { border-color: var(--peri-br); }
textarea { min-height: 130px; resize: vertical; }

:is(input, select, textarea, button, a, summary):focus-visible {
  outline: 2px solid var(--peri);
  outline-offset: 2px;
}

.row2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap: 1.125rem; }
.error { color: var(--rose-text); font-size: 0.8125rem; font-weight: 600; }

/* Spam honeypot. Must stay visually hidden but not display:none,
   since some bots skip hidden fields. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.sent {
  background: var(--mint-soft);
  border: 1px solid color-mix(in srgb, var(--mint) 40%, transparent);
  border-radius: 14px;
  padding: 1.5rem;
}
.sent h3 { color: var(--mint-text); font-size: var(--step-1); margin-bottom: 0.5rem; }
.sent p { font-size: 0.9375rem; color: var(--muted); }

.contactbox {
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.75rem;
  align-self: start;
}
.contactbox h2 { font-size: var(--step-2); margin-bottom: 1.25rem; }
.deflist { display: grid; gap: 1rem; margin: 0; }
.deflist dt {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.deflist dd { margin: 0.1875rem 0 0; font-size: 0.9375rem; font-weight: 600; }
.deflist dd a { color: var(--peri-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* ---------- dues ---------- */
.dues {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0, 300px);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
/* Price card on the Dues page. */
.price {
  background: var(--peri-soft);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: clamp(1.75rem, 4vw, 2.75rem);
}
.price__amt {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: clamp(3.5rem, 10vw, 5.5rem);
  line-height: 1;
  letter-spacing: -0.05em;
  color: var(--peri);
}
.price__amt span {
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--peri-text);
}
.price__facts { display: grid; gap: 0.625rem; margin: 1.25rem 0 1.75rem; padding: 0; list-style: none; }
.price__facts li { display: flex; gap: 0.75rem; font-size: 1.125rem; font-weight: 600; align-items: baseline; }
.price__facts li::before { content: "\25CF"; color: var(--peri); font-size: 0.5625rem; }

/* How paying works, under the price card. */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.steps li {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1.5rem;
}
.steps__n {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--peri);
  color: #fff;
  font-weight: 700;
  margin-bottom: 1rem;
}
.steps h2 { font-size: var(--step-1); margin-bottom: 0.375rem; }
.steps p { color: var(--muted); font-size: 0.9375rem; }
.steps__note { margin-top: 1.25rem; color: var(--muted); }
.qr {
  aspect-ratio: 1;
  max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  display: grid;
  place-items: center;
  gap: 0.625rem;
  text-align: center;
  padding: 1.5rem;
  color: var(--muted);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
}
.qr__grid {
  width: 96px;
  height: 96px;
  background-image:
    linear-gradient(90deg, var(--line) 1px, transparent 1px),
    linear-gradient(var(--line) 1px, transparent 1px);
  background-size: 12px 12px;
  border: 3px solid var(--peri);
  border-radius: 4px;
}
.duesstrip { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.duesstrip h2 { font-size: var(--step-3); }
.duesstrip p { margin-top: 0.375rem; font-size: 1.125rem; font-weight: 600; color: var(--muted); }

/* ---------- sponsors ---------- */
.sponsorlead {
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0, 320px);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  background: var(--peri-soft);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: clamp(1.5rem, 4vw, 2.5rem);
}
.sponsorlead h2 { font-size: var(--step-3); margin-bottom: 0.75rem; }
.sponsorlead p { color: var(--muted); max-width: 52ch; }
.sponsorlead .btn { margin-top: 1.5rem; }
.paycard {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1.5rem;
  text-align: center;
}
.paycard__amt {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 2.25rem;
  letter-spacing: -0.03em;
  color: var(--peri);
}
.paycard__note { font-size: 0.875rem; color: var(--muted); margin-top: 0.5rem; }

.tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }
.tier {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.tier__band { height: 6px; border-radius: 100px; width: 46px; }
.tier--1 .tier__band { background: var(--mint); }
.tier--2 .tier__band { background: var(--peri); }
.tier--3 .tier__band { background: var(--sun); }
.tier--4 .tier__band { background: var(--rose); }
.tier h3 { font-size: var(--step-1); }
.tier__amt {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--peri-text);
  font-variant-numeric: tabular-nums;
}
.tier ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.5rem; }
.tier li { font-size: 0.9375rem; color: var(--muted); display: flex; gap: 0.625rem; align-items: baseline; }
.tier li::before { content: "\25CF"; color: var(--line); font-size: 0.5rem; }

/* ---------- socials ---------- */
.socials { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1rem; }
.social {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1.25rem;
  text-decoration: none;
  color: inherit;
}
.social:hover { background: var(--soft); border-color: var(--peri); }
.social__icon { width: 44px; height: 44px; flex: none; }
.social__h { font-weight: 700; font-size: 1.0625rem; letter-spacing: -0.015em; display: block; }
.social__at { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 0.8125rem; color: var(--muted); }

/* ---------- call to action ---------- */
.cta {
  background: var(--peri-soft);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: clamp(1.75rem, 4vw, 2.75rem);
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  gap: 1.5rem;
  align-items: center;
}
.cta h2 { font-size: var(--step-3); margin-bottom: 0.5rem; }
.cta h2 em { font-style: normal; color: var(--peri-text); }
.cta p { color: var(--muted); max-width: 52ch; }

/* ---------- footer, light, never dark ---------- */
.foot {
  background: var(--soft);
  color: var(--muted);
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border-top: 1px solid var(--line);
  padding-block: clamp(2rem, 5vw, 3rem) 2rem;
}
.foot__connect {
  padding-bottom: 2rem;
  margin-bottom: 2rem;
  border-bottom: 1px solid var(--line);
}
.foot__connect h2 { font-size: var(--step-2); color: var(--text); margin-bottom: 1rem; }
/* .foot a below is for the small text links; the cards keep their own look. */
.foot a.social { color: var(--text); font-size: inherit; }
.foot a.social:hover { color: var(--text); }
.foot__grid {
  display: grid;
  grid-template-columns: minmax(0,1.4fr) minmax(0,1fr);
  gap: 2rem;
  padding-bottom: 2rem;
  border-bottom: 1px solid var(--line);
}
.foot__brand { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; }
.foot__brand img { width: 46px; height: 46px; border-radius: 50%; }
.foot__brand span {
  color: var(--text);
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  letter-spacing: -0.025em;
}
.foot h4 { font-size: 0.8125rem; color: var(--text); margin-bottom: 0.875rem; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.625rem; }
.foot a { font-size: 0.875rem; color: var(--muted); text-decoration: none; }
.foot a:hover { color: var(--peri-text); }
.foot__note { font-size: 0.8125rem; max-width: 40ch; }
.foot__legal {
  padding-top: 1.5rem;
  font-size: 0.75rem;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ---------- narrow ---------- */
@media (max-width: 880px) {
  .define { grid-template-columns: 1fr; }
  .slide { grid-template-columns: 1fr; }
  .dues, .sponsorlead { grid-template-columns: 1fr; }
  .dues .qr { max-width: 260px; }
  .cta { grid-template-columns: 1fr; }
  .foot__grid { grid-template-columns: 1fr 1fr; }
  .sponsor { grid-template-columns: 1fr; justify-items: start; }
  /* element+class to outrank img.sponsor__photo above */
  .sponsor img.sponsor__photo { width: 130px; }
}

@media (max-width: 560px) {
  :root { --step-4: 2.125rem; --step-3: 1.75rem; }
  .event { grid-template-columns: 62px minmax(0,1fr); row-gap: 0.75rem; }
  .event > .tag { grid-column: 2; justify-self: start; }
  .post { grid-template-columns: 1fr; gap: 0.5rem; }
  .post__date { padding-top: 0; }
  .foot__grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   MOTION
   Everything here is opt in. reveal.js adds .reveal-on to <html>
   only when IntersectionObserver exists and the visitor has not
   asked for reduced motion. Without that class every rule below
   is inert and the page renders fully visible, which is what a
   crawler, a no-JS browser, and a motion sensitive visitor get.
   ============================================================ */

/* ---------- scroll reveal ---------- */
.reveal-on [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity .75s cubic-bezier(.22,.61,.36,1),
    transform .75s cubic-bezier(.22,.61,.36,1);
}
.reveal-on [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Children of a grid arrive one after another rather than all at once.
   --i is set per child by reveal.js and capped so long lists stay snappy. */
.reveal-on [data-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity .6s cubic-bezier(.22,.61,.36,1),
    transform .6s cubic-bezier(.22,.61,.36,1);
  transition-delay: calc(var(--i, 0) * 65ms);
}
.reveal-on [data-reveal-stagger].is-in > * {
  opacity: 1;
  transform: none;
}

/* ---------- hero entrance ---------- */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}
@keyframes markIn {
  from { opacity: 0; transform: translateY(20px) scale(.92); }
  to   { opacity: 1; transform: none; }
}

.reveal-on .hero__mark {
  animation: markIn .8s cubic-bezier(.22,.61,.36,1) both;
}

/* ---------- hover lift ---------- */
/* Only on things that genuinely read as a pickable object. Lifting
   every block flattens the hierarchy rather than adding to it. */
.card, .person, .social, .tier, .shot, .event {
  transition:
    transform .2s cubic-bezier(.22,.61,.36,1),
    box-shadow .2s cubic-bezier(.22,.61,.36,1),
    border-color .15s ease;
}
.card:hover, .person:hover, .social:hover, .tier:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-hover);
}
.shot:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); }
.event:hover { border-color: var(--peri-br); }

.repnames li {
  transition: transform .18s cubic-bezier(.22,.61,.36,1);
}
.repnames li:hover { transform: translateY(-2px); }

/* ---------- nav and buttons ---------- */
.nav a { position: relative; }

.btn {
  transition:
    transform .15s cubic-bezier(.22,.61,.36,1),
    background-color .15s ease,
    box-shadow .2s ease;
}
.btn--primary:hover { box-shadow: 0 6px 18px -6px rgba(92,99,166,.55); transform: translateY(-1px); }
.btn--primary:active { transform: translateY(0); }

.arrow { transition: transform .18s cubic-bezier(.22,.61,.36,1), background-color .15s ease, color .15s ease, border-color .15s ease; }
.arrow:hover { transform: scale(1.08); }

.brand__mark, .hero__mark { transition: transform .3s cubic-bezier(.22,.61,.36,1); }
.brand:hover .brand__mark { transform: rotate(-6deg) scale(1.05); }

/* ---------- slideshow crossfade ---------- */
.reveal-on .slide:not([hidden]) {
  animation: riseIn .5s cubic-bezier(.22,.61,.36,1) both;
}

/* ---------- smooth anchor scrolling ---------- */
html { scroll-behavior: smooth; }

/* The global prefers-reduced-motion block near the top of this file
   already kills every animation and transition, and .reveal-on is never
   added in that case, so nothing above needs its own guard. */

/* ---------- typewriter ---------- */
/* typing.js locks the measured height before it empties these, so the
   hero does not collapse and then shove the page down as text arrives. */

@keyframes caretBlink {
  0%, 45%  { opacity: 1; }
  55%, 100% { opacity: 0; }
}

.caret::after {
  content: "";
  display: inline-block;
  width: 0.07em;
  height: 0.82em;
  margin-left: 0.06em;
  vertical-align: baseline;
  background: currentColor;
  animation: caretBlink 1s step-end infinite;
}

/* The dot separator belongs to the word, so keep it off until the word
   has started typing. */
.fivewords li.is-pending { visibility: hidden; }
.fivewords li.caret::after { display: none; }
.fivewords li.caret {
  border-right: 2px solid var(--rose);
  padding-right: 0.3em;
  animation: caretBlink 1s step-end infinite;
}

.hero h1 .caret::after { background: var(--peri); }

/* ---------- dues card ---------- */
/* Same component as the "Got an idea" card, tinted differently so two
   identical blocks do not sit on top of each other. */
.cta--dues {
  background: var(--sun-soft);
  border-color: color-mix(in srgb, var(--sun) 40%, transparent);
}
.cta--dues h2 em { color: var(--sun-text); }
.cta--dues p { color: var(--sun-text); }

/* ============================================================
   FEATURE PANELS
   Big statement blocks that need to carry weight on a white page.
   The tinted wash plus the logo watermark does the lifting, so the
   type itself can stay calm.
   ============================================================ */

.panel {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 22px;
  border: 1px solid var(--line);
  background:
    radial-gradient(90% 120% at 8% 0%,   color-mix(in srgb, var(--peri) 16%, transparent) 0%, transparent 58%),
    radial-gradient(80% 110% at 95% 15%, color-mix(in srgb, var(--mint) 15%, transparent) 0%, transparent 55%),
    radial-gradient(90% 120% at 70% 100%, color-mix(in srgb, var(--sun)  20%, transparent) 0%, transparent 60%),
    var(--surface);
  padding: clamp(1.75rem, 5vw, 3.5rem);
  box-shadow: var(--shadow);
}

/* The wolf, very faint, bleeding off the right edge. */
.panel::after {
  content: "";
  position: absolute;
  z-index: -1;
  right: -4%;
  bottom: -28%;
  width: clamp(190px, 30vw, 330px);
  aspect-ratio: 1;
  background: var(--panel-mark) center / contain no-repeat;
  /* logo.jpg is a square with a solid background, so clip it to a circle
     or the watermark reads as a grey box instead of the wolf badge. */
  border-radius: 50%;
  opacity: .10;
  pointer-events: none;
}

.panel__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.38fr);
  gap: clamp(1.25rem, 4vw, 3.5rem);
  align-items: start;
}
.panel h2 {
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 0.98;
}
.panel h2 .accent { color: var(--peri); display: block; }

.panel__body {
  font-size: clamp(1.125rem, 2.1vw, 1.4375rem);
  line-height: 1.5;
  max-width: 54ch;
  font-weight: 500;
}
.panel__body strong {
  font-weight: 700;
  background: var(--sun-mark);
  padding: 0 0.2em;
  /* pull following punctuation back against the highlight so a comma
     does not float away from the phrase it belongs to */
  margin-right: -0.12em;
  border-radius: 4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* A rule that picks up the brand colors, used under a panel heading. */
.panel__rule {
  width: 72px;
  height: 5px;
  border-radius: 100px;
  margin-top: 1.25rem;
  background: linear-gradient(90deg, var(--peri), var(--mint) 45%, var(--sun) 75%, var(--rose));
}

@media (max-width: 880px) {
  .panel__grid { grid-template-columns: 1fr; }
  .panel::after { opacity: .06; }
}

/* ---------- accent cards ---------- */
/* A colored top edge so a row of cards reads as a set of distinct
   things rather than three identical grey boxes. */
.card--accent { position: relative; overflow: hidden; padding-top: 1.75rem; }
.card--accent::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 5px;
}
.card--peri::before { background: var(--peri); }
.card--mint::before { background: var(--mint); }
.card--sun::before  { background: var(--sun); }
.card--rose::before { background: var(--rose); }

.card--accent h3 { font-size: var(--step-2); }
.card__lede { font-size: 1rem; color: var(--muted); }

/* ============================================================
   UNIVERSAL CARD HOVER
   Every card shaped block lifts and gains a shadow on hover, so
   the behaviour is consistent wherever a card appears rather than
   only on the few that happened to get it first.
   ============================================================ */
.card,
.person,
.social,
.tier,
.shot,
.post,
.panel,
.cta,
.contactbox,
.sponsor,
.sponsorlead,
.paycard,
.qr,
.show__frame {
  transition:
    transform .2s cubic-bezier(.22,.61,.36,1),
    box-shadow .2s cubic-bezier(.22,.61,.36,1),
    border-color .15s ease,
    background-color .15s ease;
}

.card:hover,
.person:hover,
.social:hover,
.tier:hover,
.shot:hover,
.post:hover,
.panel:hover,
.cta:hover,
.contactbox:hover,
.sponsor:hover,
.sponsorlead:hover,
.paycard:hover,
.qr:hover,
.show__frame:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-hover);
}

/* Give the blocks that had no border a visible edge on hover so the
   lift reads as deliberate rather than as the block drifting. */
.cta:hover, .panel:hover, .sponsor:hover, .sponsorlead:hover {
  border-color: var(--peri-br);
}
.cta--dues:hover { border-color: var(--sun); }

/* Resting shadow on the big statement blocks so they sit above the
   page rather than flat on it. */
.panel, .cta, .contactbox, .sponsor, .sponsorlead { box-shadow: var(--shadow); }

/* ---------- album slideshow inside the lightbox ---------- */
.lb__stage {
  position: relative;
  aspect-ratio: 3 / 2;
  background: var(--peri-soft);
  border-bottom: 1px solid var(--line);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.lb__stage img { width: 100%; height: 100%; object-fit: cover; }
.lb__empty {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--peri-text);
  text-align: center;
  padding: 1rem;
}
.lb__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  color: var(--text);
  font: inherit;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  backdrop-filter: blur(6px);
}
.lb__nav:hover { background: var(--surface); border-color: var(--peri); }
.lb__nav--prev { left: 12px; }
.lb__nav--next { right: 12px; }
.lb__nav[hidden] { display: none !important; }

.lb__count {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 0.25rem 0.625rem;
  backdrop-filter: blur(6px);
}

/* ---------- album button on the home slideshow ---------- */
.show__cta {
  display: flex;
  justify-content: flex-end;
  margin-top: 1rem;
}
@media (max-width: 560px) {
  .show__controls { justify-content: center; }
  .show__cta { justify-content: stretch; }
  .show__cta .btn { width: 100%; }
}

/* ---------- dues QR ---------- */
.qr img { width: 100%; max-width: 210px; height: auto; border-radius: 8px; }

/* ---------- embedded PDF viewer ---------- */
.pdfbox {
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--soft);
  box-shadow: var(--shadow);
}
#pdfviewer {
  display: grid;
  gap: 1rem;
  padding: clamp(0.75rem, 2vw, 1.25rem);
  max-height: min(82vh, 1000px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.pdfpage {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
  box-shadow: var(--shadow);
  background: #fff;
}
.pdfstatus {
  padding: 2.5rem 1rem;
  text-align: center;
  color: var(--muted);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
}
.pdfstatus[hidden] { display: none !important; }
.pdffallback[hidden] { display: none !important; }
/* Shown only when the browser cannot render a PDF inline, which is most
   phones. Without this the box would just be blank on mobile. */
.pdffallback {
  padding: clamp(1.5rem, 5vw, 2.5rem);
  text-align: center;
  display: grid;
  gap: 1rem;
  justify-items: center;
}
.pdffallback p { color: var(--muted); max-width: 44ch; }
.pdfactions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.25rem; }

/* ---------- officer contact button ---------- */
.person__contact {
  display: inline-block;
  margin-top: 0.875rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--peri-text);
  background: var(--peri-soft);
  border: 1px solid transparent;
  border-radius: 100px;
  padding: 0.375rem 0.8125rem;
  transition: background-color .15s ease, border-color .15s ease;
}
.person__contact:hover { background: var(--surface); border-color: var(--peri); }

.field--prefilled select {
  border-color: var(--peri);
  background: var(--peri-soft);
}

/* Photos are plain <img>, not <picture>. With display:contents on a
   picture the <source> element also becomes a grid item and steals the
   first column, which pushed the sponsor photo into the text column.
   The files are small enough that a webp variant was not worth it. */

img.person__photo {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 22%;
}

img.sponsor__photo {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: center 20%;
}

/* ---------- group photos ---------- */
.groupshot {
  margin: 0;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--soft);
  box-shadow: var(--shadow);
  transition: transform .2s cubic-bezier(.22,.61,.36,1), box-shadow .2s cubic-bezier(.22,.61,.36,1);
}
.groupshot:hover { transform: translateY(-5px); box-shadow: var(--shadow-hover); }
.groupshot img {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
.groupshot figcaption {
  padding: 0.875rem 1.25rem;
  border-top: 1px solid var(--line);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}

/* The whole council shot leads the page, so it runs wider and taller. */
.groupshot--hero img { aspect-ratio: 16 / 9; }
.groupshot--class { margin-bottom: 1.25rem; }

/* ---------- finished events ---------- */
/* The row recedes but the badge does not. Fading specific elements
   rather than setting opacity on the whole row, because opacity on a
   parent cannot be undone by a child, and that was dimming the badge
   along with everything else. */
.event--done { background: var(--soft); }
.event--done .event__title,
.event--done .event__meta,
.event--done .datechip__m,
.event--done .datechip__d { color: var(--muted); }

.tag--done {
  background: var(--mint);
  color: var(--text);
  font-weight: 700;
  letter-spacing: 0.1em;
  box-shadow: 0 1px 2px rgba(47,49,66,.12);
}
.tag--done::before {
  content: "\2713";
  margin-right: 0.375rem;
  font-weight: 700;
}
/* Both tags share the one tag cell so neither wraps onto its own row. */
.event__tags {
  display: flex;
  gap: 0.375rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}
@media (max-width: 560px) {
  .event > .event__tags { grid-column: 2; justify-self: start; }
  .event__tags { justify-content: flex-start; }
}

/* ---------- next event + folded past events (eventstatus.js) ---------- */
/* The next unfinished event gets an outline and a solid badge so it is
   the first thing seen on the page. */
.event--next { border-color: var(--peri); box-shadow: 0 0 0 1px var(--peri); }
.tag--next {
  background: var(--peri);
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.1em;
}

/* Finished events live in a collapsed section under the upcoming ones. */
.pastevents {
  margin-top: 2.5rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
}
.pastevents > summary {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 1rem 1.25rem;
  cursor: pointer;
  list-style: none;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
}
.pastevents > summary::-webkit-details-marker { display: none; }
.pastevents > summary::after {
  content: "";
  margin-left: auto;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg);
  transition: transform .2s ease;
}
.pastevents[open] > summary::after { transform: rotate(225deg); }
.pastevents > summary:hover { color: var(--peri-text); }
.pastevents__count {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.1875rem 0.5rem;
  border-radius: 100px;
  background: var(--soft);
  color: var(--muted);
}
.pastevents__body { padding: 0.5rem 1.25rem 1.25rem; border-top: 1px solid var(--line); }
.pastevents__body .monthhead { font-size: var(--step-1); margin-top: 1.5rem; }
.pastevents__body .monthhead:first-child { margin-top: 0.75rem; }

/* ---------- album cover photos ---------- */
/* A tile with photos shows its first one as the cover. Tiles without
   photos keep the flat tint, so an album that is still waiting on
   pictures still looks deliberate rather than broken. */
.shot__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.shot--photo .shot__cap {
  color: #FFFFFF;
  background: linear-gradient(to top, rgba(23,22,28,.85), rgba(23,22,28,.35) 55%, transparent);
  padding-top: 2rem;
}
.shot--photo .shot__cap span { color: rgba(255,255,255,.85); opacity: 1; }
.shot--photo .shot__img { transition: transform .35s cubic-bezier(.22,.61,.36,1); }
.shot--photo:hover .shot__img { transform: scale(1.04); }

/* ---------- clubs directory (clubs.js) ---------- */
/* Each club is a card with just its name; the details open in the
   shared lightbox dialog. */
.clubs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
}
.clubs > .calempty { grid-column: 1 / -1; }
.club {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.75rem;
  aspect-ratio: 1 / 1;
  min-width: 0;
  padding: 1.5rem 1.25rem 1.125rem;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  cursor: pointer;
  transition:
    transform .2s cubic-bezier(.22,.61,.36,1),
    box-shadow .2s cubic-bezier(.22,.61,.36,1),
    border-color .15s ease;
}
.club:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); border-color: var(--peri-br); }
.club__name {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  line-height: 1.15;
  overflow-wrap: break-word;
  hyphens: auto;
}
.club__more {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--peri-text);
}
.club__more::after { content: " \2192"; }
.club__foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
/* Small marker on clubs that need a tryout, a class, or similar. */
.club__req {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 0.1875rem 0.5rem;
  border-radius: 100px;
  background: var(--sun-soft);
  color: var(--sun-text);
}

/* Category groups, each with its own heading and count. */
.clubgroup { scroll-margin-top: 5.5rem; }
.clubgroup + .clubgroup { margin-top: 2.75rem; }
.clubgroup__head { display: flex; align-items: center; gap: 0.625rem; }
.clubgroup__count {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
  padding: 0.1875rem 0.5rem;
  border-radius: 100px;
  background: var(--soft);
  color: var(--muted);
}

/* Category pills at the top of the page jump to each group. */
.clubjump {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2rem;
}
.clubjump[hidden] { display: none; }
.clubjump__pill {
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.5rem 0.9375rem;
  border-radius: 100px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.clubjump__pill:hover { background: var(--peri-soft); border-color: var(--peri); color: var(--peri-text); }

/* ----- the club popup ----- */
.clubdlg .lightbox__panel { max-width: 540px; max-height: calc(100vh - 2rem); overflow-y: auto; }
.clubdlg .lightbox__meta { padding: 1.75rem 1.75rem 1.5rem; }
.clubdlg .lightbox__meta h3 { font-size: var(--step-2); letter-spacing: -0.02em; margin-top: 0.625rem; line-height: 1.1; }
.clubdlg .flag[hidden] { display: none; }

.clubdlg__chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.875rem; }
.chip {
  font-size: 0.8125rem;
  font-weight: 600;
  padding: 0.3125rem 0.75rem;
  border-radius: 100px;
  line-height: 1.35;
}
.chip--open { background: var(--mint-soft); color: var(--mint-text); }
.chip--req  { background: var(--sun-soft);  color: var(--sun-text); }
.chip--fee  { background: var(--soft); color: var(--text); border: 1px solid var(--line); }

.clubdlg .clubdlg__about { font-size: 1rem; line-height: 1.55; color: var(--text); margin-top: 1.125rem; }
.clubdlg__does {
  margin: 0.75rem 0 0;
  padding-left: 1.125rem;
  font-size: 0.9375rem;
  color: var(--muted);
}
.clubdlg__does li + li { margin-top: 0.375rem; }
.clubdlg__does[hidden], .clubdlg__about[hidden], .clubdlg__facts[hidden], .clubdlg__social[hidden] { display: none; }

.clubdlg__facts {
  margin: 1.25rem 0 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--soft);
}
.clubdlg__facts > div {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 0.75rem;
  padding: 0.75rem 0.875rem;
}
.clubdlg__facts > div + div { border-top: 1px solid var(--line); }
.clubdlg__facts dt {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
  padding-top: 0.1875rem;
}
.clubdlg__facts dd { margin: 0; font-size: 0.9375rem; }
.clubdlg__people { display: grid; gap: 0.5rem; }
.clubdlg__person { display: block; }
.clubdlg__pname { display: block; font-weight: 600; }
.clubdlg__person a {
  display: block;
  font-size: 0.8125rem;
  color: var(--peri-text);
  overflow-wrap: anywhere;
}

.clubdlg__social { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.social-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.875rem 0.375rem 0.375rem;
  border-radius: 100px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition: border-color .12s ease, background-color .12s ease;
}
.social-pill:hover { border-color: var(--peri); background: var(--peri-soft); }
.social-pill__site {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: 100px;
  background: var(--peri);
  color: #fff;
}

@media (max-width: 480px) {
  .clubdlg .lightbox__meta { padding: 1.5rem 1.25rem 1.25rem; }
  .clubdlg__facts > div { grid-template-columns: 1fr; gap: 0.25rem; }
}
/* Two squares per row on phones; one full-width square would be huge. */
@media (max-width: 480px) {
  .clubs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
  .club { padding: 1.25rem 1rem 1rem; }
  .club__name { font-size: 1.0625rem; }
}

/* ---------- newsletter (The Pack) ---------- */
/* One big card that links out to Substack. Same soft color wash and
   faint wolf watermark as the "Who we are" panel, plus a little stack of
   newspaper sheets drawn in CSS that fans out on hover. The whole card
   is the link, so it is one tap target on a phone. */
.newscard {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: center;
  gap: clamp(1.5rem, 5vw, 4rem);
  padding: clamp(1.75rem, 5vw, 3.5rem);
  border-radius: 22px;
  border: 1px solid var(--line);
  background:
    radial-gradient(90% 120% at 8% 0%,   color-mix(in srgb, var(--peri) 16%, transparent) 0%, transparent 58%),
    radial-gradient(80% 110% at 95% 15%, color-mix(in srgb, var(--rose) 13%, transparent) 0%, transparent 55%),
    radial-gradient(90% 120% at 70% 100%, color-mix(in srgb, var(--sun)  22%, transparent) 0%, transparent 60%),
    var(--surface);
  box-shadow: var(--shadow);
  color: var(--text);
  text-decoration: none;
  transition:
    transform .25s cubic-bezier(.22,.61,.36,1),
    box-shadow .25s cubic-bezier(.22,.61,.36,1),
    border-color .15s ease;
}
.newscard::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: -6%;
  bottom: -34%;
  width: clamp(180px, 26vw, 300px);
  aspect-ratio: 1;
  background: var(--panel-mark) center / contain no-repeat;
  border-radius: 50%;
  opacity: .07;
  pointer-events: none;
}
.newscard:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-hover);
  border-color: var(--peri-br);
}
.newscard__title {
  margin-top: 1rem;
  font-size: clamp(3rem, 9vw, 5.5rem);
  line-height: 0.92;
  letter-spacing: -0.045em;
}
.newscard__title span { color: var(--peri); }
.newscard__body {
  margin-top: 1rem;
  max-width: 46ch;
  font-size: clamp(1.0625rem, 1.8vw, 1.25rem);
  line-height: 1.5;
  color: var(--muted);
  font-weight: 500;
}
.newscard__btn { margin-top: 1.75rem; }
.newscard:hover .newscard__btn { background: var(--peri-br); }
.newscard__url {
  display: block;
  margin-top: 0.875rem;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* The paper stack. Three sheets; the front one has a masthead and
   ruled lines suggesting an issue. */
.newscard__art {
  position: relative;
  justify-self: center;
  width: min(100%, 300px);
  aspect-ratio: 4 / 5;
}
.sheet {
  position: absolute;
  inset: 0;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: 0 10px 30px -14px rgba(47,49,66,.35);
  transition: transform .35s cubic-bezier(.22,.61,.36,1);
}
.sheet--3 { background: var(--sun-soft);  transform: rotate(9deg)  translate(10px, 6px); }
.sheet--2 { background: var(--peri-soft); transform: rotate(-6deg) translate(-8px, 4px); }
.sheet--1 {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1.25rem 1.125rem;
  transform: rotate(1.5deg);
}
.newscard:hover .sheet--3 { transform: rotate(14deg)  translate(26px, 10px); }
.newscard:hover .sheet--2 { transform: rotate(-11deg) translate(-24px, 6px); }
.newscard:hover .sheet--1 { transform: rotate(0deg) translateY(-6px); }

.sheet__mast {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  letter-spacing: 0.06em;
  text-align: center;
  color: var(--text);
}
.sheet__rule {
  height: 3px;
  border-top: 1px solid var(--text);
  border-bottom: 1px solid var(--text);
}
.sheet__head {
  height: 34%;
  border-radius: 6px;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--peri) 30%, transparent), color-mix(in srgb, var(--mint) 30%, transparent));
}
.sheet__lines,
.sheet__cols span {
  display: block;
  background: repeating-linear-gradient(to bottom, var(--line) 0 6px, transparent 6px 13px);
  border-radius: 3px;
}
.sheet__lines { height: 32px; }
.sheet__cols { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }

@media (max-width: 760px) {
  .newscard { grid-template-columns: 1fr; }
  .newscard__art { order: -1; width: min(70%, 230px); margin: 0.5rem auto 0.75rem; }
  .newscard::after { left: auto; right: -12%; }
}

/* ---------- club cards with a logo (club.logo in site.json) ---------- */
/* Built around the Coding Club crest: the logo is on pure black, so the
   card is black too and the crest floats on it with no visible box. A
   glow in the crest's ring blue sits behind it, faint terminal scanlines
   run across the card, and a blinking cursor trails the club name, so it
   reads like a screen. */
/* Colors come from the club's "logoGlow" and "logoAccent" in site.json
   (set as --logo-glow / --logo-hi by clubs.js); the defaults are the
   Coding Club crest's ring blue. */
.club--logo, .clubdlg__logo { --logo-glow: #111E7F; --logo-hi: #5872C1; }
.club--logo {
  background:
    radial-gradient(75% 65% at 50% 36%, color-mix(in srgb, var(--logo-glow) 55%, transparent) 0%, color-mix(in srgb, var(--logo-glow) 18%, transparent) 55%, transparent 75%),
    #000;
  border-color: color-mix(in srgb, var(--logo-glow) 70%, #222);
  color: #fff;
  justify-content: flex-end;
}
/* scanlines */
.club--logo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(to bottom, color-mix(in srgb, var(--logo-hi) 7%, transparent) 0 1px, transparent 1px 4px);
  pointer-events: none;
}
/* The logo is a flex item that takes whatever height is left above the
   name and tags, scaled to fit. A long name or a wrapped Requirements
   tag shrinks the logo instead of covering it. */
.club__logo {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  object-fit: contain;
  /* screen turns the logo's black square transparent, so the crest
     floats on the glow instead of sitting in a dark box */
  mix-blend-mode: screen;
  /* no drop-shadow: on a square image it traces the square's outline */
  transition: transform .35s cubic-bezier(.22,.61,.36,1), filter .35s ease;
}
.club--logo .club__name,
.club--logo .club__foot { position: relative; z-index: 1; }
.club--logo .club__name { color: #fff; font-size: 1.0625rem; }
.club--logo .club__name::after {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.95em;
  margin-left: 0.15em;
  vertical-align: -0.12em;
  background: var(--logo-hi);
  animation: club-caret 1.1s steps(1) infinite;
}
.club--logo .club__more { color: color-mix(in srgb, var(--logo-hi) 55%, #fff); }
.club--logo:hover {
  border-color: var(--logo-hi);
  box-shadow: 0 0 0 1px var(--logo-hi), 0 18px 40px -14px color-mix(in srgb, var(--logo-glow) 75%, transparent);
}
.club--logo:hover .club__logo {
  transform: scale(1.06);
  filter: brightness(1.15);
}
@keyframes club-caret { 50% { opacity: 0; } }

/* Popup banner for a club with a logo: same black screen look. */
.clubdlg__logo {
  position: relative;
  display: grid;
  place-items: center;
  padding: 1.25rem 0 0.75rem;
  background:
    radial-gradient(45% 75% at 50% 50%, color-mix(in srgb, var(--logo-glow) 55%, transparent) 0%, color-mix(in srgb, var(--logo-glow) 15%, transparent) 60%, transparent 80%),
    #000;
  border-bottom: 1px solid color-mix(in srgb, var(--logo-glow) 70%, #222);
}
.clubdlg__logo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(to bottom, color-mix(in srgb, var(--logo-hi) 7%, transparent) 0 1px, transparent 1px 4px);
  pointer-events: none;
}
.clubdlg__logo[hidden] { display: none; }
.clubdlg__logo img {
  position: relative;
  /* Fixed height reserves the space so the banner doesn't jump when the
     logo loads; width follows the logo's own shape, so wide logos (Key
     Club, Wolf Band) are not squeezed into a square. */
  height: clamp(130px, 34vw, 180px);
  width: auto;
  max-width: 82%;
  object-fit: contain;
  mix-blend-mode: screen;
}
@media (max-width: 480px) {
  .club--logo .club__name { font-size: 0.9375rem; }
}

/* ---------- light logo cards ("logoTone": "light") ---------- */
/* For logos drawn on white or cream (Math Honor Society, Science Fair
   Club). The card takes the logo's own background color (--logo-bg) and
   the logo uses multiply, which turns its white or cream transparent
   the same way screen hides black on the dark cards. Instead of
   terminal scanlines, a faint graph paper grid in the logo's accent
   color sits behind it. */
.club--logo-light,
.clubdlg__logo--light { --logo-bg: #FFFFFF; }
.club--logo.club--logo-light {
  background:
    radial-gradient(70% 60% at 50% 38%, color-mix(in srgb, var(--logo-glow) 16%, transparent) 0%, transparent 72%),
    var(--logo-bg);
  border-color: color-mix(in srgb, var(--logo-hi) 30%, var(--line));
  color: var(--text);
}
.club--logo.club--logo-light::before,
.clubdlg__logo.clubdlg__logo--light::before {
  background:
    linear-gradient(to right, color-mix(in srgb, var(--logo-hi) 12%, transparent) 1px, transparent 1px) 0 0 / 14px 14px,
    linear-gradient(to bottom, color-mix(in srgb, var(--logo-hi) 12%, transparent) 1px, transparent 1px) 0 0 / 14px 14px;
}
.club--logo-light .club__logo { mix-blend-mode: multiply; }
.club--logo.club--logo-light .club__name { color: var(--text); }
.club--logo.club--logo-light .club__name::after { display: none; }
.club--logo.club--logo-light .club__more { color: color-mix(in srgb, var(--logo-hi) 55%, #12172E); }
.club--logo.club--logo-light:hover {
  border-color: var(--logo-hi);
  box-shadow: 0 0 0 1px var(--logo-hi), 0 18px 40px -16px color-mix(in srgb, var(--logo-hi) 45%, transparent);
}
.club--logo.club--logo-light:hover .club__logo {
  transform: scale(1.06) rotate(-2deg);
  filter: none;
}

.clubdlg__logo.clubdlg__logo--light {
  background:
    radial-gradient(45% 75% at 50% 50%, color-mix(in srgb, var(--logo-glow) 16%, transparent) 0%, transparent 80%),
    var(--logo-bg);
  border-bottom: 1px solid var(--line);
}
.clubdlg__logo--light img { mix-blend-mode: multiply; }
/* Logo cards: tighter padding, and the Requirements tag moves to the top
   corner as a badge, so the logo gets the height instead of a line of
   tags. */
.club.club--logo { padding: 0.875rem 1rem 0.875rem; gap: 0.5rem; }
.club--logo .club__req {
  position: absolute;
  top: 0.625rem;
  left: 0.625rem;
  z-index: 2;
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
}
/* leave room for the corner tag so it never sits on the logo */
.club--logo:has(> .club__req) .club__logo { margin-top: 1.375rem; }

/* ---------- color logo cards ("logoTone": "color") ---------- */
/* For logos on a solid color (Nerdy Girls Success, white on magenta).
   The logo is cut out to a transparent PNG and the card is filled with
   the club's color instead, so it floats with no box. A soft highlight
   and a scatter of faint dots keep the flat color from looking like a
   plain swatch. */
.club--logo.club--logo-color,
.clubdlg__logo.clubdlg__logo--color {
  background:
    radial-gradient(70% 60% at 50% 32%, rgba(255,255,255,.16) 0%, transparent 70%),
    var(--logo-bg);
  border-color: color-mix(in srgb, var(--logo-bg) 80%, #000);
}
.club--logo.club--logo-color::before,
.clubdlg__logo.clubdlg__logo--color::before {
  background: radial-gradient(circle, rgba(255,255,255,.12) 1.2px, transparent 1.6px) 0 0 / 16px 16px;
}
.club--logo-color .club__logo,
.clubdlg__logo--color img { mix-blend-mode: normal; }
.club--logo.club--logo-color .club__name { color: #fff; }
.club--logo.club--logo-color .club__name::after { display: none; }
.club--logo.club--logo-color .club__more { color: rgba(255,255,255,.85); }
.club--logo.club--logo-color:hover {
  border-color: #fff;
  box-shadow: 0 0 0 1px #fff, 0 18px 40px -14px color-mix(in srgb, var(--logo-bg) 70%, transparent);
}
.club--logo.club--logo-color:hover .club__logo { transform: scale(1.06); filter: none; }
