/* HouseKey SD styles
   Minimal, editorial, black and white. Typography-led.
   Heading font: Druk Wide Bold (falls back until a licensed webfont file is added).
   Body font: Radio Canada, loaded free from Google Fonts (see the
   <link> tags in each page's <head>), falls back to Helvetica Neue /
   system sans-serif if the CDN request fails. */

:root {
  --hk-black: #000000;
  --hk-white: #ffffff;
  --hk-grey-1: #a3a3a3;
  --hk-grey-2: #6b6b6b;
  --hk-border: rgba(255, 255, 255, 0.18);
  --hk-heading-font: "Druk Wide Bold", "Helvetica Neue", Arial, sans-serif;
  --hk-body-font: "Radio Canada", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --hk-max-width: 1200px;
  --hk-gutter: 24px;
  --hk-motion-fast: 200ms;
  --hk-motion-slow: 600ms;
}

* {
  box-sizing: border-box;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

html {
  background: var(--hk-black);
}

body {
  margin: 0;
  background: var(--hk-black);
  color: var(--hk-white);
  font-family: var(--hk-body-font);
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  max-width: 100%;
  display: block;
}

/* Focus states: always visible, never suppressed */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--hk-white);
  outline-offset: 3px;
}

/* ---------- Header / nav ---------- */

.site-header {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hk-gutter);
  padding: 20px var(--hk-gutter);
  max-width: var(--hk-max-width);
  margin: 0 auto;
}

.brand-mark img {
  height: 28px;
  width: auto;
}

