/* Brush Bunni — site styles.
   Moved out of base.html so browsers cache it instead of re-downloading the
   CSS with every page. Image paths are relative: this file and the
   backgrounds both live in blog/static/blog/. */

/* =========================================================================
   DESIGN TOKENS
   One source of truth for colour, radius, shadow and layout. Before this
   existed the site ran three unrelated purple families — #6c5ce7/#b06ae6 on
   the event pages, #667eea/#f093fb on contact and BB Notes, #b565d8 for the
   contact focus ring — so the same "primary button" looked different on
   three pages. Everything below now resolves to --brand-*.
   ========================================================================= */
:root {
  /* Brand */
  --brand: #7b6cf6;
  --brand-deep: #4b3fd1;
  --brand-ink: #6c5ce7;
  --brand-magenta: #b06ae6;
  --brand-pink: #f0709b;
  --brand-gradient: linear-gradient(135deg, var(--brand), var(--brand-magenta));
  --accent-orange: #ff9a00;

  /* Ink — text, darkest to lightest */
  --ink-900: #111;
  --ink-800: #222;
  --ink-700: #333;
  --ink-600: #444;
  --ink-500: #666;
  --ink-400: #888;
  --ink-300: #aaa;
  --ink-200: #ccc;
  --ink-muted: #8a8a9a;

  /* Surfaces */
  --surface: rgba(255, 255, 255, 0.94);
  --surface-strong: rgba(255, 255, 255, 0.92);
  --surface-page: rgba(255, 255, 255, 0.9);
  --surface-soft: rgba(255, 255, 255, 0.75);
  --surface-tint: #faf9ff;
  --surface-tint-strong: #ece9ff;
  --surface-field: #fafafa;
  --hairline: rgba(0, 0, 0, 0.06);
  --field-border: #ddd;

  /* Dark surfaces used by the events pages */
  --cream: #f2efe9;
  --bar-dark: #4a4744;
  --carousel-dark: #0f0f11;
  --card-dark: #232323;

  /* Feedback */
  --danger: #d33;
  --success-bg: #dcfce7;
  --success-ink: #166534;

  /* Radii */
  --r-sm: 10px;
  --r-md: 12px;
  --r-lg: 14px;
  --r-xl: 16px;
  --r-2xl: 20px;
  --r-pill: 999px;

  /* Shadows */
  --shadow-sm: 0 4px 20px rgba(0, 0, 0, 0.08);
  --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.15);
  --shadow-lg: 0 10px 34px rgba(0, 0, 0, 0.22);
  --shadow-brand: 0 6px 18px rgba(123, 108, 246, 0.4);
  --shadow-brand-lg: 0 10px 24px rgba(123, 108, 246, 0.5);

  /* Layout */
  --sidebar-w: 280px;
  --font: 'Inter', sans-serif;
}

/* =========================================================================
   BASE RESET
   Bootstrap used to supply these silently. Dropping the CDN bundle dropped
   them too: without the border-box rule, .content-box added its 30px padding
   *outside* its calc() width and overhung the viewport by 60px.
   ========================================================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
}

h1, h2, h3, h4, h5, h6 {
  margin-top: 0;
  line-height: 1.2;
}

p {
  margin-top: 0;
}

/* Form controls do not inherit typography from the page by default — the UA
   gives them their own font. Without this the Send-message button rendered
   5px shorter than it used to. */
button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  margin: 0;
}

/* =========================================================================
   KEYBOARD FOCUS
   Only the contact inputs had a focus style, so tabbing through the site
   showed nothing at all — the nav, the event tabs, the carousel arrows and
   the gallery thumbnails were all invisible to a keyboard user.

   :focus-visible, not :focus, so the ring appears for keyboard and
   assistive-tech users and never fires on a mouse click.
   ========================================================================= */
:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

/* The sidebar sits on photographs, where the brand purple can disappear into
   a dark patch. White reads against every one of the background images. */
.nav-link:focus-visible,
.social-icons a:focus-visible {
  outline-color: #fff;
}

/* Same problem on the events page's dark bars and the lightbox scrim. */
.event-tabs-nav:focus-visible,
.carousel-nav:focus-visible,
.ev-lb-nav:focus-visible,
.ev-lb-close:focus-visible {
  outline-color: #fff;
}

/* The event tabs are chevrons cut with clip-path, and clip-path clips the
   outline away — the browser reports a 3px outline that is never painted.
   An inset shadow is drawn inside the shape, so it survives the clip. */
.event-tab:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 3px #fff;
}

.event-tab.active:focus-visible {
  box-shadow: inset 0 0 0 3px var(--brand);
}

body {
  /* Also Bootstrap's. The browser default (~1.2) tightened every block of
     text on the site, most visibly the sidebar menu. */
  line-height: 1.5;
}

html,
body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  font-family: var(--font);
  overflow-y: auto;
  overflow-x: hidden; /* guard against accidental sideways scroll on mobile */
}

body {
  background-color: #2b2b2b; /* fallback while the image loads / if it fails */
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
}

/* ===== Per-page backgrounds =====
   JPEG line first = fallback for old browsers that ignore image-set.
   image-set line = WebP for modern browsers, JPEG for those without WebP. */
body.page-home {
  background-image: url("bg_about.jpg");
  background-image: image-set(url("bg_about.webp") type("image/webp"), url("bg_about.jpg") type("image/jpeg"));
}
body.page-community,
body.page-gallery {
  background-image: url("bg_community.jpg");
  background-image: image-set(url("bg_community.webp") type("image/webp"), url("bg_community.jpg") type("image/jpeg"));
}
body.page-be_online {
  background-image: url("bg_online.jpg");
  background-image: image-set(url("bg_online.webp") type("image/webp"), url("bg_online.jpg") type("image/jpeg"));
}
body.page-events {
  background-image: url("bg_events.jpg");
  background-image: image-set(url("bg_events.webp") type("image/webp"), url("bg_events.jpg") type("image/jpeg"));
}
body.page-shop,
body.page-project_bunni {
  background-image: url("bg_shop.jpg");
  background-image: image-set(url("bg_shop.webp") type("image/webp"), url("bg_shop.jpg") type("image/jpeg"));
}
/* These two were 2560x1572 JPEGs holding a single flat colour — 48 KB each to
   say what one line of CSS says. No image, so no download and no decode. */
body.page-members {
  background-color: #5cbeed;
}
body.page-contact {
  background-color: #ffa56e;
}

