/* BASIS Plano Booster — design system
   Palette + type lifted from the existing site; layout rebuilt in normal flow. */

/* ── type ──────────────────────────────────────────────────────────────────
   Self-hosted, latin subset. These used to come from Google Fonts, which cost
   two extra origins — DNS, TCP and TLS to fonts.googleapis.com for a
   render-blocking stylesheet, then the same again to fonts.gstatic.com before a
   single letter could paint. On a weak signal that was about a second of blank
   page. Same-origin they ride the connection the HTML already opened.

   Josefin Sans and Roboto are variable fonts: one file covers 400 through 700,
   which is why there is no separate 600 or bold file. Lobster has one weight.
   Only the latin subset is shipped — the ✓ and the emoji in the calendar come
   from the system font either way.

   The files are NOT in git (CLAUDE.md rule 2). They live on the asset host
   beside the images and are served from /assets/fonts/ — see server.js. */
@font-face{font-family:'Josefin Sans';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/assets/fonts/josefin-sans-var.woff2) format('woff2')}
@font-face{font-family:'Lobster';font-style:normal;font-weight:400;font-display:swap;
  src:url(/assets/fonts/lobster-400.woff2) format('woff2')}
@font-face{font-family:'Roboto';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/assets/fonts/roboto-var.woff2) format('woff2')}

:root{
  --green:#31a050; --green-lt:#47c76b; --green-dk:#268040;
  --ink:#0d141a; --char:#1d1e20; --char-2:#26282b; --char-3:#303337;
  --cream:#f2f1e6; --white:#fff;
  --muted:#a8adb4; --muted-dk:#56585e; --line:rgba(255,255,255,.10);
  /* who runs an event, on a light ground — used by .who badges and the printable calendar */
  --who-b:#2f5c7a; --who-s:#268040;
  /* the school's two carlines, named by colour — see .lane */
  --lane-red:#c0392f; --lane-red-lt:#e8897c;
  --lane-blue:#1f5f96; --lane-blue-lt:#84b8e0;
  --display:'Lobster',Georgia,serif;
  --head:'Josefin Sans','Trebuchet MS',sans-serif;
  --body:'Roboto',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  --wrap:1180px; --pad:clamp(18px,4vw,40px);
  --r:14px;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
/* One continuous mascot watermark behind the entire site. Fixed, so it does not
   scroll or tile; dark sections are translucent to let it through, light ones
   sit on top of it. */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:var(--mascot) center/cover no-repeat;opacity:.07}