.main-nav {
  display: flex;
  gap: 28px;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.main-nav a {
  padding: 4px 0;
  border-bottom: 1px solid transparent;
  opacity: 0.55;
  transition: opacity var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.main-nav a:hover,
.main-nav a:focus-visible {
  opacity: 1;
  border-color: var(--hk-white);
}

.main-nav a[aria-current="page"] {
  opacity: 1;
  border-color: var(--hk-white);
}

.instagram-link {
  display: inline-flex;
  color: var(--hk-grey-1);
  transition: color var(--hk-motion-fast) ease;
}

.instagram-link svg {
  width: 20px;
  height: 20px;
}

.instagram-link:hover,
.instagram-link:focus-visible {
  color: var(--hk-white);
}

@media (max-width: 640px) {
  .site-header {
    flex-wrap: wrap;
    gap: 14px;
  }

  .main-nav {
    order: 3;
    width: 100%;
    justify-content: space-between;
    gap: 10px;
    font-size: 11px;
  }
}

/* ---------- Hero ----------
   Full-screen black hero. Three layers of motion, all driven from
   assets/js/hero.js:
   1. A one-shot "keyhole" reveal on load: a flyer image masked into the
      brand key silhouette, briefly visible then fading back to black.
   2. Headline split into three typographic layers (.hero-line), each
      drifting a different amount on scroll, with a slower pointer-driven
      horizontal drift on .hero-line-inner (fine-pointer devices only).
   3. The key/brand mark rotating subtly as the hero scrolls past, as if
      turning in a lock.
   Every layer above is inert under prefers-reduced-motion (see the
   reduced-motion block near the end of this file) and pointer drift is
   skipped entirely on touch devices — hero.js also treats narrow
   viewports as "mobile" and halves the scroll-drift distances. Nothing
   here intercepts scroll or blocks the header nav: transforms are read
   passively from scroll position, the hero stays in normal document
   flow, and .hero-keyhole is pointer-events: none. */

.hero {
  min-height: 88vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 60px var(--hk-gutter);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.hero-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero-logo-wrap {
  margin-bottom: 40px;
}

.hero-logo {
  height: 44px;
  width: auto;
  margin: 0 auto;
  opacity: 0.92;
  will-change: transform;
}

.hero-headline {
  font-family: var(--hk-heading-font);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(2rem, 6vw, 4.5rem);
  line-height: 1.05;
  letter-spacing: 0.01em;
  margin: 0;
  max-width: 16ch;
}

/* Typographic scroll layers: each line drifts at a slightly different
   speed via translateY set by JS from scroll position. The inner span
   carries a separate, pointer-driven translateX so the two motions
   never fight over the same transform. Reduced-motion users get fully
   static text (see prefers-reduced-motion block below). */
.hero-line {
  display: block;
  will-change: transform;
  transition: transform 60ms linear;
}

.hero-line-inner {
  display: inline-block;
  will-change: transform;
  transition: transform 120ms linear;
}

/* ---------- Full-screen intro loader (homepage only) ----------
   A genuine full-screen "unlock" moment, ahead of the rest of the site
   frame (header included): a flyer masked into the brand key silhouette,
   scaling and turning into view against solid black, then fading away
   to reveal the page underneath, which has already laid out behind it.
   hero.js adds .is-revealed shortly after load, then .is-done once the
   reveal has held long enough to read, at which point this element is
   removed from the DOM entirely. Fully skipped under reduced motion:
   hero.js removes it immediately, no animation, no delay. */
.intro-loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hk-black);
  transition: opacity 700ms ease;
}

.intro-loader.is-done {
  opacity: 0;
  pointer-events: none;
}

body.intro-loading {
  overflow: hidden;
}

.intro-loader-image {
  width: min(60vw, 60vh, 460px);
  height: min(60vw, 60vh, 460px);
  object-fit: cover;
  -webkit-mask-image: url("../img/housekey-logo-white-san-diego.png");
  mask-image: url("../img/housekey-logo-white-san-diego.png");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  filter: saturate(0.25) brightness(0.45);
  opacity: 0;
  transform: scale(0.55) rotate(-16deg);
  transition: opacity 900ms ease, transform 1500ms cubic-bezier(0.16, 1, 0.3, 1), filter 1500ms ease;
}

.intro-loader-image.is-revealed {
  opacity: 1;
  filter: saturate(1) brightness(1);
  transform: scale(1) rotate(0deg);
}

/* ---------- Reveal-on-scroll (smooth transition out of the hero) ----------
   Applied via a [data-reveal] attribute (currently just the weekend
   section). hero.js flips on .is-visible via IntersectionObserver, with
   a same-tick fallback to fully visible if IntersectionObserver isn't
   available, so content is never stuck hidden. */

[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 700ms ease, transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

.section-label span {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
}

/* ---------- Inner page header (About, Contact, Interviews, Calendar) ---------- */

.page-main {
  max-width: var(--hk-max-width);
  margin: 0 auto;
  padding: 60px var(--hk-gutter) 100px;
}

.page-header {
  margin-bottom: 56px;
  max-width: 62ch;
}

/* Calendar page only: heading + intro on the left, "Submit an Event"
   pill on the right. The inner wrapper keeps the same 62ch reading
   width as every other .page-header; only the row itself goes full
   width so the pill can sit at the far right. */
.page-header-with-action {
  max-width: none;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  flex-wrap: wrap;
}

.page-header-with-action > div {
  max-width: 62ch;
}

.pill-cta {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  padding: 10px 20px;
  border: 1px solid var(--hk-border);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hk-white);
  transition: background var(--hk-motion-fast) ease, color var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.pill-cta:hover,
.pill-cta:focus-visible {
  background: var(--hk-white);
  color: var(--hk-black);
  border-color: var(--hk-white);
}

/* Calendar page only: pull the weekend content up closer to the title
   instead of the usual generous .page-header gap — the "Next Week"
   link + date cards read better sitting tight under "Upcoming". */
#real-calendar {
  margin-top: -28px;
}

.page-header .section-label span {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
}

.page-header h1 {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: clamp(1.8rem, 5vw, 3rem);
  line-height: 1.1;
  margin: 10px 0 18px;
}

.page-header p {
  color: var(--hk-grey-1);
  font-size: 15px;
  line-height: 1.6;
  margin: 0;
}

/* ---------- About page body copy ---------- */

.about-body p {
  max-width: 60ch;
  font-size: 16px;
  line-height: 1.7;
  margin: 0 0 22px;
  color: #e6e6e6;
}

.about-body a {
  border-bottom: 1px solid var(--hk-white);
}

/* Opening statement, given real typographic weight instead of reading
   as just the first paragraph in a block. */
.about-lead {
  font-family: var(--hk-heading-font);
  text-transform: none;
  font-size: clamp(20px, 2.6vw, 28px) !important;
  line-height: 1.45 !important;
  color: var(--hk-white) !important;
  max-width: 22ch !important;
  margin-bottom: 34px !important;
}

/* Shared bordered "card link" treatment - used for the About page's
   Instagram follow card and the Contact page's "submitting an event?"
   redirect card. */
.about-ig-cta,
.contact-event-cta {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  margin-top: 12px;
  padding: 18px 24px;
  border: 1px solid var(--hk-border);
  border-radius: 8px;
  transition: border-color var(--hk-motion-fast) ease, background var(--hk-motion-fast) ease;
}

.about-ig-cta svg,
.contact-event-cta svg {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  color: var(--hk-white);
}

.about-ig-cta span,
.contact-event-cta span {
  display: block;
  font-size: 14px;
  color: var(--hk-grey-1);
}

.about-ig-cta strong,
.contact-event-cta strong {
  display: block;
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--hk-white);
  margin-bottom: 4px;
}