/* Lighter backgrounds on phones (~1200px wide instead of 1920px) */
@media (max-width: 768px) {
  body.page-home {
    background-image: url("bg_about-mobile.jpg");
    background-image: image-set(url("bg_about-mobile.webp") type("image/webp"), url("bg_about-mobile.jpg") type("image/jpeg"));
  }
  body.page-community,
  body.page-gallery {
    background-image: url("bg_community-mobile.jpg");
    background-image: image-set(url("bg_community-mobile.webp") type("image/webp"), url("bg_community-mobile.jpg") type("image/jpeg"));
  }
  body.page-be_online {
    background-image: url("bg_online-mobile.jpg");
    background-image: image-set(url("bg_online-mobile.webp") type("image/webp"), url("bg_online-mobile.jpg") type("image/jpeg"));
  }
  body.page-events {
    background-image: url("bg_events-mobile.jpg");
    background-image: image-set(url("bg_events-mobile.webp") type("image/webp"), url("bg_events-mobile.jpg") type("image/jpeg"));
  }
  body.page-shop,
  body.page-project_bunni {
    background-image: url("bg_shop-mobile.jpg");
    background-image: image-set(url("bg_shop-mobile.webp") type("image/webp"), url("bg_shop-mobile.jpg") type("image/jpeg"));
  }
}

/* ===== Translucent page scrollbar ===== */
html {
  scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
  scrollbar-width: thin;
}

body::-webkit-scrollbar {
  width: 8px;
}

body::-webkit-scrollbar-track {
  background: transparent;
}

body::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.4);
  border-radius: 5px;
}

body::-webkit-scrollbar-thumb:hover {
  background-color: rgba(255, 255, 255, 0.7);
}

/* ===== Sidebar ===== */
.sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--sidebar-w);
  background-color: transparent;
  color: white;
  padding: 30px 0 30px 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  z-index: 1000;
}

/* The menu block scrolls on its own so the social icons stay pinned to the
   bottom; min-height:0 is what lets a flex child actually shrink and scroll. */
.sidebar > div:first-child {
  overflow-y: auto;
  min-height: 0;
  padding-right: 8px; /* keep text clear of the scrollbar */
}

.sidebar > div:first-child::-webkit-scrollbar {
  width: 8px;
}
.sidebar > div:first-child::-webkit-scrollbar-track {
  background: transparent;
}
.sidebar > div:first-child::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.35);
  border-radius: 6px;
}
.sidebar > div:first-child::-webkit-scrollbar-thumb:hover {
  background-color: rgba(255, 255, 255, 0.55);
}

.menu-container {
  position: relative;
}

/* Vertical white rule to the right of the menu */
.menu-container::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 3px;
  height: 100%;
  background-color: white;
}

.logo {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  padding-top: 15px;
  padding-left: 55px;
  margin-bottom: 20px;
}

/* The logo is a link home now. line-height:0 stops the anchor adding a few
   pixels of text baseline under the image and nudging the menu down. */
.logo a {
  display: inline-block;
  line-height: 0;
  text-decoration: none;
  border-radius: var(--r-md);
}

.logo a:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 4px;
}

.logo img {
  height: 200px;
  width: auto;
}

/* This replaces Bootstrap. The CDN bundle (~230 KB) was loaded on every page
   to supply exactly this: `.nav` as a flex container and `.flex-column` to
   stand it upright. */
.nav {
  display: flex;
  flex-direction: column;
}

.nav-link {
  font-family: 'Poppins', sans-serif;
  color: white;
  font-size: 1.7rem;
  padding: 9px 38px;
  font-weight: 500;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
  text-decoration: none;
  transition: all 0.2s ease;
}

.nav-link.active {
  background-color: white;
  color: black;
  font-weight: bold;
}

.nav-link:hover {
  background-color: rgba(255, 255, 255, 0.15);
}

/* ===== Fitting the menu to short screens =====
   The menu must never need to scroll. When it overflowed, the script that
   brought the current page into view had to scroll it after the first paint —
   up to 323px of movement, which read as the whole menu jumping on every
   navigation. Shrinking the logo and links to fit removes the cause instead
   of animating around it.

   These sit AFTER the .logo/.nav-link rules on purpose: the previous
   max-height block was written before them and lost the cascade, so it never
   applied at all — the logo stayed 200px at every height. */
@media (min-width: 769px) and (max-height: 880px) {
  .logo img { height: 150px; }
  .logo { padding-top: 10px; margin-bottom: 14px; }
  .nav-link { font-size: 1.45rem; padding: 7px 34px; margin-bottom: 5px; }
}

@media (min-width: 769px) and (max-height: 740px) {
  .logo img { height: 112px; }
  .logo { padding-top: 6px; margin-bottom: 10px; }
  .nav-link { font-size: 1.25rem; padding: 5px 30px; margin-bottom: 4px; }
  .social-icons { padding: 10px 20px 14px; }
}

@media (min-width: 769px) and (max-height: 640px) {
  .sidebar { padding: 16px 0 16px 20px; }
  .logo img { height: 84px; }
  .logo { padding-top: 4px; margin-bottom: 8px; }
  .nav-link { font-size: 1.1rem; padding: 4px 26px; margin-bottom: 3px; }
  .social-icons { padding: 8px 20px 10px; }
  .social-icons img { width: 22px; }
}

/* Social icons sit at the bottom of the sidebar, outside the scrolling area */
.social-icons {
  display: flex;
  justify-content: space-around;
  padding: 16px 20px 20px 20px;
}

.social-icons img {
  width: 28px;
  height: auto;
  filter: brightness(0) invert(1);
  transition: transform 0.2s;
  object-fit: contain;
}

.social-icons img:hover {
  transform: scale(1.1);
}

/* ===== Content ===== */
.content {
  flex-grow: 1;
  position: relative;
  overflow: hidden;
  margin-left: var(--sidebar-w);
  /* A flex item defaults to min-width:auto, which lets wide children (the
     events carousel) stretch this column past the viewport. */
  min-width: 0;
}

.content-box {
  position: fixed;
  left: var(--sidebar-w);
  margin-top: var(--content-offset, 60px);
  width: calc(100vw - var(--sidebar-w) - 40px);
  max-width: 90%;
  max-height: 80vh;
  background-color: var(--surface-page);
  padding: 30px;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-md);
  overflow-y: auto;
  z-index: 1;
  transition: all 0.25s ease;
}

/* Set by the positioning JS while it writes --content-offset, so placing the
   box never animates. Without it the box slid down the page on every load. */
.content-box.is-positioning {
  transition: none;
}

/* The browser can get a paint in before the end-of-body script runs, which
   showed the box at the default 60px for one frame before it moved to its
   real offset — the slide people kept seeing. Keep it invisible (but still
   laid out, so nothing reflows) until the script has placed it.
   Scoped to html.js: with JavaScript off the box is never hidden. */
html.js .content-box:not(.is-placed) {
  visibility: hidden;
  /* Failsafe. Hiding content until a script reveals it means a broken script
     hides the page — which is exactly what happened when a duplicate `let`
     killed the block and the Events page rendered blank. This reveals the box
     after 1.2s no matter what, so the worst case is a late paint, never
     missing content. */
  animation: content-box-failsafe 0s linear 1.2s forwards;
}

@keyframes content-box-failsafe {
  to { visibility: visible; }
}