body>*{position:relative;z-index:1}
body{margin:0;background:var(--char);color:#fff;font-family:var(--body);
  font-size:17px;line-height:1.65;-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
a{color:var(--green-lt)}
.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ── skip link ── */
.skip{position:absolute;left:-9999px;background:var(--green);color:#fff;padding:12px 20px;z-index:100;border-radius:0 0 8px 0}
.skip:focus{left:0;top:0}

/* ── header ── */
.hdr{position:sticky;top:0;z-index:50;background:var(--cream);border-bottom:1px solid rgba(13,20,26,.10)}
.hdr__in{display:flex;align-items:center;gap:20px;max-width:var(--wrap);margin-inline:auto;padding:10px var(--pad)}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none;color:var(--ink);flex:0 0 auto}
.brand img{width:56px;height:56px;border-radius:50%}
.brand b{font-family:var(--head);font-weight:700;font-size:17px;line-height:1.15;letter-spacing:.01em}
.brand span{display:block;font-size:12px;color:var(--muted-dk);font-weight:400}
.nav{margin-left:auto;display:flex;align-items:center;gap:2px;flex-wrap:wrap}
.nav a{font-family:var(--head);font-size:15px;font-weight:600;color:var(--ink);
  text-decoration:none;padding:9px 10px;border-radius:8px;white-space:nowrap}
.nav a:hover{background:rgba(49,160,80,.12);color:var(--green-dk)}
.nav a[aria-current=page]{color:var(--green-dk);box-shadow:inset 0 -2px 0 var(--green)}
.nav__grp{position:relative}
.nav__grp>summary{list-style:none;cursor:pointer;font-family:var(--head);font-size:15px;font-weight:600;
  color:var(--ink);padding:9px 10px;border-radius:8px;display:flex;align-items:center;gap:5px}
.nav__grp>summary:hover{background:rgba(49,160,80,.12);color:var(--green-dk)}
.nav__grp>summary::-webkit-details-marker{display:none}
.nav__grp>summary::marker{content:""}
.nav__grp button{font-family:var(--head);font-size:15px;font-weight:600;color:var(--ink);background:none;
  border:0;cursor:pointer;padding:9px 10px;border-radius:8px;display:flex;align-items:center;gap:5px}
.nav__grp button:hover{background:rgba(49,160,80,.12);color:var(--green-dk)}
.nav__grp ul{position:absolute;top:calc(100% + 4px);left:0;min-width:190px;background:#fff;list-style:none;
  margin:0;padding:6px;border-radius:10px;box-shadow:0 10px 30px rgba(13,20,26,.18);display:none}
.nav__grp[open] ul,.nav__grp:focus-within ul{display:block}
.nav__grp ul a{display:block;padding:9px 12px}
.cta{background:var(--green);color:#fff!important;padding:10px 20px!important;border-radius:8px;font-weight:700!important}
.cta:hover{background:var(--green-dk)!important}
.burger{display:none;margin-left:auto;background:none;border:0;padding:10px;cursor:pointer}
.burger span{display:block;width:24px;height:2px;background:var(--ink);margin:5px 0;border-radius:2px}

/* ── sections ── */
.sec{padding:clamp(52px,8vw,96px) 0;position:relative}
.sec--dark{background:color-mix(in srgb,var(--char) 88%,transparent)}
.sec--dark2{background:color-mix(in srgb,var(--char-2) 88%,transparent)}
.sec--cream{background:var(--cream);color:var(--ink)}
.sec--green{background:var(--green);color:#fff}
/* .sec--mascot is a no-op now: the watermark is one fixed page-level layer. */
.sec>.wrap{position:relative}

/* ── type ── */
.display{font-family:var(--display);font-weight:400;color:var(--green-lt);
  font-size:clamp(34px,6vw,62px);line-height:1.12;margin:0 0 .3em}
h1,h2,h3,h4{font-family:var(--head);font-weight:700;line-height:1.2;margin:0 0 .5em}
h1{font-size:clamp(32px,5.5vw,54px)}
h2{font-size:clamp(27px,4vw,40px)}
h3{font-size:clamp(21px,2.6vw,27px)}
h4{font-size:19px}
.eyebrow{font-family:var(--head);font-size:12px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--green-lt);margin:0 0 10px}
.sec--cream .eyebrow{color:var(--green-dk)}
.lead{font-size:clamp(17px,2vw,21px);line-height:1.6;color:#e7e9ec;max-width:62ch}
.sec--cream .lead{color:var(--muted-dk)}
p{margin:0 0 1.1em;max-width:72ch}
.center{text-align:center}
/* `center` may sit on the element itself or on an ancestor — match both, or a
   max-width'd <p> stays anchored left while its text centres inside it. */
.center .lead,.center p,.center .eyebrow,.center h1,.center h2,.center h3,
p.center,.lead.center,.eyebrow.center,.note.center{margin-left:auto;margin-right:auto}
.note{font-size:14px;color:var(--muted);max-width:70ch;margin-inline:auto;text-align:center}
.sec--cream .note{color:var(--muted-dk)}

/* ── buttons ── */
.btn{display:inline-block;font-family:var(--head);font-weight:700;font-size:16px;text-decoration:none;
  padding:14px 30px;border-radius:9px;background:var(--green);color:#fff;border:2px solid var(--green);transition:.15s}
.btn:hover{background:var(--green-dk);border-color:var(--green-dk)}
.btn--ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.45)}
.btn--ghost:hover{background:rgba(255,255,255,.10);border-color:#fff}
.sec--cream .btn--ghost{color:var(--ink);border-color:rgba(13,20,26,.30)}
.btns{display:flex;flex-wrap:wrap;gap:12px;margin-top:26px}
.center .btns{justify-content:center}

/* ── grids ── */
.grid{display:grid;gap:clamp(16px,2.4vw,28px)}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.g2-tight{grid-template-columns:1fr 1fr}
/* One card left in a three-up row. .g3 is auto-fit, so it would collapse the
   empty tracks and stretch the card across the whole row; this keeps all three
   tracks, leaving the card the width it had when it had company, in the
   left-hand one. Below the width where a third is still a sensible card, it
   goes full width like any other. */
.g3--lonely{grid-template-columns:1fr}
@media (min-width:900px){.g3--lonely{grid-template-columns:repeat(3,1fr)}}
.card{background:var(--char-2);border:1px solid var(--line);border-radius:var(--r);padding:26px;height:100%}
.sec--cream .card{background:#fff;border-color:rgba(13,20,26,.10)}
.card h3{margin-bottom:.35em}
.card p:last-child{margin-bottom:0}
/* An event that has already run: a record that it happened, not an invitation.
   Outline rather than fill, so it reads as quieter than a live card without
   needing a second colour. */
.card--done{background:transparent;border-style:dashed}
.sec--cream .card--done{background:transparent;border-color:rgba(13,20,26,.18)}
.card--done h3{color:var(--muted-dk)}
.card--done .ended{margin:10px 0 0}

/* ── icon badges on event pages ──
   The icon sits in the heading rather than above it: a stacked badge cost a
   whole row of height on every card and pushed the four sessions off a phone
   screen. Stroke icons inherit the green tokens, so they flip with the section
   shade the same way the type does. A logo that already carries its own
   circular ground (the crest) uses --logo, which swaps the tint for a light
   ground — on tint the crest's own green ring disappears into it. */
.ico{width:40px;height:40px;flex:none;border-radius:50%;display:grid;place-items:center;
  background:rgba(49,160,80,.12);border:1px solid rgba(49,160,80,.28)}
.sec--dark .ico,.sec--dark2 .ico{background:rgba(71,199,107,.11);border-color:rgba(71,199,107,.30)}
.ico svg{width:21px;height:21px;fill:none;stroke:var(--green-dk);stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.sec--dark .ico svg,.sec--dark2 .ico svg{stroke:var(--green-lt)}
.ico--logo,.sec--dark .ico--logo,.sec--dark2 .ico--logo{background:#fff;
  border-color:rgba(255,255,255,.55)}
.ico--logo img{width:34px;height:34px;object-fit:contain}

/* icon + (eyebrow / heading) on one row */
.ico-h{display:flex;align-items:center;gap:13px;margin:0 0 10px}
.ico-h h3,.ico-h .eyebrow{margin:0}
.ico-h .eyebrow{margin-bottom:2px}
.ico-h h3{font-size:19px;line-height:1.25}

/* ── the When / Where / Who facts ──
   Three cards carrying the only three things somebody scanning the page has to
   come away with, so they get a filled icon and the answer in heading type
   rather than reading as three paragraphs in boxes. */
.fact{position:relative;overflow:hidden;padding-top:30px}
.fact::before{content:"";position:absolute;inset:0 0 auto;height:3px;
  background:linear-gradient(90deg,var(--green),var(--green-lt))}
.fact__b{display:flex;align-items:flex-start;gap:12px}
.fact__b .ico{margin-top:1px}
.fact .ico,.sec--dark .fact .ico,.sec--dark2 .fact .ico{background:var(--green);
  border-color:var(--green)}
.fact .ico svg,.sec--dark .fact .ico svg,.sec--dark2 .fact .ico svg{stroke:var(--white)}
.fact__v{margin:0;font-family:var(--head);font-size:17px;font-weight:600;line-height:1.5;
  color:var(--ink)}
.sec--dark .fact__v,.sec--dark2 .fact__v{color:var(--white)}

/* ── the STEAM band ──
   The letters, decoded. The atom is a watermark: decorative, behind the tiles,
   and low enough in contrast that it never competes with the text on top. */
.stm{position:relative;overflow:hidden}
.stm__atom{position:absolute;top:-70px;right:-60px;width:290px;height:290px;
  opacity:.08;pointer-events:none}
.stm__atom svg{width:100%;height:100%;fill:none;stroke:var(--green-lt);stroke-width:.6}
.stm__row{position:relative;display:grid;gap:clamp(10px,1.8vw,16px);margin-top:28px;
  grid-template-columns:repeat(auto-fit,minmax(96px,1fr))}
.stm__t{text-align:center;padding:18px 8px;border:1px solid var(--line);
  border-radius:var(--r);background:rgba(255,255,255,.035)}
.sec--cream .stm__t{border-color:rgba(13,20,26,.10);background:#fff}
.stm__t .ico{width:48px;height:48px;margin:0 auto 11px}
.stm__t .ico svg{width:26px;height:26px}
.stm__t b{display:block;font-family:var(--head);font-weight:700;font-size:27px;line-height:1;
  color:var(--green-lt)}
.sec--cream .stm__t b{color:var(--green-dk)}
.stm__t i{display:block;font-style:normal;font-family:var(--head);font-size:12px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin-top:7px}
.sec--cream .stm__t i{color:var(--muted-dk)}
/* Three tiles to a phone row leaves 88px of label, and "Engineering" wants
   101px of it. Tighter tracking and less gutter buy back the difference. */
@media (max-width:560px){
  .stm__t{padding:16px 5px}
  .stm__t i{font-size:11px;letter-spacing:.04em}
}

/* Four session cards: 2x2, not the 3+1 that .g2's auto-fit gives at this
   width, and tighter than a default card since each holds three short lines. */
.ssn{grid-template-columns:1fr}
@media (min-width:760px){.ssn{grid-template-columns:1fr 1fr}}
.ssn .card{padding:20px;transition:transform .18s ease,border-color .18s ease}
.ssn .card:hover{transform:translateY(-3px);border-color:rgba(71,199,107,.45)}
.sec--cream .ssn .card:hover{border-color:rgba(49,160,80,.40)}
.ssn .card p{font-size:15px}
.ssn .ended{margin:12px 0 0;padding:8px 12px;font-size:13px}

/* ── speaker card ──
   The seminar's draw is a named person from a named company, so the section is
   built around them rather than around another centred paragraph. */
.spk{display:grid;gap:clamp(16px,3vw,26px);max-width:820px;margin:30px auto 0;
  background:#fff;border:1px solid rgba(13,20,26,.10);border-left:5px solid var(--green);
  border-radius:var(--r);padding:clamp(20px,3vw,30px)}
@media (min-width:640px){.spk{grid-template-columns:auto 1fr;align-items:start}}
.spk__medal{width:96px;height:96px;border-radius:50%;display:grid;place-items:center;
  background:rgba(49,160,80,.11);border:1px solid rgba(49,160,80,.28);margin-inline:auto}
.spk__medal svg{width:44px;height:44px;fill:none;stroke:var(--green-dk);stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.spk__name{font-family:var(--head);font-size:clamp(23px,3vw,29px);line-height:1.15;
  margin:0 0 6px;color:var(--ink)}
.spk__role{margin:0;font-family:var(--head);font-weight:700;font-size:16px;color:var(--ink)}
.spk__org{margin:3px 0 0;font-size:15px;color:var(--muted-dk)}
/* The tint stays light enough that --green-dk on top of it still clears 4.5:1;
   at .09 the TOPIC label measured 4.49 and failed by a rounding error. */
.spk__talk{margin:18px 0 0;padding:15px 18px;border-radius:11px;background:rgba(49,160,80,.06);
  border-left:3px solid rgba(49,160,80,.35)}
.spk__talk span{display:block;font-family:var(--head);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--green-dk);margin-bottom:6px}
.spk__talk b{font-family:var(--head);font-weight:700;font-size:clamp(16px,1.9vw,19px);
  line-height:1.4;color:var(--ink)}
/* The topic now carries a description under its headline; the bold line stays
   the thing you read first, the paragraph is body type. */
.spk__talk p{margin:9px 0 0;font-size:15px;line-height:1.65;color:var(--ink)}
.spk__lbl{margin:22px 0 7px;font-family:var(--head);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--green-dk)}
.spk__bio{margin:0 0 12px;font-size:15px;line-height:1.7;color:var(--ink);max-width:68ch}
.spk__note{margin:14px 0 0;font-size:14px;color:var(--muted-dk);max-width:62ch}

.stat{text-align:center}
.stat b{display:block;font-family:var(--display);font-size:clamp(40px,6vw,64px);color:var(--green-lt);line-height:1}
.stat span{font-family:var(--head);font-size:15px;color:var(--muted);font-weight:600}
.sec--cream .stat span{color:var(--muted-dk)}
figure{margin:0}
figure img{border-radius:var(--r);width:100%}
figcaption{font-size:14px;color:var(--muted);margin-top:9px;font-family:var(--head)}
.sec--cream figcaption{color:var(--muted-dk)}
.gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px}
.gal img{border-radius:10px;aspect-ratio:4/3;object-fit:cover;width:100%}
/* One 339px-wide column on a phone meant the smallest screen pulled the
   LARGEST thumbnail of any device. Two-up halves the pixels and shows more
   of the album at once. GAL_SIZES in generate.py mirrors this — change both. */
@media (max-width:559px){.gal{grid-template-columns:repeat(2,1fr);gap:10px}}
/* The home page's Instagram strip is a .gal with two things .gal cannot give it,
   so there is nothing here about columns, gaps or thumbnails — change .gal above
   and this follows.
   1. It ships empty and `hidden`, and is unhidden by assets/instagram.js once it
      has tiles. `display:grid` on an author stylesheet outranks the browser's own
      [hidden]{display:none}, so without this rule the empty grid would hold open
      a gap under the heading until the feed arrived — or forever, if it never did.
   2. The same air under the lead paragraph that an album gets on /gallery. */
/* Square tiles, not the 4/3 the photo galleries use. What this account posts is
   mostly flyers - shade campaign, Element shirts, blood drive, movie night -
   which are portrait or square and carry their message as text. A 4/3 crop
   takes the top and bottom off each one and leaves an unreadable middle band.
   Instagram's own grid is square, so this is also what a visitor recognises. */
.ig__grid{margin-top:24px}
.ig__grid img{aspect-ratio:1}
.ig__grid[hidden]{display:none}
.person{text-align:center}
.person img{border-radius:50%;aspect-ratio:1;object-fit:cover;width:132px;margin:0 auto 12px}
.person b{display:block;font-family:var(--head);font-size:17px}
.person span{font-size:14px;color:var(--green-lt)}
.sec--cream .person span{color:var(--green-dk)}

/* ── hero ── */
.hero{position:relative;background:color-mix(in srgb,var(--char) 84%,transparent);padding:clamp(48px,8vw,92px) 0;overflow:hidden}

.hero__in{position:relative;display:grid;grid-template-columns:1fr auto 1fr;gap:clamp(16px,3vw,44px);align-items:center}
.hero__logo{width:clamp(140px,20vw,230px);border-radius:50%}
/* Each flanking phrase wraps to two lines. Shrink the block to its widest line
   and centre the text inside it, so "Booster" sits under "BASIS Plano" instead
   of hanging off one edge — the block itself still hugs the crest. */
.hero .display{margin:0;width:fit-content;text-align:center}
.hero__l .display{margin-left:auto}
.hero__r .display{margin-right:auto}
@media(max-width:820px){
  .hero__in{grid-template-columns:1fr;justify-items:center;text-align:center}
  .hero__l .display,.hero__r .display{margin-inline:auto}
}

/* ── FAQ ── */
details.faq{border:1px solid var(--line);border-radius:11px;margin-bottom:11px;background:var(--char-2)}
.sec--cream details.faq{background:#fff;border-color:rgba(13,20,26,.10)}
details.faq>summary{cursor:pointer;padding:17px 20px;font-family:var(--head);font-weight:700;font-size:17px;list-style:none;display:flex;gap:12px}
details.faq>summary::-webkit-details-marker{display:none}
details.faq>summary::before{content:"+";color:var(--green-lt);font-size:21px;line-height:1;flex:0 0 auto}
details.faq[open]>summary::before{content:"–"}
details.faq .bd{padding:0 20px 18px 52px}
/* App names in an answer, picked out so a parent scanning for the one they need
   finds it. Only the ones we have an address for are links, and only those get
   the underline — a green name with no rule under it is not clickable. */
.appname{font-family:var(--head);font-weight:700;color:var(--green-lt)}
a.appname{text-decoration:none;border-bottom:2px solid rgba(49,160,80,.45)}
a.appname:hover{color:#fff;border-bottom-color:var(--green-lt)}
.sec--cream .appname{color:var(--green-dk)}
.sec--cream a.appname:hover{color:var(--green-dk);border-bottom-color:var(--green-dk)}
details.faq .bd p:last-child{margin-bottom:0}

/* ── footer ── */
.ftr{background:var(--ink);padding:56px 0 30px;font-size:15px}
.ftr__g{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:34px}
.ftr h4{font-family:var(--head);font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--green-lt);margin-bottom:14px}
.ftr ul{list-style:none;margin:0;padding:0}
.ftr li{margin-bottom:9px}
.ftr a{color:#cbd0d6;text-decoration:none}
.ftr a:hover{color:#fff;text-decoration:underline}
.ftr__btm{border-top:1px solid rgba(255,255,255,.10);margin-top:34px;padding-top:22px;
  display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;color:#8b9198;font-size:13px}

@media(max-width:1060px){
  .burger{display:block}
  .nav{display:none;position:absolute;top:100%;left:0;right:0;background:var(--cream);
    flex-direction:column;align-items:stretch;padding:10px var(--pad) 18px;
    border-bottom:1px solid rgba(13,20,26,.12);gap:0}
  .nav.open{display:flex}
  .nav a,.nav__grp button{width:100%;text-align:left;padding:12px 8px}
  .nav__grp ul{position:static;display:block;box-shadow:none;background:transparent;padding-left:14px}
  .nav__grp ul a{color:var(--muted-dk)}
  .cta{margin-top:8px;text-align:center}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

/* ── roster tables ── */
.tw{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.roster{width:100%;border-collapse:collapse;font-size:16px;min-width:420px}
table.roster caption{font-family:var(--head);font-weight:700;font-size:clamp(21px,2.6vw,27px);
  text-align:left;padding:0 0 14px;color:inherit}
table.roster th,table.roster td{text-align:left;padding:13px 16px;border-bottom:1px solid var(--line)}
.sec--cream table.roster th,.sec--cream table.roster td{border-bottom-color:rgba(13,20,26,.10)}
table.roster thead th{font-family:var(--head);font-size:12px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--green-lt);border-bottom-width:2px}
.sec--cream table.roster thead th{color:var(--green-dk)}
table.roster tbody th{font-weight:700;font-family:var(--head);font-size:17px;white-space:nowrap}
table.roster tbody tr:hover{background:rgba(49,160,80,.07)}
table.roster td{color:#d8dce1}
.sec--cream table.roster td{color:var(--muted-dk)}
.tag{display:inline-block;font-family:var(--head);font-size:12px;font-weight:700;letter-spacing:.06em;
  padding:3px 9px;border-radius:999px;background:rgba(49,160,80,.16);color:var(--green-lt);margin:2px 4px 2px 0}
.sec--cream .tag{background:rgba(49,160,80,.14);color:var(--green-dk)}
.tag--open{background:rgba(255,255,255,.10);color:var(--muted)}
.sec--cream .tag--open{background:rgba(13,20,26,.07);color:var(--muted-dk)}


/* ══════════ org chart ══════════ */
.org{--boxbd:rgba(13,20,26,.55)}
.org ul{list-style:none;margin:0;padding:0}
.org__tier{font-family:var(--head);font-weight:700;font-size:clamp(20px,2.5vw,26px);
  text-align:center;margin:0 0 20px;text-decoration:underline;text-underline-offset:6px}
.org__top{display:flex;justify-content:center;margin-bottom:14px}
.org__top .box{min-width:230px}
.org__link{width:2px;height:18px;background:var(--boxbd);margin:0 auto 14px;opacity:.5}
.org__board{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;max-width:940px;margin:0 auto}
.org__cols{display:grid;grid-template-columns:repeat(7,1fr);gap:12px;align-items:start}
.org__col{display:flex;flex-direction:column;gap:12px}

.box{border:2px solid var(--boxbd);border-radius:8px;padding:11px 12px;text-align:center;
  font-family:var(--head);line-height:1.25;display:flex;flex-direction:column;justify-content:center;
  min-height:62px}
.box b{display:block;font-weight:700;font-size:15px}
.box span{display:block;font-weight:600;font-size:13px;opacity:.92;margin-top:2px}

/* Colour = REPORTING LINE. Each chair's box matches the VP they report to.
   Muted stand-ins for the source chart's red / purple / gold. */
.box--pres{background:#1e5c34;color:#fff}   /* President                    */
.box--fin {background:#2b7b76;color:#fff}   /* Treasurer                    */
.box--evt {background:#c2703f;color:#fff}   /* VP Events        (was red)   */
.box--com {background:#6b5ca5;color:#fff}   /* VP Comms & FR    (was purple)*/
.box--sec {background:#b3862f;color:#fff}   /* Secretary        (was gold)  */
.box--open{background:#efecf8;color:#4a4270;border-style:dashed;border-color:#6b5ca5}
.sec--dark .org,.sec--dark2 .org{--boxbd:rgba(255,255,255,.45)}
.sec--dark .box--open,.sec--dark2 .box--open{background:rgba(107,92,165,.18);color:#cfc8ea;border-color:#8c7ec4}
/* legend */
.org__legend{display:flex;flex-wrap:wrap;gap:16px 24px;justify-content:center;margin:0 auto 30px;text-align:center;max-width:none;
  font-family:var(--head);font-size:14px;font-weight:600}
.org__legend span{display:flex;align-items:center;gap:8px}
.org__legend i{width:15px;height:15px;border-radius:4px;border:2px solid var(--boxbd);display:inline-block}

@media(max-width:1080px){ .org__cols{grid-template-columns:repeat(4,1fr)} }
@media(max-width:820px) { .org__board{grid-template-columns:repeat(2,1fr)}
                          .org__cols{grid-template-columns:repeat(3,1fr)} }
@media(max-width:600px) { .org__cols{grid-template-columns:repeat(2,1fr)}
                          .org__top .box{min-width:0;width:100%} }
@media(max-width:400px) { .org__board,.org__cols{grid-template-columns:1fr} }

/* ── contact tables: stack into labelled rows on narrow screens ── */
@media(max-width:640px){
  table.roster{min-width:0;display:block}
  table.roster thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  table.roster tbody,table.roster tr,table.roster th,table.roster td{display:block;width:100%}
  table.roster tr{padding:14px 0;border-bottom:1px solid var(--line)}
  .sec--cream table.roster tr{border-bottom-color:rgba(13,20,26,.10)}
  table.roster tbody th{padding:0 0 6px;border:0;white-space:normal;font-size:18px}
  table.roster td{padding:2px 0;border:0}
  table.roster td[data-label]::before{content:attr(data-label) ": ";
    font-family:var(--head);font-weight:700;font-size:12px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--green-dk);margin-right:6px}
  .sec--dark table.roster td[data-label]::before,
  .sec--dark2 table.roster td[data-label]::before{color:var(--green-lt)}
  table.roster tbody tr:hover{background:none}
}
table.roster td a{color:var(--green-dk);word-break:break-word}
.sec--dark table.roster td a,.sec--dark2 table.roster td a{color:var(--green-lt)}

/* ── events calendar ── */
.cal{display:grid;grid-template-columns:repeat(auto-fit,minmax(255px,1fr));gap:16px}
.cal__m{background:var(--char-2);border:1px solid var(--line);border-radius:var(--r);padding:20px;height:100%}
.sec--cream .cal__m{background:#fff;border-color:rgba(13,20,26,.10)}
.cal__m h3{font-size:20px;margin:0 0 12px;padding-bottom:9px;border-bottom:2px solid var(--green);
  display:flex;align-items:baseline;gap:8px}
.cal__m ul{list-style:none;margin:0;padding:0}
.cal__m li{padding:7px 0;font-size:15px;line-height:1.45;border-bottom:1px dashed var(--line)}
.sec--cream .cal__m li{border-bottom-color:rgba(13,20,26,.09)}
.cal__m li:last-child{border-bottom:0}
.cal__d{font-family:var(--head);font-weight:700;color:var(--green-lt);margin-right:6px}
.sec--cream .cal__d{color:var(--green-dk)}
.cal__sub{font-family:var(--head);font-size:11px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--muted);margin:12px 0 2px;font-weight:700}
.sec--cream .cal__sub{color:var(--muted-dk)}
.who{display:inline-block;font-family:var(--head);font-size:10px;font-weight:700;letter-spacing:.07em;
  padding:1px 7px;border-radius:999px;margin-left:6px;vertical-align:1px;white-space:nowrap}
.who--b{background:rgba(63,111,143,.22);color:#8fbcdb}
.who--s{background:rgba(49,160,80,.22);color:var(--green-lt)}
.sec--cream .who--b{background:rgba(63,111,143,.16);color:var(--who-b)}
.sec--cream .who--s{background:rgba(49,160,80,.16);color:var(--who-s)}
.hl{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:14px}
.hl div{background:var(--green);color:#fff;border-radius:var(--r);padding:18px 16px;text-align:center}
.hl b{display:block;font-family:var(--head);font-size:17px;margin-bottom:4px}
.hl span{font-size:14px;opacity:.95;line-height:1.4}

/* ── modal dialog + forms ── */
dialog.modal{border:0;padding:0;border-radius:16px;max-width:520px;width:calc(100% - 32px);
  background:var(--cream);color:var(--ink);box-shadow:0 24px 70px rgba(0,0,0,.42)}
dialog.modal::backdrop{background:rgba(9,12,15,.66)}
.modal__hd{display:flex;align-items:flex-start;gap:14px;padding:24px 24px 0}
.modal__hd h2{margin:0;font-size:23px}
.modal__hd p{margin:6px 0 0;font-size:14px;color:var(--muted-dk);max-width:none}
.modal__x{margin-left:auto;background:none;border:0;font-size:26px;line-height:1;cursor:pointer;
  color:var(--muted-dk);padding:0 2px;border-radius:6px}
.modal__x:hover{color:var(--ink);background:rgba(13,20,26,.07)}
.modal form{padding:18px 24px 24px}
.fld{margin-bottom:14px}
.fld label{display:block;font-family:var(--head);font-weight:700;font-size:13px;margin-bottom:5px}
.fld .req{color:#b4453a}
.fld input,.fld textarea{width:100%;font:inherit;font-size:15px;padding:11px 13px;border-radius:9px;
  border:1px solid rgba(13,20,26,.24);background:#fff;color:var(--ink)}
.fld textarea{min-height:104px;resize:vertical}
.fld input:focus,.fld textarea:focus{outline:2px solid var(--green);outline-offset:1px;border-color:var(--green)}
.modal .btns{margin-top:18px}
.modal__note{font-size:12px;color:var(--muted-dk);margin:12px 0 0}
/* Result of a submission. The form used to close silently whether or not the
   message went anywhere, so say plainly which happened. */
.modal__status{margin:14px 0 0;padding:11px 13px;border-radius:9px;font-size:14px;line-height:1.5}
.modal__status.is-ok{background:rgba(49,160,80,.12);border:1px solid rgba(49,160,80,.45);
  color:var(--green-dk)}
.modal__status.is-err{background:rgba(180,69,58,.10);border:1px solid rgba(180,69,58,.40);
  color:#8f3128}
/* Honeypot: reachable by a bot reading the DOM, invisible to everyone else.
   Kept out of the layout and out of tab order rather than display:none, which
   some bots check for. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
@media(prefers-reduced-motion:no-preference){
  dialog.modal[open]{animation:pop .16s ease-out}
  @keyframes pop{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
}

/* short pages: fill the viewport and centre their panel vertically */
.sec.panel{min-height:calc(100vh - 78px);display:flex;align-items:center;justify-content:center}
@media(max-width:1060px){.sec.panel{min-height:calc(100vh - 70px)}}

/* ── gallery lightbox ── */
.gal button{padding:0;border:0;background:none;cursor:zoom-in;display:block;border-radius:10px;
  overflow:hidden;position:relative}
.gal button:focus-visible{outline:3px solid var(--green);outline-offset:3px}
.gal button::after{content:"";position:absolute;inset:0;background:rgba(9,12,15,0);transition:background .15s}
.gal button:hover::after{background:rgba(9,12,15,.22)}
@media(hover:none){.gal button:hover::after{background:none}}

/* position:fixed, not the UA default of absolute: an absolutely positioned
   dialog is placed against the document, so opening a photo from the bottom of
   a long gallery put the viewer offscreen at the top of the page. */
dialog.lb{position:fixed;inset:0;border:0;padding:0;background:transparent;
  max-width:100vw;max-height:100vh;width:100%;height:100%;overflow:hidden}
/* showModal() does not stop the page behind from scrolling; this does. */
html.lb-open{overflow:hidden}
dialog.lb::backdrop{background:rgba(9,12,15,.93)}
.lb__fig{margin:0;height:100%;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:14px;padding:56px 62px}
.lb__fig img{max-width:100%;max-height:calc(100vh - 150px);width:auto;height:auto;
  object-fit:contain;border-radius:8px;background:#111}
.lb__cap{color:#dfe3e8;font-family:var(--head);font-size:14px;text-align:center;margin:0;
  max-width:70ch;min-height:1.2em}
.lb__btn{position:fixed;top:50%;transform:translateY(-50%);background:rgba(255,255,255,.12);
  color:#fff;border:0;width:46px;height:46px;border-radius:50%;font-size:24px;line-height:1;
  cursor:pointer;display:flex;align-items:center;justify-content:center}
.lb__btn:hover{background:rgba(255,255,255,.24)}
.lb__btn:focus-visible{outline:3px solid var(--green);outline-offset:2px}
.lb__prev{left:12px}.lb__next{right:12px}
.lb__x{position:fixed;top:12px;right:12px;transform:none;width:42px;height:42px;font-size:22px}
.lb__n{position:fixed;top:20px;left:18px;color:#aeb5bd;font-family:var(--head);font-size:13px;
  letter-spacing:.08em}
@media(max-width:620px){
  .lb__fig{padding:52px 12px 74px}
  .lb__btn{top:auto;bottom:14px;transform:none}
  .lb__prev{left:calc(50% - 58px)}.lb__next{right:calc(50% - 58px)}
}

/* ── paw cursor (lifted from the original site) ── */
body{cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='29.4' height='29.4' viewBox='0 0 42 42'><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(0,1)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(19,20)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g></svg>") 6 6,auto}
a,button,summary,label,[role="button"],.gal button{cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='29.4' height='29.4' viewBox='0 0 42 42'><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(0,1)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(19,20)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g></svg>") 6 6,pointer}
input,textarea,select{cursor:auto}
.gal button{cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='29.4' height='29.4' viewBox='0 0 42 42'><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(0,1)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g><g fill='%23355e39' stroke='%23ffffff' stroke-width='0.9' transform='translate(19,20)'><path d='M12,10.5 C9.5,10 8,10.8 8,12 C8,10.5 5,10.5 3.5,13 C2.5,15 3,18 6,20 C8,21.7 10,22 12,22 C14,22 16,21.7 18,20 C21,18 21.5,15 20.5,13 C19,10.5 16,10.5 16,12 C16,10.8 14.5,10 12,10.5 Z' transform='translate(12,16) scale(0.85,-0.85) translate(-12,-16)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(5,6) rotate(-25)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(9.5,3) rotate(-8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(14.5,3) rotate(8)'/><path d='M0,-3.5 C1.8,-3.5 2,-1 2,1 C2,3 1,3.5 0,3.5 C-1,3.5 -2,3 -2,1 C-2,-1 -1.8,-3.5 0,-3.5 Z' transform='translate(19,6) rotate(25)'/></g></svg>") 6 6,zoom-in}
@media (hover:none),(pointer:coarse){
  body,a,button,summary,label,[role="button"],.gal button{cursor:auto}
}

/* two-up photo rows: equal height regardless of the source aspect ratio */
.g2--even figure{height:100%}
.g2--even img{width:100%;height:100%;object-fit:cover;aspect-ratio:16/10}

/* ── membership tiers ── */
.tiers{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:20px;align-items:start}
.tier{background:#fff;border:1px solid rgba(13,20,26,.12);border-radius:var(--r);padding:26px;height:100%;
  display:flex;flex-direction:column}
.sec--dark .tier,.sec--dark2 .tier{background:var(--char-2);border-color:var(--line)}
.tier--best{border:2px solid var(--green);box-shadow:0 6px 24px rgba(49,160,80,.14)}
.tier h3{font-size:20px;margin:0 0 4px;line-height:1.25}
.tier__price{font-family:var(--display);font-size:42px;color:var(--green-dk);line-height:1;margin:10px 0 2px}
.sec--dark .tier__price,.sec--dark2 .tier__price{color:var(--green-lt)}
.tier__valid{font-family:var(--head);font-size:13px;color:var(--muted-dk);margin:0 0 16px}
.sec--dark .tier__valid,.sec--dark2 .tier__valid{color:var(--muted)}
.tier ul{list-style:none;margin:0 0 18px;padding:0;flex:1}
.tier li{position:relative;padding:0 0 11px 26px;font-size:15px;line-height:1.5}
.tier li::before{content:"";position:absolute;left:0;top:.42em;width:14px;height:8px;
  border-left:2.5px solid var(--green);border-bottom:2.5px solid var(--green);
  transform:rotate(-45deg)}
.tier__note{font-size:13px;font-weight:700;color:var(--green-dk);margin:0 0 16px}
.sec--dark .tier__note,.sec--dark2 .tier__note{color:var(--green-lt)}
.tier .btn{width:100%;text-align:center}
.tier__tag{display:inline-block;font-family:var(--head);font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;background:var(--green);color:#fff;padding:3px 10px;border-radius:999px;margin-bottom:10px}

/* ── social links ── */
.social{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.social a{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  border-radius:10px;background:rgba(255,255,255,.09);color:#cbd0d6;transition:.15s}
.social a:hover{background:var(--green);color:#fff}
.social svg{width:20px;height:20px;fill:currentColor}
.hdr .social{margin:0}
.hdr .social a{width:34px;height:34px;background:transparent;color:var(--ink)}
.hdr .social a:hover{background:rgba(49,160,80,.14);color:var(--green-dk)}
.hdr .social svg{width:18px;height:18px}
@media(max-width:1060px){.hdr .social{display:none}}
.cal__x{display:block;font-size:13px;color:var(--muted);margin-top:2px}
.sec--cream .cal__x{color:var(--muted-dk)}

/* ── shade campaign ── */
.camp{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(20px,3vw,34px);align-items:start}
@media(max-width:860px){.camp{grid-template-columns:1fr}}
.camp__goal{background:var(--green);color:#fff;border-radius:var(--r);padding:26px;text-align:center}
.camp__goal b{display:block;font-family:var(--display);font-size:clamp(38px,6vw,56px);line-height:1}
.camp__goal span{display:block;font-family:var(--head);font-size:14px;opacity:.95;margin-top:6px}
.camp__spec{display:inline-block;margin-top:14px;background:rgba(0,0,0,.22);border-radius:999px;
  padding:5px 14px;font-family:var(--head);font-size:13px;font-weight:700;letter-spacing:.04em}
.camp__perks{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:22px 0}
.camp__perks div{text-align:center;padding:16px 8px;border:1px solid rgba(13,20,26,.12);border-radius:11px}
.sec--dark .camp__perks div,.sec--dark2 .camp__perks div{border-color:var(--line)}
.camp__perks b{display:block;font-family:var(--head);font-size:13px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--green-dk);margin-top:8px}
.sec--dark .camp__perks b,.sec--dark2 .camp__perks b{color:var(--green-lt)}
.camp__perks svg{width:30px;height:30px;stroke:var(--green);fill:none;stroke-width:1.8}
.camp__ask{border-left:4px solid var(--green);padding:4px 0 4px 18px;margin:22px 0}
.camp__ask b{font-family:var(--head);font-size:17px;display:block;margin-bottom:4px}
.camp__major{background:rgba(49,160,80,.10);border:1px dashed var(--green);border-radius:11px;
  padding:18px 20px;margin-top:18px}
.camp__major b{font-family:var(--head);font-size:16px;display:block}
/* These callouts are boxed and short; the global 72ch measure left the text
   ending halfway across a full-width panel. Let them fill the box. */
.camp__major p,.camp__ask p{max-width:none}

/* sold-out products stay visible but read as unavailable */
.card--sold{opacity:.72}
.card--sold img{filter:grayscale(.55)}
.sold{display:inline-block;font-family:var(--head);font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;background:rgba(13,20,26,.10);color:var(--muted-dk);
  padding:3px 10px;border-radius:999px;margin-left:8px;vertical-align:2px}
.stock{display:inline-block;font-family:var(--head);font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;background:rgba(49,160,80,.16);color:var(--green-dk);
  padding:3px 10px;border-radius:999px;margin-left:8px;vertical-align:2px}

/* ── year calendar: month tiles that open a detail dialog ── */
.yr{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:14px}
.yr button{text-align:left;font:inherit;cursor:pointer;background:var(--char-2);color:#fff;
  border:1px solid var(--line);border-radius:var(--r);padding:18px;transition:.15s;height:100%}
.sec--cream .yr button{background:#fff;color:var(--ink);border-color:rgba(13,20,26,.12)}
.yr button:hover{border-color:var(--green);transform:translateY(-2px)}
.yr button:focus-visible{outline:3px solid var(--green);outline-offset:2px}
.yr__m{display:flex;align-items:baseline;gap:8px;font-family:var(--head);font-weight:700;font-size:20px}
.yr__y{font-size:13px;opacity:.6;font-weight:600}
.yr__c{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px}
.yr__c span{font-family:var(--head);font-size:11px;font-weight:700;letter-spacing:.05em;
  padding:3px 9px;border-radius:999px;white-space:nowrap}
.yr__c .b{background:rgba(63,111,143,.22);color:#8fbcdb}
.yr__c .s{background:rgba(49,160,80,.22);color:var(--green-lt)}
.yr__c .n{background:rgba(179,134,47,.22);color:#d8b667}
.sec--cream .yr__c .b{background:rgba(63,111,143,.16);color:#2f5c7a}
.sec--cream .yr__c .s{background:rgba(49,160,80,.16);color:var(--green-dk)}
.sec--cream .yr__c .n{background:rgba(179,134,47,.20);color:#7a5c14}

dialog.month{border:0;padding:0;border-radius:16px;max-width:620px;width:calc(100% - 32px);
  background:var(--cream);color:var(--ink);box-shadow:0 24px 70px rgba(0,0,0,.42)}
dialog.month::backdrop{background:rgba(9,12,15,.7)}
.month__hd{display:flex;align-items:flex-start;gap:14px;padding:24px 24px 6px}
.month__hd h2{margin:0;font-size:26px}
.month__bd{padding:0 24px 24px;max-height:70vh;overflow:auto}
.month__bd h3{font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--green-dk);
  margin:20px 0 8px}
.month__bd ul{list-style:none;margin:0;padding:0}
.month__bd li{padding:8px 0;border-bottom:1px dashed rgba(13,20,26,.12);font-size:15px;line-height:1.5}
.month__bd li:last-child{border-bottom:0}
.month__empty{color:var(--muted-dk);font-style:italic}
/* inline text that opens a dialog should look like a link, not a button */
.linkish{background:none;border:0;padding:0;font:inherit;color:var(--green-lt);
  text-decoration:underline;cursor:pointer}
.sec--cream .linkish,.month__bd .linkish,details.faq .linkish{color:var(--green-dk)}
.linkish:hover{opacity:.8}

/* ── "ways to help" — the page's call to action, not a mid-page afterthought ── */
.ways{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px;margin-top:34px}
.way{background:#fff;border:2px solid rgba(13,20,26,.10);border-radius:var(--r);padding:24px;
  display:flex;flex-direction:column;text-align:center;transition:.16s;height:100%}
.sec--dark .way,.sec--dark2 .way{background:var(--char-2);border-color:var(--line)}
.way:hover{border-color:var(--green);transform:translateY(-3px);
  box-shadow:0 10px 28px rgba(49,160,80,.16)}
.way__i{width:56px;height:56px;border-radius:50%;background:rgba(49,160,80,.14);
  display:flex;align-items:center;justify-content:center;margin:0 auto 14px}
.way__i svg{width:28px;height:28px;stroke:var(--green-dk);fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.sec--dark .way__i,.sec--dark2 .way__i{background:rgba(49,160,80,.20)}
.sec--dark .way__i svg,.sec--dark2 .way__i svg{stroke:var(--green-lt)}
.way h3{font-size:19px;margin:0 0 6px}
.way p{font-size:15px;flex:1;margin-bottom:16px}
.way .btn{width:100%;padding:11px 18px;font-size:15px}

/* ── featured campaign band ── */
.feat{background:var(--green);border-radius:18px;padding:clamp(26px,4vw,42px);color:#fff;
  box-shadow:0 14px 40px rgba(49,160,80,.28)}
.feat__tag{display:inline-block;background:rgba(255,255,255,.20);font-family:var(--head);
  font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:5px 14px;border-radius:999px;margin-bottom:14px}
.feat h2{color:#fff;margin:0 0 10px;font-size:clamp(28px,4.2vw,42px)}
/* scope to direct children: .feat p would also hit text inside the white panel,
   and at higher specificity than .feat__goal, painting it white on white */
.feat>p,.feat__grid>div>p{color:rgba(255,255,255,.94)}
.feat__panel p{color:var(--ink)}
.feat__grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(20px,3vw,34px);align-items:center;
  margin-top:22px}
@media(max-width:820px){.feat__grid{grid-template-columns:1fr}}
.feat__panel{background:#fff;border-radius:14px;padding:22px;color:var(--ink)}
.feat__panel .feat__goal{font-family:var(--display);font-size:clamp(34px,5vw,48px);color:var(--green-dk);
  line-height:1;margin:0}
.feat__panel .feat__sub{font-family:var(--head);font-size:14px;color:var(--muted-dk);margin:2px 0 14px}
.feat .btn{background:#fff;color:var(--green-dk);border-color:#fff}
.feat .btn:hover{background:#f0f5f1;border-color:#f0f5f1}

/* Zeffy's thermometer iframe contains a full-height toast container, which makes
   the frame scrollable. Clip it: the visible content is a single line + bar. */
.therm{overflow:hidden;height:64px;border-radius:6px}
.therm iframe{display:block;border:0;width:calc(100% + 22px);height:104px;background:transparent}

/* artwork behind the featured campaign band */
.feat{position:relative;overflow:hidden}
.feat::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--mascot) center/cover no-repeat;opacity:.13;mix-blend-mode:luminosity}
.feat>*{position:relative;z-index:1}
.ended{font-family:var(--head);font-size:14px;font-weight:700;color:var(--muted-dk);
  background:rgba(13,20,26,.06);border-radius:8px;padding:10px 14px;margin:12px 0 14px;text-align:center}
/* --muted-dk on a charcoal card is 2.1:1 — below AA at any size. On dark
   sections the same text needs the light muted, and a light tint rather than a
   dark one, or it reads as a smudge. */
.sec--dark .ended,.sec--dark2 .ended{color:var(--muted);background:rgba(255,255,255,.06)}

/* ── element & grade parents roster ── */
.ep{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:16px;margin-top:32px}
.ep__g{background:var(--char-2);border:1px solid var(--line);border-radius:var(--r);padding:18px 20px}
.sec--cream .ep__g{background:#fff;border-color:rgba(13,20,26,.10)}
.ep__g h3{font-size:15px;letter-spacing:.1em;text-transform:uppercase;color:var(--green-lt);
  margin:0 0 10px;padding-bottom:8px;border-bottom:1px solid var(--line)}
.sec--cream .ep__g h3{color:var(--green-dk);border-bottom-color:rgba(13,20,26,.10)}
.ep__g ul{list-style:none;margin:0;padding:0}
.ep__g li{display:flex;gap:10px;align-items:baseline;padding:6px 0;font-size:15px}
.ep__el{font-family:var(--head);font-weight:700;font-size:13px;color:var(--green-lt);
  min-width:52px;flex:0 0 auto}
.sec--cream .ep__el{color:var(--green-dk)}
.ep__n{color:#dfe3e8}
.sec--cream .ep__n{color:var(--ink)}
.ep__open{color:var(--muted);font-style:italic;font-size:14px}
.sec--cream .ep__open{color:var(--muted-dk)}
/* STEAM Saturday session list */
.sessions{list-style:none;padding:0;margin:0 0 14px}
.sessions li{padding:10px 0;border-bottom:1px dashed rgba(13,20,26,.12)}
.sec--dark .sessions li,.sec--dark2 .sessions li{border-bottom-color:var(--line)}
.sessions li:last-child{border-bottom:0}
.sessions b{display:block;font-family:var(--head);font-size:15px}
.sessions span{display:block;font-size:14px;color:var(--muted-dk);margin-top:2px}
.sec--dark .sessions span,.sec--dark2 .sessions span{color:var(--muted)}
.sessions em{display:block;font-family:var(--head);font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--green-dk);font-style:normal;margin-top:4px}
.sec--dark .sessions em,.sec--dark2 .sessions em{color:var(--green-lt)}

/* ── carpool & dismissal ── */
/* The carlines are named by colour, so the chip always spells out the line and
   the door too — the colour is reinforcement, never the only cue. */
.lane{display:inline-flex;align-items:center;gap:7px;font-family:var(--head);font-weight:700;
  font-size:13px;letter-spacing:.05em;line-height:1.4;padding:3px 12px;border-radius:999px;
  border:2px solid currentColor;white-space:nowrap}
.lane::before{content:"";width:9px;height:9px;border-radius:50%;background:currentColor;flex:0 0 auto}
.lane--red{color:var(--lane-red-lt)}
.lane--blue{color:var(--lane-blue-lt)}
.sec--cream .lane--red{color:var(--lane-red)}
.sec--cream .lane--blue{color:var(--lane-blue)}
.lane + .lane{margin-left:6px}
.card h3 .lane{vertical-align:middle}
/* dismissal time, sitting under the grade band on a .cal__m card */
.dsm__t{font-family:var(--head);font-weight:700;font-size:25px;line-height:1;
  color:var(--green-lt);margin:0 0 12px}
.sec--cream .dsm__t{color:var(--green-dk)}

/* ── corner mascot ── */
/* The husky is drawn by WebGL into a canvas (assets/husky.js), on a transparent
   background — no disc, no card, just the drawing sitting on the page.
   It is pinned to the viewport rather than to the page, and what scrolls behind it
   alternates charcoal and cream, so it is drawn in black or in white depending on
   which the background is not; husky.js measures that and flips the ink. The shadow
   under it is a neutral grey so that one value works in both states — a dark shadow
   vanishes on charcoal and a light one vanishes on cream, but grey reads as a soft
   halo against the dark and as a cast shadow against the cream, and it is what keeps
   the drawing off a photograph on the gallery.
   Below the header's z-index 50 on purpose, so an open mobile menu covers it. */
.husky{position:fixed;z-index:40;
  right:max(14px,env(safe-area-inset-right));
  bottom:max(14px,env(safe-area-inset-bottom));
  /* Small enough on a phone that it clips the edge of a paragraph rather than a
     word of it, and big enough on a desktop that the drawing is legible. */
  width:clamp(78px,21vw,156px);aspect-ratio:1;
  pointer-events:none;
  filter:drop-shadow(0 2px 4px rgba(125,130,136,.72));
  opacity:0;transition:opacity .5s ease}
.husky--in{opacity:1}
.husky__c{display:block;width:100%;height:100%}
/* Orbit is a mouse affordance. On a touch screen the badge stays inert so a thumb
   scrolling past the corner scrolls the page instead of spinning the dog. */
.husky--grab{pointer-events:auto;cursor:grab}
.husky--grab:active{cursor:grabbing}
@media(prefers-reduced-motion:reduce){.husky{display:none}}

/* anchored sections (gallery albums) clear the sticky header when linked to */
.sec[id]{scroll-margin-top:88px}