.about-ig-cta:hover,
.about-ig-cta:focus-visible,
.contact-event-cta:hover,
.contact-event-cta:focus-visible {
  border-color: var(--hk-white);
  background: rgba(255, 255, 255, 0.04);
}

.contact-event-cta {
  margin-top: 0;
  margin-bottom: 32px;
}

/* ---------- Interview article body ---------- */

.interview-body p {
  max-width: 66ch;
}

/* The dek: given real typographic contrast (heading font, larger,
   a divider rule below) so it reads as a distinct standfirst rather
   than blending into the Q&A body that follows it. */
.interview-intro {
  font-family: var(--hk-heading-font);
  text-transform: none;
  font-size: clamp(18px, 2.1vw, 22px) !important;
  line-height: 1.55 !important;
  color: var(--hk-white) !important;
  max-width: 58ch;
  padding-bottom: 28px;
  margin-bottom: 32px !important;
  border-bottom: 1px solid var(--hk-border);
}

.qa-question strong {
  display: block;
  font-family: var(--hk-heading-font);
  text-transform: none;
  font-size: 15px;
  color: var(--hk-white);
  margin-top: 34px;
  letter-spacing: 0.01em;
}

/* Sits inline in the middle of the Q&A, not glued to the end, and not
   floated off to the side either (that read as disconnected from the
   piece). Integrated directly into the column: full body measure, top
   and bottom rules, larger statement-style type, so it reads as a beat
   in the article rather than a sidebar. */
.pull-quote {
  border-top: 1px solid var(--hk-border);
  border-bottom: 1px solid var(--hk-border);
  padding: 26px 0;
  margin: 40px 0;
  font-family: var(--hk-heading-font);
  text-transform: none;
  font-size: clamp(20px, 2.4vw, 26px);
  line-height: 1.4;
  color: var(--hk-white);
  max-width: 66ch;
}

.embed-wrap {
  margin: 30px 0;
  max-width: 480px;
}

/* Links block: the artist's name (not the word "Links") heads the list,
   in a different font/color from the body so it reads as a byline-style
   sign-off, followed by their links with a platform icon where one
   exists (Instagram) and a generic outbound-link icon otherwise. */
.artist-links-name {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--hk-grey-1);
  margin: 46px 0 14px;
}

.artist-links {
  list-style: none;
  padding: 0;
  margin: 0;
}

.artist-links li {
  margin-bottom: 10px;
}

.artist-links a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  border-bottom: 1px solid var(--hk-border);
  padding-bottom: 1px;
}

.artist-links a svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--hk-grey-1);
  transition: color var(--hk-motion-fast) ease;
}

.artist-links a:hover,
.artist-links a:focus-visible {
  border-color: var(--hk-white);
}

.artist-links a:hover svg,
.artist-links a:focus-visible svg {
  color: var(--hk-white);
}

/* ---------- Forms (Contact / Submit an Event) ---------- */

/* Contact page: intro (heading, blurb, email) on the left, form on the
   right, on desktop. Single column, form second, on mobile. */
.contact-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.contact-intro .page-header {
  margin-bottom: 24px;
}

@media (min-width: 860px) {
  .contact-layout {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 64px;
    align-items: start;
  }
}

.hk-form {
  max-width: 560px;
}

/* Give the form its own visible panel instead of floating directly on
   the black page background, so it reads as a distinct, fillable
   object rather than blending into the page. Glassmorphism treatment:
   a soft gradient tint, blurred/saturated backdrop, a hairline border
   and a top inner highlight, so the panel reads as frosted glass sitting
   above the black page rather than a flat tinted box. Used on both the
   Contact form and the Submit an Event form. */
.contact-form-panel {
  max-width: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 18px;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02));
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  padding: 32px;
}