/* The events pages lay out their own cards, so they drop the white box.
   These flow in the normal document instead of being position:fixed — the
   fixed box was offset by the sidebar *and* sized at 100% of the
   viewport, so its right-hand side was cut off outside the screen. */
body.page-events .content {
  margin-left: var(--sidebar-w);
  overflow: visible;
}
body.page-events .content-box {
  position: static;
  left: auto;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 24px 0 0 !important;
  max-width: 100% !important;
  width: auto !important;
  max-height: none !important;
  overflow: visible !important;
  margin-top: 0 !important;
}

.content-box::-webkit-scrollbar {
  width: 8px;
}

.content-box::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.05);
}

.content-box::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
}

.content-box::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 0, 0, 0.5);
}

/* ===== Custom vertical scrollbar for the fixed content box ===== */
.content-scrollbar {
  position: fixed;
  right: 20px;
  top: 20%;
  width: 6px;
  height: 60%;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  z-index: 1001;
  cursor: pointer;
}

.scrollbar-thumb {
  position: absolute;
  top: 0;
  width: 100%;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 3px;
  min-height: 20px;
  transition: all 0.2s ease;
}

.scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.8);
  width: 8px;
  right: -1px;
}

/* ===== Mobile menu controls (hidden on desktop) ===== */
.menu-toggle {
  display: none;
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  left: max(14px, env(safe-area-inset-left));
  z-index: 1100;
  width: 46px;
  height: 46px;
  border: none;
  border-radius: var(--r-sm);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(4px);
  cursor: pointer;
  padding: 0;
}

.menu-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  margin: 4px auto;
  background: #fff;
  border-radius: 2px;
  transition: transform 0.25s ease, opacity 0.25s ease;
}

/* Animate the burger into an X when the menu is open */
body.menu-open .menu-toggle span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
body.menu-open .menu-toggle span:nth-child(2) {
  opacity: 0;
}
body.menu-open .menu-toggle span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 900;
  opacity: 0;
  transition: opacity 0.25s ease;
}

/* ===== Mobile layout ===== */
@media (max-width: 768px) {
  .menu-toggle {
    display: block;
  }

  .sidebar {
    width: 260px;
    background-color: rgba(20, 20, 20, 0.96);
    transform: translateX(-100%);
    transition: transform 0.28s ease;
    padding-top: calc(70px + env(safe-area-inset-top)); /* clear the burger + notch */
  }
  body.menu-open .sidebar {
    transform: translateX(0);
  }

  .sidebar-overlay {
    display: block;
    pointer-events: none;
  }
  body.menu-open .sidebar-overlay {
    opacity: 1;
    pointer-events: auto;
  }

  /* The vertical white divider only makes sense next to the fixed desktop menu */
  .menu-container::after {
    display: none;
  }

  /* The drawer is wider and roomier than the old 260px strip: it is the only
     thing on screen when open, so the logo and links can be read at a glance
     rather than squeezed. */
  .logo {
    padding-left: 24px;
    padding-top: 18px;
    margin-bottom: 18px;
  }
  .logo img {
    height: 132px;
  }
  .nav-link {
    font-size: 1.45rem;
    padding: 11px 26px;
    margin-bottom: 6px;
  }

  /* Content takes the full width and scrolls with the page, not in a fixed box.
     body.page-events is repeated here because it outranks a bare .content. */
  .content,
  body.page-events .content {
    margin-left: 0;
    overflow: visible;
    /* Clears the fixed burger button. Padding, not margin: a child's margin-top
       collapses through this wrapper now that the box is no longer fixed. */
    padding-top: 70px;
  }
  .content-box,
  body.page-events .content-box {
    position: static;
    left: auto;
    width: auto !important;
    max-width: 100%;
    max-height: none;
    margin: 0 14px 24px;
    padding: 20px !important;
    overflow: visible;
    background-color: var(--surface-strong);
  }

  /* The event pages bring their own surfaces, so keep the wrapper transparent */
  body.page-events .content-box {
    background-color: transparent !important;
    padding: 0 !important;
    margin: 0 12px 24px;
  }

  /* The custom desktop scrollbar is tied to the fixed content box — hide it */
  .content-scrollbar {
    display: none;
  }
}

/* =========================================================================
   BUTTONS
   One component with modifiers. This replaced three separately-invented
   buttons: .page-cta (135deg purple gradient), .ev-btn--primary (the same
   gradient, re-declared) and .contact-submit (a 45deg blue/pink gradient and
   a 25px radius). .page-cta / .ev-btn / .contact-submit are kept as aliases
   so existing templates keep working.
   ========================================================================= */
.btn,
.page-cta,
.ev-btn,
.contact-submit {
  display: inline-block;
  padding: 13px 26px;
  border: none;
  border-radius: var(--r-pill);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover,
.page-cta:hover,
.ev-btn:hover,
.contact-submit:hover {
  transform: translateY(-2px);
}

.btn--primary,
.page-cta,
.ev-btn--primary,
.contact-submit {
  background: var(--brand-gradient);
  color: #fff;
  box-shadow: var(--shadow-brand);
}

.btn--primary:hover,
.page-cta:hover,
.ev-btn--primary:hover,
.contact-submit:hover {
  color: #fff;
  box-shadow: var(--shadow-brand-lg);
}

.btn--ghost,
.ev-btn--ghost {
  background: var(--surface);
  color: var(--brand-deep);
  box-shadow: none;
}

.btn--ghost:hover,
.ev-btn--ghost:hover {
  background: #fff;
  box-shadow: var(--shadow-sm);
}

/* ===== Editable page content (About / Community / Members / Project Bunni) ===== */
.page-heading {
  font-size: 2rem;
  font-weight: 700;
  margin: 0 0 0.4rem;
}

.page-intro {
  color: var(--ink-500);
  font-size: 1.05rem;
  margin: 0 0 1.4rem;
}

.page-body {
  color: var(--ink-700);
  line-height: 1.65;
  max-width: 68ch;
}

.page-body p {
  margin: 0 0 1rem;
}

.page-image {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--r-xl);
  margin: 0 0 1.5rem;
}

.page-cta {
  margin-top: 0.6rem;
}

/* ===== Members grid ===== */
.member-grid {
  list-style: none;
  padding: 0;
  margin: 1.8rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 1.2rem;
}

.member-card {
  background: var(--surface-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 1.1rem 1rem 1rem;
  text-align: center;
}

.member-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 auto 0.7rem;
  display: block;
  background: var(--surface-tint-strong);
}

.member-avatar--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.2rem;
}

.member-name {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0 0 0.15rem;
}

.member-role {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brand-ink);
  margin: 0 0 0.6rem;
}

.member-bio {
  font-size: 0.9rem;
  color: var(--ink-500);
  line-height: 1.5;
  margin: 0 0 0.7rem;
}

.member-links {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
}