@media (max-width: 640px) {
  .contact-form-panel {
    padding: 24px 20px;
  }
}

.form-row {
  margin-bottom: 26px;
}

.form-row label {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
  margin-bottom: 8px;
}

.form-row .hint {
  display: block;
  font-size: 12px;
  color: var(--hk-grey-2);
  margin-top: 6px;
}

.hk-form input,
.hk-form select,
.hk-form textarea {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--hk-border);
  color: var(--hk-white);
  font-family: var(--hk-body-font);
  font-size: 15px;
  padding: 10px 2px;
  transition: border-color var(--hk-motion-fast) ease;
}

.hk-form select {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--hk-border);
  border-radius: 6px;
  padding: 12px 40px 12px 14px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  cursor: pointer;
  transition: border-color var(--hk-motion-fast) ease, background-color var(--hk-motion-fast) ease;
}

.hk-form select:hover {
  border-color: var(--hk-grey-1);
}

.hk-form select:focus {
  border-color: var(--hk-white);
}

.hk-form select option {
  background: var(--hk-black);
  color: var(--hk-white);
}

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

.hk-form input:focus,
.hk-form select:focus,
.hk-form textarea:focus {
  outline: none;
  border-color: var(--hk-white);
}

/* Only flag a field red after the user has actually interacted with it
   (browser support for :user-invalid varies, so this degrades safely
   to relying on the native validation bubble triggered on submit). */
.hk-form input:user-invalid,
.hk-form textarea:user-invalid {
  border-color: #b33a3a;
}

.event-fields {
  border-top: 1px solid var(--hk-border);
  padding-top: 22px;
  margin-top: 8px;
  display: none;
}

.event-fields.is-visible {
  display: block;
}

.event-fields .section-label {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
  margin-bottom: 20px;
}

/* Contact page: the "is this actually one event?" branch question shown
   when "Paid Promotion" is selected, and the redirect card shown once
   they confirm it's a one-off event rather than a real promotion ask. */
.promo-branch {
  display: none;
  border-top: 1px solid var(--hk-border);
  padding-top: 22px;
  margin: 8px 0 26px;
}

.promo-branch.is-visible {
  display: block;
}

.promo-branch-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.promo-branch-btn {
  padding: 10px 16px;
  border: 1px solid var(--hk-border);
  border-radius: 999px;
  background: transparent;
  color: var(--hk-white);
  font-family: var(--hk-body-font);
  font-size: 13px;
  cursor: pointer;
  transition: border-color var(--hk-motion-fast) ease, background var(--hk-motion-fast) ease;
}

.promo-branch-btn:hover,
.promo-branch-btn:focus-visible {
  border-color: var(--hk-white);
}

.promo-branch-btn.is-active {
  background: var(--hk-white);
  color: var(--hk-black);
  border-color: var(--hk-white);
}

.promo-redirect {
  display: none;
  border: 1px solid var(--hk-border);
  border-radius: 6px;
  padding: 22px 24px;
  margin-bottom: 26px;
  background: rgba(255, 255, 255, 0.03);
}

.promo-redirect.is-visible {
  display: block;
}

.promo-redirect p {
  margin: 0 0 16px;
  font-size: 14px;
  color: var(--hk-grey-1);
}

#restOfForm.is-hidden {
  display: none;
}

.hk-submit {
  background: var(--hk-white);
  color: var(--hk-black);
  border: none;
  padding: 13px 30px;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity var(--hk-motion-fast) ease;
}

.hk-submit:hover,
.hk-submit:focus-visible {
  opacity: 0.85;
}

.form-status {
  margin-top: 18px;
  font-size: 13px;
  color: var(--hk-grey-1);
}

.form-status[data-state="success"] {
  color: var(--hk-white);
}

.form-status[data-state="error"] {
  color: #d97a7a;
}

.contact-channels {
  list-style: none;
  margin: 0 0 48px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.contact-channels a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--hk-grey-1);
  transition: color var(--hk-motion-fast) ease;
}

.contact-channels svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--hk-grey-1);
  transition: color var(--hk-motion-fast) ease;
}

.contact-channels a:hover,
.contact-channels a:focus-visible {
  color: var(--hk-white);
}

.contact-channels a:hover svg,
.contact-channels a:focus-visible svg {
  color: var(--hk-white);
}

.submit-event-note {
  margin: 0 0 20px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--hk-grey-1);
  max-width: 46ch;
}

.submit-event-note a {
  color: var(--hk-white);
  border-bottom: 1px solid var(--hk-border);
}

/* Honeypot field for the Submit an Event form - positioned off-screen
   rather than display:none, since some bots skip hidden fields but
   still fill in anything technically visible in the DOM. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Empty / error states (Calendar, Interviews) ---------- */

.empty-state {
  border: 1px solid var(--hk-border);
  padding: 60px 30px;
  text-align: center;
  color: var(--hk-grey-1);
  font-size: 14px;
  max-width: 60ch;
}

.submit-event-line {
  margin-top: 40px;
}

.empty-state strong {
  display: block;
  color: var(--hk-white);
  font-size: 15px;
  margin-bottom: 10px;
}

.error-state {
  border: 1px solid #b33a3a;
  padding: 40px 30px;
  color: #d97a7a;
  font-size: 14px;
  max-width: 60ch;
}

/* ---------- Interviews: Recent Posts carousel ---------- */

.recent-posts {
  margin-bottom: 64px;
}

.recent-posts-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 20px;
}

.recent-posts-see-all {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
  border-bottom: 1px solid var(--hk-border);
  padding-bottom: 2px;
  transition: color var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.recent-posts-see-all:hover,
.recent-posts-see-all:focus-visible {
  color: var(--hk-white);
  border-color: var(--hk-white);
}

.recent-posts-viewport {
  overflow: hidden;
}

.recent-posts-track {
  display: flex;
  gap: 24px;
  transition: transform 900ms cubic-bezier(0.65, 0, 0.35, 1);
}

.recent-post-tile {
  flex: 0 0 calc((100% - 48px) / 3);
  display: block;
}

.recent-post-tile .interview-tile-image {
  border: 1px solid var(--hk-border);
  transition: border-color var(--hk-motion-fast) ease;
}

.recent-post-tile:hover .interview-tile-image,
.recent-post-tile:focus-visible .interview-tile-image {
  border-color: var(--hk-white);
}

.recent-post-title {
  margin: 12px 0 0;
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1.3;
}

@media (max-width: 860px) {
  .recent-post-tile {
    flex-basis: calc((100% - 24px) / 2);
  }
}

@media (max-width: 560px) {
  .recent-posts-track {
    gap: 16px;
  }

  .recent-post-tile {
    flex-basis: 100%;
  }
}

/* ---------- Interviews grid ---------- */

.interview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 30px;
}

.interview-tile {
  border: 1px solid var(--hk-border);
  display: block;
  transition: border-color var(--hk-motion-fast) ease;
}

.interview-tile:hover,
.interview-tile:focus-visible {
  border-color: var(--hk-white);
}

.interview-tile-image {
  aspect-ratio: 4 / 5;
  background: #0a0a0a;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--hk-grey-2);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.interview-tile-body {
  padding: 16px;
}

.interview-tile-title {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 15px;
  margin: 0 0 8px;
}

.interview-tile-date {
  font-size: 12px;
  color: var(--hk-grey-2);
}

/* ---------- Calendar: day-grouped list ----------
   Superseded as the live weekend pattern by .weekend-accordion /
   .weekend-filmstrip further down (Nicole wanted mobile collapsible
   days + a desktop horizontal day-selector instead of a flat vertical
   stack). Left in place as reusable day-group/card building blocks,
   and in case scope later expands from "just the weekend" to a full
   running list, which could reuse this flatter pattern. */

.calendar-list {
  display: flex;
  flex-direction: column;
}

.day-group {
  border-top: 1px solid var(--hk-border);
  padding: 28px 0;
}

.day-group:last-child {
  border-bottom: 1px solid var(--hk-border);
}

.day-header {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 18px;
}

.day-header-dow {
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
}

.day-header-date {
  font-family: var(--hk-heading-font);
  font-size: 44px;
  line-height: 1;
}

.day-header-month {
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hk-grey-2);
}