.member-links a {
  font-size: 0.85rem;
  color: var(--brand-ink);
  text-decoration: none;
}

.member-links a:hover {
  text-decoration: underline;
}

/* =========================================================================
   BB NOTES  (was inline in be_online.html)
   ========================================================================= */
.bb-notes-section h2 {
  font-size: 1.4rem;
  font-weight: 600;
  margin-bottom: 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid #eee;
}

.note-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.note-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  background: var(--surface-field);
  border-radius: var(--r-md);
  text-decoration: none;
  color: inherit;
  transition: all 0.2s ease;
  border: 1px solid transparent;
}

.note-card:hover {
  background: #fff;
  border-color: #e0e0e0;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  transform: translateY(-1px);
  text-decoration: none;
  color: inherit;
}

.note-card.pinned {
  border-left: 3px solid var(--accent-orange);
  background: #fffaf0;
}

.note-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--r-sm);
  object-fit: cover;
  flex-shrink: 0;
}

.note-thumb-placeholder {
  width: 56px;
  height: 56px;
  border-radius: var(--r-sm);
  background: var(--brand-gradient);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 22px;
}

.note-info {
  flex: 1;
  min-width: 0;
}

.note-title {
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink-700);
  margin-bottom: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.note-desc {
  font-size: 0.85rem;
  color: var(--ink-400);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.note-date {
  font-size: 0.8rem;
  color: var(--ink-300);
  white-space: nowrap;
  flex-shrink: 0;
}

.note-arrow {
  color: var(--ink-200);
  font-size: 1.2rem;
  flex-shrink: 0;
  transition: color 0.2s;
}

.note-card:hover .note-arrow,
.note-card:hover .note-title {
  color: var(--brand);
}

.empty-notes {
  text-align: center;
  padding: 40px 20px;
  color: #bbb;
}

.empty-notes .icon {
  font-size: 40px;
  margin-bottom: 10px;
}

@media (max-width: 600px) {
  .note-card {
    padding: 12px 14px;
  }
  .note-thumb,
  .note-thumb-placeholder {
    width: 44px;
    height: 44px;
  }
  .note-date {
    display: none;
  }
}

/* =========================================================================
   CONTACT FORM  (was inline in contact.html)
   ========================================================================= */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-width: 560px;
}

.field label {
  display: block;
  font-weight: 600;
  color: var(--ink-700);
  margin-bottom: 0.4rem;
  font-size: 0.95rem;
}

.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--field-border);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink-700);
  background: var(--surface-field);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
  box-sizing: border-box;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand-magenta);
  box-shadow: 0 0 0 3px rgba(176, 106, 230, 0.18);
  background: #fff;
}

/* The soft halo above is enough when you clicked into the field, but a
   keyboard user needs the same strong ring as everything else. This has to be
   restated because `.field input:focus` outranks the global :focus-visible
   rule and would otherwise cancel the outline. */
.field input:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

.field textarea {
  resize: vertical;
  min-height: 120px;
}

.field .errorlist {
  list-style: none;
  padding: 0;
  margin: 0.4rem 0 0;
  color: var(--danger);
  font-size: 0.85rem;
}

.contact-submit {
  align-self: flex-start;
  padding: 13px 34px;
}

.form-success {
  background: var(--success-bg);
  color: var(--success-ink);
  border-radius: var(--r-md);
  padding: 14px 18px;
  margin-bottom: 1.5rem;
  font-weight: 600;
}

/* =========================================================================
   EVENT DETAIL PAGE
   Lives on a transparent .content-box (inherited from the events page), so
   every section brings its own surface instead of relying on the white card.
   ========================================================================= */
.ev {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 4px 40px;
  color: var(--ink-800);
}

.ev-back {
  display: inline-block;
  margin-bottom: 18px;
  padding: 9px 18px;
  border-radius: var(--r-pill);
  background: var(--surface-strong);
  color: var(--ink-700);
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  backdrop-filter: blur(6px);
  transition: transform 0.15s ease, background 0.15s ease;
}

.ev-back:hover {
  background: #fff;
  transform: translateX(-2px);
  color: var(--ink-900);
}

/* ----- Photo grid ----- */
.ev-grid-item {
  margin: 0;
}

.ev-thumb {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  border-radius: var(--r-lg);
  overflow: hidden;
  cursor: zoom-in;
  background: var(--surface-tint-strong);
  line-height: 0;
}

.ev-thumb img,
.ev-grid-item video {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-lg);
  transition: transform 0.35s ease;
}

.ev-thumb:hover img {
  transform: scale(1.04);
}

.ev-caption {
  margin: 7px 2px 0;
  font-size: 0.85rem;
  color: var(--ink-500);
  line-height: 1.4;
}

/* ----- Lightbox ----- */
.ev-lightbox {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 20px;
  background: rgba(10, 10, 14, 0.92);
  backdrop-filter: blur(4px);
}

.ev-lightbox[hidden] {
  display: none;
}

.ev-lb-figure {
  margin: 0;
  max-width: min(1100px, 88vw);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.ev-lb-figure img {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--r-sm);
}

.ev-lb-figure figcaption {
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.9rem;
  text-align: center;
}

.ev-lb-nav,
.ev-lb-close {
  border: none;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  cursor: pointer;
  border-radius: 50%;
  transition: background 0.15s ease;
}

.ev-lb-nav {
  width: 48px;
  height: 48px;
  font-size: 30px;
  line-height: 1;
  flex: 0 0 auto;
}

.ev-lb-close {
  position: absolute;
  top: 18px;
  right: 20px;
  width: 42px;
  height: 42px;
  font-size: 26px;
  line-height: 1;
}

.ev-lb-nav:hover,
.ev-lb-close:hover {
  background: rgba(255, 255, 255, 0.28);
}

@media (max-width: 640px) {
  .ev-lb-nav {
    width: 40px;
    height: 40px;
    font-size: 24px;
  }
  /* A sign-up button is the one thing a phone reader is likely to tap, so it
     gets the full width rather than sharing a row with the note.com link. */
  .ev-actions .btn {
    flex: 1 1 100%;
    text-align: center;
  }
}

/* ===== Narrow phones ===== */
@media (max-width: 480px) {
  .content-box,
  body.page-events .content-box {
    margin: 0 10px 20px;
    padding: 20px;
    border-radius: var(--r-md);
  }
  /* Still generous on a narrow phone — only a little tighter than 768px. */
  .logo img {
    height: 116px;
  }
  .nav-link {
    font-size: 1.35rem;
    padding: 10px 22px;
  }
}

/* =========================================================================
   EVENTS LIST PAGE  (was inline in events.html)
   ========================================================================= */
/* Override default content box for events page */
.page-events .content-box {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    max-width: 100% !important;
    width: 100% !important;
    max-height: none !important;
    overflow: visible !important;
    margin-top: 0 !important;
    position: static !important;
}