.day-events {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 6px;
  margin: 0 calc(var(--hk-gutter) * -1);
  padding-left: var(--hk-gutter);
  padding-right: var(--hk-gutter);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.day-event-card {
  flex: 0 0 auto;
  width: 62vw;
  max-width: 260px;
  scroll-snap-align: start;
  display: block;
  border: 1px solid var(--hk-border);
  transition: border-color var(--hk-motion-fast) ease, opacity var(--hk-motion-fast) ease;
  position: relative;
}

.day-event-card:hover,
.day-event-card:focus-visible {
  border-color: var(--hk-white);
}

.day-event-image-wrap {
  position: relative;
  aspect-ratio: 4 / 5;
  background: #0a0a0a;
  overflow: hidden;
}

.day-event-image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* A submitted flyer IS the card - no name/venue text laid over it, and
   no darkening gradient needed since nothing needs to stay legible on
   top of it. The whole card already links out to the ticket URL. */

/* No flyer submitted: fall back to a plain white card with black text
   instead of pretending there's an image to overlay text onto. */
.day-event-card.no-image .day-event-image-wrap {
  background: var(--hk-white);
  display: flex;
  align-items: center;
  justify-content: center;
}

.day-event-pick {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hk-black);
  background: var(--hk-white);
  padding: 4px 8px;
}

/* On a no-image (white) card, an all-white Pick badge would disappear,
   so it inverts to black-on-white there instead. */
.day-event-card.no-image .day-event-pick {
  color: var(--hk-white);
  background: var(--hk-black);
}

.day-event-text {
  padding: 20px 16px;
  text-align: center;
}

.day-event-name {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 15px;
  line-height: 1.15;
  margin: 0 0 4px;
  color: var(--hk-black);
}

.day-event-venue {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.6);
}

.day-event-time {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 4px;
}

.weekend-nav-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
  gap: 10px;
}

.calendar-month-nav {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
}

.calendar-month-label {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 14px;
  letter-spacing: 0.08em;
  color: var(--hk-white);
  min-width: 130px;
  text-align: center;
}

.week-nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--hk-border);
  border-radius: 999px;
  color: var(--hk-white);
  background: transparent;
  transition: background var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.week-nav-btn svg {
  width: 16px;
  height: 16px;
}

.week-nav-btn:hover,
.week-nav-btn:focus-visible {
  background: var(--hk-white);
  color: var(--hk-black);
  border-color: var(--hk-white);
}

.week-nav-btn:disabled {
  opacity: 0.3;
  pointer-events: none;
}

/* "Back to this weekend" - sits next to the prev/next arrows, only
   shown once paging has moved away from the nearest upcoming dates. */
.week-nav-text-btn {
  display: inline-flex;
  align-items: center;
  padding: 0 16px;
  height: 38px;
  border: 1px solid var(--hk-border);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hk-white);
  background: transparent;
  transition: background var(--hk-motion-fast) ease, color var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.week-nav-text-btn:hover,
.week-nav-text-btn:focus-visible {
  background: var(--hk-white);
  color: var(--hk-black);
  border-color: var(--hk-white);
}

@media (min-width: 860px) {
  .day-header-date {
    font-size: 56px;
  }

  .day-events {
    overflow-x: visible;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
  }

  .day-event-card {
    width: 220px;
  }
}

/* ---------- Weekend accordion (mobile, < 860px) ----------
   Each day is independently collapsible (not a strict one-open
   accordion) so more than one day can be expanded at once. The
   nearest day with events auto-opens on load via JS; the rest start
   collapsed. Uses the grid-template-rows: 0fr -> 1fr technique for a
   smooth height transition without JS measuring scrollHeight. */

.weekend-accordion {
  border-bottom: 1px solid var(--hk-border);
}

.day-accordion-item {
  border-top: 1px solid var(--hk-border);
}

.day-accordion-heading {
  margin: 0;
}

.day-accordion-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  background: none;
  border: 0;
  padding: 18px 0;
  color: var(--hk-white);
  font-family: inherit;
  cursor: pointer;
  text-align: left;
}

.day-accordion-header:focus-visible {
  outline: 1px solid var(--hk-white);
  outline-offset: 4px;
}

.day-accordion-label {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex: 1;
}

.day-accordion-dow {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
  flex-shrink: 0;
  /* No fixed width: "Saturday" is noticeably longer than "Friday" /
     "Sunday", and a fixed column was crowding it right up against the
     date number while the shorter labels had extra breathing room. A
     consistent gap reads more evenly than forcing equal-width columns. */
}

.day-accordion-date {
  font-family: var(--hk-heading-font);
  font-size: 28px;
  line-height: 1;
  margin-left: -2px;
}

.day-accordion-month {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hk-grey-2);
  margin-left: 4px;
}