/* Main events container */
.events-container {
    width: 100%;
    padding: 40px 40px 40px 0;
    margin: 0;
    min-height: 100vh;
}

/* Combined wrapper with rounded corners — one continuous card holding
   every section (previous events, carousel, upcoming), matching the
   reference design. */
.events-wrapper {
    background: rgba(26, 26, 28, 0.95);
    backdrop-filter: blur(20px);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7);
}

/* Previous Events Section */
.previous-events-section {
    padding: 32px 32px 28px;
}

.events-title {
    font-size: 2.3rem;
    font-weight: 700;
    color: white;
    margin: 0 0 18px;
    font-family: 'Inter', sans-serif;
}

/* ----- Tabs: horizontally scrollable strip on a shared gray bar -----
   There are more past events than fit on one screen, so the strip
   scrolls instead of overflowing the rounded card (the old fixed-width
   tab strip broke as soon as an 8th event was added). Prev/next arrows
   (like the photo carousel below) make the overflow discoverable —
   the native scrollbar is hidden and mouse wheel doesn't scroll
   sideways, so without the arrows the tabs past the first screenful
   were unreachable. */
.event-tabs-wrapper {
    position: relative;
    margin: 0 0 22px;
    background: var(--bar-dark);
    border-radius: 16px;
}

.event-tabs-scroll {
    overflow-x: auto;
    overflow-y: hidden;
    -ms-overflow-style: none;
    scrollbar-width: none;
    border-radius: inherit;
}
.event-tabs-scroll::-webkit-scrollbar {
    display: none;
}

/* Fade behind the arrow buttons, same technique as the photo carousel. */
.event-tabs-wrapper::before,
.event-tabs-wrapper::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    width: 50px;
    z-index: 2;
    pointer-events: none;
}
.event-tabs-wrapper::before {
    left: 0;
    background: linear-gradient(to right, var(--bar-dark), transparent);
}
.event-tabs-wrapper::after {
    right: 0;
    background: linear-gradient(to left, var(--bar-dark), transparent);
}

.event-tabs-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    cursor: pointer;
    z-index: 3;
    font-size: 26px;
    line-height: 1;
    padding: 6px;
    transition: color 0.2s ease;
}

.event-tabs-nav:hover {
    color: #fff;
}

.event-tabs-nav.prev { left: 0; }
.event-tabs-nav.next { right: 0; }

/* Dimmed, not forbidden. `cursor: not-allowed` drew the 🚫 symbol over an
   arrow whose only crime was being at the end of the strip — it scolds the
   reader for something harmless. The lower opacity already says "nothing
   that way". */
.event-tabs-nav:disabled {
    opacity: 0.25;
    cursor: default;
}

.event-tabs-container {
    display: flex;
    align-items: stretch;
    height: 34px;
    width: max-content;
    padding: 0 10px;
}

/* Every tab is a breadcrumb segment: a rectangle whose right edge is cut
   to a point and whose left edge carries the matching notch, so the strip
   reads as one connected chain of arrows — the reference mockup — rather
   than a row of loose labels with one highlighted.

   The shape is a clip-path, not the pseudo-element triangle this replaced,
   because a triangle has to be recoloured and re-sized per state; a
   clip-path is one geometry that every tab shares whatever its fill. */
.event-tab {
    --notch: 11px;
    position: relative;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    white-space: nowrap;
    background: rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.72);
    border: none;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.02em;
    padding: 0 20px 0 26px;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
    clip-path: polygon(
        0 0,
        calc(100% - var(--notch)) 0,
        100% 50%,
        calc(100% - var(--notch)) 100%,
        0 100%,
        var(--notch) 50%);
    /* Pull each tab left so its notch swallows the previous tab's point,
       leaving a constant-width slice of the dark bar behind as the
       divider — 4px measured perpendicular to the arrow, not 4px of
       horizontal margin. */
    margin-right: calc(4px - var(--notch));
}

/* Nothing points into the first tab, so it keeps a straight left edge and
   lets the bar's own rounded corner cap the strip. */
.event-tab:first-child {
    padding-left: 18px;
    clip-path: polygon(
        0 0,
        calc(100% - var(--notch)) 0,
        100% 50%,
        calc(100% - var(--notch)) 100%,
        0 100%);
}

.event-tab:hover {
    background: rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.9);
}

.event-tab.active {
    background: var(--cream);
    color: var(--card-dark);
}

/* ----- Photo carousel: three equal photos in a filmstrip, paginated one
   at a time ----- Slide width/position is computed in JS (see
   updateCarousel) so it stays correct at any viewport width. Arrows sit
   in a dark gutter inside the rounded card rather than overlapping the
   photos, echoing the reference design's arrows-outside-the-frame look. */
.gallery-carousel {
    position: relative;
    height: 500px;
    border-radius: 18px;
    overflow: hidden;
    background: var(--carousel-dark);
    padding: 0 46px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
}

.carousel-viewport {
    width: 100%;
    height: 88%;
    overflow: hidden;
}

.carousel-track {
    display: flex;
    align-items: center;
    height: 100%;
    gap: 0;
    will-change: transform;
}

.gallery-slide {
    height: 100%;
    overflow: hidden;
    cursor: zoom-in;
}

.gallery-slide img,
.gallery-slide video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* Neighbours are dimmed and drained of colour so the centre photo is the
       one the eye lands on, as in the reference design. */
    filter: brightness(0.42) saturate(0.5);
    transition: filter 0.35s ease;
}

.gallery-slide.is-centre img,
.gallery-slide.is-centre video {
    filter: none;
}

/* A side photo is still clickable, so it lifts a little on hover rather than
   staying inert. */
.gallery-slide:hover img,
.gallery-slide:hover video {
    filter: brightness(0.72) saturate(0.8);
}

.gallery-slide.is-centre:hover img,
.gallery-slide.is-centre:hover video {
    filter: none;
}

.gallery-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    background: linear-gradient(135deg, var(--brand-ink), var(--brand-magenta) 55%, var(--brand-pink));
    color: white;
    text-align: center;
    padding: 0 20px;
}

.gallery-placeholder .emoji {
    font-size: 56px;
}

.gallery-placeholder .text {
    font-size: 18px;
    font-weight: 600;
}

/* Plain chevrons in the carousel's own dark gutter — no button chrome,
   matching the reference design's arrows-outside-the-photos look. */
.carousel-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    cursor: pointer;
    z-index: 10;
    font-size: 34px;
    line-height: 1;
    padding: 8px;
    transition: color 0.2s ease;
}

.carousel-nav:hover {
    color: #fff;
}

.carousel-nav.prev { left: 4px; }
.carousel-nav.next { right: 4px; }

.carousel-nav:disabled {
    opacity: 0.25;
    cursor: default;
}

/* ----- Upcoming Events ----- */
.upcoming-section {
    background: var(--accent-orange);
}