.day-accordion-count {
  font-size: 12px;
  color: var(--hk-grey-2);
  flex-shrink: 0;
}

.day-accordion-chevron {
  width: 9px;
  height: 9px;
  border-right: 1px solid var(--hk-white);
  border-bottom: 1px solid var(--hk-white);
  transform: rotate(-45deg);
  transition: transform var(--hk-motion-fast) ease;
  flex-shrink: 0;
  margin-right: 2px;
}

.day-accordion-header[aria-expanded="true"] .day-accordion-chevron {
  transform: rotate(45deg);
}

.day-accordion-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--hk-motion-slow) cubic-bezier(0.4, 0, 0.2, 1);
}

.day-accordion-panel.is-open {
  grid-template-rows: 1fr;
}

.day-accordion-panel-inner {
  overflow: hidden;
  min-height: 0;
}

.day-accordion-panel .day-events {
  padding-bottom: 22px;
}

@media (prefers-reduced-motion: reduce) {
  .day-accordion-panel {
    transition: none;
  }
}

@media (min-width: 860px) {
  .weekend-accordion {
    display: none;
  }
}

/* ---------- Weekend date cards + night carousel (desktop, >= 860px) ----------
   Nicole's call after seeing the continuous-timeline version: some
   nights run ~20 events deep, which breaks a per-event strip outright.
   The top row is always exactly 3 date cards (Fri/Sat/Sun), so it
   scales to any event count per night. Hovering (or focusing/clicking,
   for keyboard and touch users) a date card swaps which night's
   carousel shows in the reveal area below — content swaps in place
   rather than the area hiding/showing, so there's no flicker moving
   from the cards down into the carousel. Each night's carousel reuses
   the homepage "This Weekend" carousel's exact one-flyer-at-a-time
   slide-stack mechanic for a consistent feel across the site. */

.weekend-datecards {
  display: none;
}

@media (min-width: 860px) {
  .weekend-datecards {
    display: block;
  }
}

.calendar-weekend-block + .calendar-weekend-block {
  margin-top: 48px;
  padding-top: 40px;
  border-top: 1px solid var(--hk-border);
}

.calendar-empty-month {
  border: 1px solid var(--hk-border);
  padding: 40px 24px;
  text-align: center;
  color: var(--hk-grey-1);
  font-size: 14px;
}

.datecards-row {
  display: flex;
  gap: 12px;
}

.datecard {
  flex: 1 1 0%;
  text-align: left;
  background: transparent;
  border: 1px solid var(--hk-border);
  padding: 16px 20px;
  cursor: pointer;
  transition: flex-grow var(--hk-motion-slow) cubic-bezier(0.4, 0, 0.2, 1), border-color var(--hk-motion-fast) ease,
    background var(--hk-motion-fast) ease;
}

.datecard:hover,
.datecard:focus-visible,
.datecard.is-active {
  border-color: var(--hk-white);
  background: rgba(255, 255, 255, 0.03);
}

/* The active/hovered card grows wider than the other two — same
   responsive-width idea as the earlier filmstrip version, just applied
   to 3 day cards instead of 6 event columns. */
.datecard.is-active {
  flex-grow: 2;
}

.datecard-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.datecard-dow,
.datecard-month {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
}

.datecard-date {
  font-family: var(--hk-heading-font);
  font-size: 32px;
  line-height: 1;
  color: var(--hk-white);
}

.datecard-count {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hk-grey-2);
}

.datecard.is-active .datecard-count {
  color: var(--hk-grey-1);
}

.night-reveal {
  margin-top: 16px;
}

.night-carousel {
  display: none;
}

.night-carousel.is-active {
  display: block;
}

.night-carousel-stage {
  position: relative;
  width: min(40vw, 280px);
  aspect-ratio: 1080 / 1440;
  margin: 0 auto;
  perspective: 1200px;
}

.night-slide {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #050505;
  transition: transform 260ms cubic-bezier(0.22, 0.8, 0.36, 1), opacity 260ms ease;
}

/* No flyer submitted: fall back to a plain white slide with black text
   instead of pretending there's an image to overlay text onto. */
.night-slide.no-image {
  background: var(--hk-white);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* A night's stage shows 3 flyers at once by default (active + one peek
   each side). Nights with more events show more peeks at once — see
   getVisibleCount() in the script below — using these extra "2 away"
   positions, scaled down and dimmed further to keep the active flyer
   as the clear focal point. */