.upcoming-header {
    color: white;
    font-size: 1.7rem;
    font-weight: 700;
    padding: 24px 32px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* A single column: the cards are wide rows now, not three little tiles, so a
   3-column grid squeezed each one into a third of the width. */
.upcoming-content {
    background: white;
    padding: 28px 32px 36px;
}

/* Minimal card: coloured icon + text, no box/shadow — matches the flat
   reference design instead of the previous drop-shadowed grey tile. */
.upcoming-card {
    display: flex;
    align-items: center;
    gap: 18px;
    text-decoration: none;
    color: inherit;
}

.upcoming-card-icon {
    width: 74px;
    height: 74px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
}

.upcoming-card:nth-child(3n+1) .upcoming-card-icon { background: #d8846c; }
.upcoming-card:nth-child(3n+2) .upcoming-card-icon { background: #c7a83c; }
.upcoming-card:nth-child(3n+3) .upcoming-card-icon { background: #a86cd1; }

.upcoming-card-icon img {
    width: 55%;
    height: 55%;
    filter: brightness(0) invert(1);
    object-fit: contain;
}

.upcoming-card-details {
    min-width: 0;
}

.upcoming-card-name {
    font-weight: 700;
    font-size: 17px;
    color: var(--ink-800);
    margin-bottom: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.upcoming-card-link {
    color: var(--ink-500);
    font-size: 14px;
}

.upcoming-card:hover .upcoming-card-link {
    color: var(--accent-orange);
    text-decoration: underline;
}

.upcoming-empty {
    grid-column: 1 / -1;
    color: #999;
    padding: 10px 0;
}

/* Lightbox Modal */
.lightbox {
    display: none;
    position: fixed;
    z-index: 9999;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.95);
    cursor: zoom-out;
    animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.lightbox-content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* Column, so the counter sits under the photo. As a row it became a
       sibling of the image and drifted off to one side. */
    display: flex;
    flex-direction: column;
    align-items: center;
    max-width: 92vw;
    max-height: 90vh;
}

/* The image is constrained directly, in viewport units. It used to be
   width/height:100% inside a wrapper that carried the only max-height, so a
   tall poster overflowed its own wrapper and ran off the bottom of the
   screen — with body scrolling locked, the cut-off part was unreachable. */
.lightbox-content img {
    max-width: 92vw;
    max-height: 90vh;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 8px;
}

.lightbox-close {
    position: absolute;
    top: 30px;
    right: 50px;
    color: white;
    font-size: 45px;
    font-weight: 300;
    cursor: pointer;
    z-index: 10000;
    transition: all 0.3s ease;
}

.lightbox-close:hover {
    color: var(--accent-orange);
    transform: scale(1.2) rotate(90deg);
}

/* Responsive */
@media (max-width: 1024px) {
    .events-container { padding: 20px; }
    .gallery-carousel { height: 420px; padding: 0 34px; }
    .upcoming-content { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
    .events-container { padding: 15px; }
    .events-title { font-size: 1.8rem; }
    .previous-events-section { padding: 22px 20px 20px; }
    .gallery-carousel { height: 320px; padding: 0 26px; }
    .carousel-nav { font-size: 26px; }
    .upcoming-content {
        grid-template-columns: 1fr;
        gap: 18px;
        padding: 24px 20px;
    }
    /* Keep the left padding clear of the notch or the label overlaps the
       point of the tab before it. */
    .event-tab { --notch: 9px; font-size: 11.5px; padding: 0 15px 0 21px; }
    .event-tab:first-child { padding-left: 15px; }
}

@media (max-width: 480px) {
    .gallery-carousel { height: 260px; padding: 0 20px; }
    .carousel-nav { font-size: 20px; padding: 4px; }
}

/* =========================================================================
   GALLERY + MEMBER PROFILES
   ========================================================================= */

/* ----- Filter pills ----- */
.gal-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 1.6rem;
}

.gal-pill {
  padding: 6px 15px;
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.05);
  color: var(--ink-600);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}

.gal-pill:hover {
  background: rgba(0, 0, 0, 0.1);
  color: var(--ink-800);
}

.gal-pill.active {
  background: var(--brand-gradient);
  color: #fff;
}

/* Event filters read as a different kind of thing than artist filters. */
.gal-pill--event {
  background: transparent;
  border: 1px solid var(--hairline);
}

/* ----- Artwork grid ----- */
.gal-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 18px;
}

.gal-item {
  margin: 0;
}

.gal-thumb {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  border-radius: var(--r-lg);
  overflow: hidden;
  cursor: zoom-in;
  background: var(--surface-tint-strong);
  line-height: 0;
}

.gal-thumb img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--r-lg);
  transition: transform 0.35s ease;
}

.gal-thumb:hover img {
  transform: scale(1.04);
}

.gal-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 9px 2px 0;
}

.gal-title {
  font-size: 0.95rem;
  line-height: 1.3;
  color: var(--ink-800);
}

.gal-credit {
  font-size: 0.85rem;
  color: var(--brand-ink);
  text-decoration: none;
}

.gal-credit:hover {
  text-decoration: underline;
}

/* A guest artist has no profile to link to, so it must not look clickable. */
.gal-credit--plain {
  color: var(--ink-500);
}

.gal-event {
  font-size: 0.78rem;
  color: var(--ink-400);
  text-decoration: none;
}

.gal-event:hover {
  color: var(--ink-600);
  text-decoration: underline;
}

.gal-empty {
  color: var(--ink-500);
  padding: 24px 0;
}

/* ----- Member profile ----- */
.mem-back {
  display: inline-block;
  margin-bottom: 1.2rem;
  color: var(--brand-ink);
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
}

.mem-back:hover {
  text-decoration: underline;
}

.mem-header {
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem;
  align-items: flex-start;
  margin-bottom: 2rem;
}

.mem-avatar {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--surface-tint-strong);
}

.mem-avatar--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
}

.mem-ident {
  flex: 1 1 260px;
  min-width: 0;
}

.mem-role {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brand-ink);
  margin: 0 0 0.8rem;
}

.mem-bio {
  color: var(--ink-600);
  line-height: 1.6;
  max-width: 60ch;
  margin: 0 0 0.9rem;
}

.mem-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin: 0;
  font-size: 0.9rem;
}

.mem-links a {
  color: var(--brand-ink);
  text-decoration: none;
}

.mem-links a:hover {
  text-decoration: underline;
}

.mem-discord {
  color: var(--ink-400);
}

.mem-h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--ink-800);
  margin: 0 0 1rem;
}

/* ----- Member cards become links ----- */
.member-card-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.member-card {
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.member-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-sm);
}

.member-count {
  font-size: 0.8rem;
  color: var(--brand-ink);
  font-weight: 600;
  margin: 0.4rem 0 0;
}

@media (max-width: 480px) {
  .gal-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
  }
  .mem-avatar {
    width: 96px;
    height: 96px;
  }
}

/* ----- Gallery grouped by artist ----- */
.gal-group {
  margin: 0 0 2.4rem;
}

.gal-group-name {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--ink-800);
  margin: 0 0 0.9rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--hairline);
}

.gal-group-name a {
  color: var(--brand-ink);
  text-decoration: none;
}

.gal-group-name a:hover {
  text-decoration: underline;
}

/* ----- Gallery: one folder per artist ----- */
.gal-folders {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 18px;
}

.gal-folder {
  margin: 0;
}

.gal-folder-link {
  display: block;
  color: inherit;
  text-decoration: none;
  border-radius: var(--r-lg);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.gal-folder-link:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-sm);
}

.gal-folder-cover {
  display: block;
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface-tint-strong);
  line-height: 0;
}

.gal-folder-cover img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* A second and third card peeking out behind the cover, so a folder reads as
   a stack of work rather than a single picture. */
.gal-folder-cover::after,
.gal-folder-cover::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 6px;
  background: rgba(0, 0, 0, 0.18);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

.gal-folder-cover::before {
  bottom: -4px;
  margin: 0 8px;
  background: rgba(0, 0, 0, 0.1);
}

.gal-folder-meta {
  display: block;
  margin: 12px 2px 0;
}

.gal-folder-name {
  display: block;
  font-size: 1rem;
  line-height: 1.3;
  color: var(--ink-800);
}

.gal-folder-count {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-500);
  margin-top: 2px;
}

.gal-group-profile {
  margin: 0 0 1rem;
  font-size: 0.9rem;
}

.gal-group-profile a {
  color: var(--brand-ink);
  text-decoration: none;
}

.gal-group-profile a:hover {
  text-decoration: underline;
}

/* ----- Events-list lightbox: prev/next ----- */
.lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 52px;
    height: 52px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    font-size: 30px;
    line-height: 1;
    cursor: pointer;
    z-index: 10000;
    transition: background 0.15s ease;
}

.lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.3);
}

.lightbox-nav.prev { left: 24px; }
.lightbox-nav.next { right: 24px; }

.lightbox-nav[hidden] { display: none; }

.lightbox-nav:focus-visible,
.lightbox-close:focus-visible {
    outline-color: #fff;
}

/* Was a <span>; now a real button, so the browser's button styling has to go. */
.lightbox-close {
    background: none;
    border: none;
    padding: 0;
    line-height: 1;
}

.lightbox-counter {
    margin: 12px 0 0;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.9rem;
    text-align: center;
}

/* The arrows need room on a phone, so they tuck in and shrink. */
@media (max-width: 640px) {
    .lightbox-nav {
        width: 42px;
        height: 42px;
        font-size: 24px;
    }
    .lightbox-nav.prev { left: 8px; }
    .lightbox-nav.next { right: 8px; }
    .lightbox-content img { max-width: 78vw; }
}

/* =========================================================================
   UPCOMING EVENTS
   Was a bunny logo, an event code and "Learn More" — no date anywhere, which
   is the one fact an upcoming event has to communicate. Now the date leads.
   ========================================================================= */
.uc-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.uc-card {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 16px 20px;
    background: #fff;
    border: 1px solid var(--hairline);
    border-radius: var(--r-lg);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.uc-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}

/* ----- Date chip ----- */
.uc-date {
    flex: 0 0 auto;
    width: 74px;
    text-align: center;
    padding: 10px 0 12px;
    border-radius: var(--r-md);
    background: var(--brand-gradient);
    color: #fff;
    line-height: 1.1;
}

.uc-month {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.9;
}

.uc-day {
    display: block;
    font-size: 1.7rem;
    font-weight: 800;
    margin: 2px 0;
}

.uc-year {
    display: block;
    font-size: 0.72rem;
    opacity: 0.85;
}

/* ----- Details ----- */
.uc-body {
    flex: 1 1 auto;
    min-width: 0;
}

.uc-name {
    display: block;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ink-800);
    text-decoration: none;
    line-height: 1.3;
}

.uc-name:hover {
    color: var(--brand-deep);
    text-decoration: underline;
}

/* Dot separators come from CSS, so an absent time or venue leaves no stray
   punctuation behind. */
.uc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0 8px;
    margin: 4px 0 0;
    font-size: 0.85rem;
    color: var(--ink-500);
}

/* The dot belongs to the item before the gap, not after it — as a ::before it
   wrapped onto the next line and sat there as stray punctuation. */
.uc-meta span:not(:last-child)::after {
    content: "·";
    margin-left: 8px;
    color: var(--ink-300);
}

.uc-desc {
    margin: 6px 0 0;
    font-size: 0.9rem;
    color: var(--ink-600);
    line-height: 1.45;
    max-width: 62ch;
}

/* ----- Action ----- */
.uc-action {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    text-align: center;
}

.uc-signup {
    padding: 10px 22px;
    font-size: 0.95rem;
    white-space: nowrap;
}

.uc-details {
    font-size: 0.82rem;
    color: var(--ink-500);
    text-decoration: none;
}

.uc-details:hover {
    color: var(--brand-ink);
    text-decoration: underline;
}

.upcoming-empty a {
    color: var(--brand-ink);
}

/* On a phone the row becomes a stack, with the date chip going wide so it
   still reads as a heading rather than a lost square. */
@media (max-width: 640px) {
    .uc-card {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    .uc-date {
        width: auto;
        display: flex;
        align-items: baseline;
        justify-content: center;
        gap: 8px;
        padding: 8px 12px;
    }
    .uc-day { font-size: 1.2rem; margin: 0; }
    .uc-action { flex-direction: row; align-items: center; justify-content: space-between; }
}

/* The nothing-scheduled block. Deliberately forward-looking: it leads with
   the next date and the Discord button, and carries the last gathering as
   evidence the community is still meeting. */
.upcoming-none {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 14px 20px;
    margin: 0 0 18px;
    padding: 18px 22px;
    background: rgba(255, 255, 255, 0.92);
    border-radius: var(--r-lg);
}

.upcoming-none-title {
    display: block;
    font-size: 1.02rem;
    color: var(--ink-800);
}

.upcoming-none-text {
    margin: 4px 0 0;
    font-size: 0.92rem;
    color: var(--ink-600);
    max-width: 62ch;
}

.upcoming-section {
    margin-bottom: 22px;
}

/* =========================================================================
   EVENTS ON A PHONE
   The tab strip packs ~1500px of tabs into a 300px window, so every event
   past the second was reachable only by scrubbing sideways. The picker below
   carries the same list in one tap; only one of the two is ever shown.
   ========================================================================= */
.event-picker {
    display: none;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    padding: 10px 14px;
    background: var(--bar-dark);
    border-radius: var(--r-md);
}

.event-picker-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    flex: 0 0 auto;
}

.event-picker select {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px;
    border: none;
    border-radius: var(--r-sm);
    background: var(--cream);
    color: var(--card-dark);
    font-size: 0.92rem;
    font-weight: 700;
}