.night-slide.is-left-2 {
  transform: translateX(-96%) scale(0.74);
  opacity: 0.2;
  z-index: 2;
}

.night-slide.is-right-2 {
  transform: translateX(96%) scale(0.74);
  opacity: 0.2;
  z-index: 2;
}

.night-slide img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.night-slide.is-active {
  transform: translateX(0) scale(1);
  opacity: 1;
  z-index: 4;
}

.night-slide.is-left {
  transform: translateX(-58%) scale(0.86);
  opacity: 0.35;
  z-index: 3;
}

.night-slide.is-right {
  transform: translateX(58%) scale(0.86);
  opacity: 0.35;
  z-index: 3;
}

.night-slide.is-hidden {
  transform: scale(0.7);
  opacity: 0;
  z-index: 1;
}

.night-slide-text {
  padding: 24px;
  text-align: center;
}

.night-slide-name {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 17px;
  margin: 0 0 4px;
  color: var(--hk-black);
}

.night-slide-venue {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.6);
  margin: 0;
}

.night-slide-time {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hk-grey-2);
  margin: 4px 0 0;
}

.night-slide-pick {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hk-black);
  background: var(--hk-white);
  padding: 4px 8px;
}

/* On a no-image (white) slide, an all-white Pick badge would disappear,
   so it inverts to black-on-white there instead. */
.night-slide.no-image .night-slide-pick {
  color: var(--hk-white);
  background: var(--hk-black);
}

@media (prefers-reduced-motion: reduce) {
  .night-slide {
    transition: opacity var(--hk-motion-fast) ease !important;
  }

  .night-slide.is-left,
  .night-slide.is-right,
  .night-slide.is-left-2,
  .night-slide.is-right-2,
  .night-slide.is-active,
  .night-slide.is-hidden {
    transform: none !important;
  }
}

/* ---------- Event detail (per-event page) ---------- */

.event-detail-image {
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1080 / 1440;
  border: 1px solid var(--hk-border);
  background: #050505;
  overflow: hidden;
  margin-bottom: 32px;
}

.event-detail-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.event-detail-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px 20px;
  max-width: 480px;
  font-size: 14px;
  margin-bottom: 30px;
}

.event-detail-meta dt {
  color: var(--hk-grey-1);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.event-detail-meta dd {
  margin: 0;
}

.event-detail-description {
  max-width: 60ch;
  line-height: 1.7;
  color: #e6e6e6;
  margin-bottom: 30px;
}

.back-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-bottom: 30px;
  border: 1px solid var(--hk-border);
  border-radius: 999px;
  color: var(--hk-grey-1);
  transition: color var(--hk-motion-fast) ease, background var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.back-link svg {
  width: 16px;
  height: 16px;
}

.back-link:hover,
.back-link:focus-visible {
  color: var(--hk-black);
  background: var(--hk-white);
  border-color: var(--hk-white);
}

/* ---------- Interview article header (kicker + name, then byline/date) ---------- */

/* Title block sits on its own line; the byline/date row sits directly
   under it, right-aligned, still above the intro/first question. */
.interview-header {
  max-width: none;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.interview-heading {
  max-width: 62ch;
}

.interview-kicker {
  font-size: 13px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--hk-grey-1);
  margin: 0 0 8px;
}

.interview-header h1 {
  margin: 0;
}

.interview-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.interview-meta-byline {
  font-family: var(--hk-heading-font);
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--hk-white);
  margin: 0 0 4px;
}

.interview-meta-date {
  font-size: 12px;
  color: var(--hk-grey-2);
  margin: 0;
}

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

.site-footer {
  max-width: var(--hk-max-width);
  margin: 0 auto;
  padding: 40px var(--hk-gutter) 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--hk-grey-1);
  border-top: 1px solid var(--hk-border);
}

.site-footer a {
  color: var(--hk-grey-1);
  border-bottom: 1px solid transparent;
  transition: color var(--hk-motion-fast) ease, border-color var(--hk-motion-fast) ease;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--hk-white);
  border-color: var(--hk-white);
}

.footer-instagram-link {
  display: inline-flex;
  border-bottom: none !important;
}

.footer-instagram-link svg {
  width: 18px;
  height: 18px;
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .hero-line,
  .hero-line-inner,
  .hero-logo {
    transition: none !important;
    transform: none !important;
  }

  .intro-loader {
    display: none;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