@media (max-width: 768px) {
    .event-picker { display: flex; }

    /* The strip and its arrows are replaced by the picker. */
    .event-tabs-wrapper { display: none; }

    /* Reclaim the space the tab strip and its gutters were using: the photo
       goes nearly full width and taller, instead of a 260px square adrift in
       a dark frame. */
    .gallery-carousel { height: 400px; padding: 0 10px; }
    .carousel-nav { font-size: 30px; }
    .carousel-nav.prev { left: 0; }
    .carousel-nav.next { right: 0; }
}

@media (max-width: 480px) {
    .gallery-carousel { height: 340px; padding: 0 8px; }
    .event-picker { padding: 8px 12px; }
    .event-picker-label { display: none; }
}

/* =========================================================================
   HOME PAGE
   Was a heading plus one generic sentence. Now it has to answer who, where
   and how to join before the reader scrolls.
   ========================================================================= */
.home-lede {
  font-size: 1.12rem;
  line-height: 1.6;
  color: var(--ink-600);
  max-width: 60ch;
  margin: 0 0 1.4rem;
}


.home-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 1.8rem;
}

/* ----- Three ways in ----- */
.home-cards {
  list-style: none;
  margin: 1.6rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
}

.home-card a {
  display: block;
  height: 100%;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  color: inherit;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.home-card a:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-sm);
}

.home-card-image {
  display: block;
  background: var(--surface-tint-strong);
  line-height: 0;
}

.home-card-image img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.home-card-text {
  display: block;
  padding: 14px 16px 16px;
}

.home-card-text strong {
  display: block;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-400);
  margin-bottom: 4px;
}

.home-card-text span {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-800);
  line-height: 1.3;
}

.home-card-text small {
  display: block;
  margin-top: 3px;
  font-size: 0.83rem;
  color: var(--ink-500);
}

/* A second line under a menu label, for entries whose name does not say what
   they contain. "BB Notes" is the community's own term and worth keeping, but
   it needed to say that it is writing. */
.nav-link--with-note {
  line-height: 1.15;
}

.nav-note {
  display: block;
  margin-top: 2px;
  font-family: var(--font);
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: 0;
  opacity: 0.72;
}

/* The active link is a white bar with dark text, so the note has to darken
   with it rather than staying pale. */
.nav-link.active .nav-note {
  opacity: 0.62;
}

/* The Project Bunni poster. A 648px square sitting flush left in a ~1150px
   box left half the page blank, which read as a broken layout. Centred and
   capped, the space around it is symmetric and deliberate. */
.pb-poster {
  margin: 0.5rem auto 0;
  max-width: 520px;
}

.pb-poster img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-md);
}

/* ----- Event summary: what you are looking at, in words -----
   The tabs and the carousel described an event only through pictures, so its
   date, venue and story were invisible to a reader and to search. */
.event-summary[hidden] {
    display: none;
}

.event-summary {
    margin: 0 0 18px;
    padding: 16px 20px;
    background: rgba(255, 255, 255, 0.07);
    border-radius: var(--r-lg);
}

.event-summary-name {
    margin: 0;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.25;
}

.event-summary-name a {
    color: #fff;
    text-decoration: none;
}

.event-summary-name a:hover {
    text-decoration: underline;
}

.event-summary-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0 8px;
    margin: 6px 0 0;
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.62);
}

.event-summary-meta span:not(:last-child)::after {
    content: "·";
    margin-left: 8px;
    color: rgba(255, 255, 255, 0.35);
}

.event-summary-text {
    margin: 10px 0 0;
    max-width: 70ch;
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.85);
}

.event-summary-more {
    display: inline-block;
    margin-top: 10px;
    font-size: 0.88rem;
    font-weight: 600;
    color: #fff;
    text-decoration: none;
    opacity: 0.85;
}

.event-summary-more:hover {
    opacity: 1;
    text-decoration: underline;
}

@media (max-width: 640px) {
    .event-summary { padding: 14px 16px; }
    .event-summary-name { font-size: 1.1rem; }
}

/* =========================================================================
   EVENT DETAIL — one surface
   The page was a hero with text over a photo, a five-card fact strip, an
   actions bar and three more panels, each translucent over the site's
   background photograph. Every block of text sat on a different busy image,
   which is what made it hard to read. Now: one solid card, the title on a
   plain background, and the facts as a single line.
   ========================================================================= */
.ev-card {
  background: #fff;
  border-radius: var(--r-2xl);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

/* The photo is a picture, not a backdrop for text. */
.ev-cover {
  display: block;
  width: 100%;
  max-height: 380px;
  object-fit: cover;
}

.ev-body {
  padding: 26px clamp(20px, 3vw, 34px) 4px;
  color: var(--ink-700);
}

.ev-title {
  margin: 0;
  font-size: clamp(1.6rem, 3.2vw, 2.2rem);
  font-weight: 800;
  line-height: 1.15;
  color: var(--ink-900);
}

/* Facts on one line. Separators come from CSS so a missing time or venue
   leaves nothing dangling. */
.ev-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0 8px;
  margin: 10px 0 0;
  font-size: 0.9rem;
  color: var(--ink-500);
}

/* The dot belongs to the item that follows it, not the one before — so when
   the line wraps on a phone the separator travels with the next word instead
   of being left stranded at the end of the previous line. */
.ev-meta span + span::before {
  content: "·";
  margin-right: 8px;
  color: var(--ink-200);
}

.ev-lede {
  margin: 14px 0 0;
  font-size: 1.05rem;
  line-height: 1.55;
  color: var(--ink-600);
  max-width: 62ch;
}

.ev-text {
  margin: 14px 0 0;
  line-height: 1.7;
  max-width: 68ch;
}

.ev-text p { margin: 0 0 1rem; }

.ev-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  margin: 20px 0 22px;
}

.ev-link {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--brand-ink);
  text-decoration: none;
}

.ev-link:hover { text-decoration: underline; }

/* Photos sit flush inside the same card rather than in their own panel. */
.ev-grid {
  list-style: none;
  margin: 0;
  padding: 0 clamp(20px, 3vw, 34px) clamp(20px, 3vw, 34px);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}

/* Other events: a plain row of links, not three image cards competing with
   the event you are actually reading about. */
.ev-more {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 0;
}

.ev-more a {
  flex: 1 1 200px;
  padding: 12px 16px;
  background: rgba(255, 255, 255, 0.92);
  border-radius: var(--r-md);
  text-decoration: none;
  color: var(--ink-800);
  transition: background 0.15s ease;
}

.ev-more a:hover { background: #fff; }

.ev-more strong {
  display: block;
  font-size: 0.95rem;
  line-height: 1.3;
}

.ev-more small {
  display: block;
  margin-top: 2px;
  font-size: 0.82rem;
  color: var(--ink-500);
}
