/* ==========================================================================
   Chowdiah Memorial Hall — production stylesheet
   Direction: NYC Opera–inspired (committee-approved, MoM 30 Aug 2026)

   Written mobile-first: the base rules ARE the phone layout, and every
   media query is min-width. Per MoM item 1 the site must be genuinely
   usable on a phone, and every section must sit one tap from the nav.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
    /* Light */
    --bg:            #ffffff;
    --bg-2:          #f6f4f1;
    --bg-3:          #eae6e1;
    --text:          #141414;
    --text-2:        #55504b;
    /* Locked brand tokens. Single source of truth is
       _PortableDemo/mockups/brand.css, verified against the live site
       (rgb(128,0,0)). The red is IDENTICAL in both themes - it is a brand
       constant, not a theme variable. */
    --cmh-red:       #800000;
    --cmh-red-lift:  #a03232;
    --cmh-red-deep:  #5c0000;

    --accent:        var(--cmh-red);   /* rules, borders, chevrons */
    --accent-text:   var(--cmh-red);   /* eyebrow / kicker labels */
    --header-bg:     rgba(255, 255, 255, 0.92);
    --card:          #ffffff;
    --border:        #ded8d1;
    --footer-bg:     var(--cmh-red);
    --footer-text:   #ffffff;
    --btn-bg:        var(--cmh-red);
    --btn-text:      #ffffff;
    --btn-border:    var(--cmh-red);
    --overlay:       rgba(255, 255, 255, 0.98);
    --shadow:        0 2px 18px rgba(0, 0, 0, 0.09);

    /* Type scale — fluid, so nothing needs a per-device override */
    --step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.9rem);
    --step-0:  clamp(1rem, 0.96rem + 0.2vw, 1.09rem);
    --step-1:  clamp(1.19rem, 1.1rem + 0.42vw, 1.44rem);
    --step-2:  clamp(1.42rem, 1.26rem + 0.79vw, 1.94rem);
    --step-3:  clamp(1.69rem, 1.42rem + 1.34vw, 2.62rem);
    --step-4:  clamp(2.01rem, 1.57rem + 2.19vw, 3.53rem);

    /* Rhythm */
    --gutter:       clamp(1.15rem, 0.9rem + 1.25vw, 2.5rem);
    --section-y:    clamp(3.25rem, 2.4rem + 4.2vw, 7rem);
    --measure:      68ch;
    --header-h:     4rem;
    --radius:       3px;
    --tap:          2.75rem;         /* 44px — minimum tap target */

    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    color-scheme: light;
}

[data-theme="dark"] {
    --bg:            #0a0a0a;
    --bg-2:          #121212;
    --bg-3:          #1a1a1a;
    --text:          #ffffff;
    --text-2:        #b3aca4;
    /* Same red. Only the *decorative* tone lifts, so hairlines stay visible
       on near-black (#a03232 is 2.8:1 there, #b23a3a clears the 3:1 that
       WCAG asks of non-text UI). Accent TEXT goes near-white instead of
       red, per the brand rule that red is a field colour, not type. */
    --accent:        #b23a3a;
    --accent-text:   rgba(255, 255, 255, 0.88);
    --header-bg:     rgba(10, 10, 10, 0.92);
    --card:          #161616;
    --border:        #2e2e2e;
    --footer-bg:     var(--cmh-red-deep);
    --footer-text:   #ffffff;
    --btn-bg:        var(--cmh-red);
    --btn-text:      #ffffff;
    --btn-border:    var(--cmh-red-lift);
    --overlay:       rgba(10, 10, 10, 0.985);
    --shadow:        0 2px 24px rgba(0, 0, 0, 0.6);
    color-scheme: dark;
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
    -webkit-text-size-adjust: 100%;   /* stop iOS inflating text in landscape */
    scroll-behavior: smooth;
}

body {
    font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: var(--step-0);
    line-height: 1.65;
    background: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    /* No overflow-x:hidden — overflow is fixed at source, not masked. */
}

img, picture, svg, video {
    display: block;
    max-width: 100%;
}

h1, h2, h3, h4 {
    font-family: "Playfair Display", Georgia, serif;
    font-variant-numeric: lining-nums;
    font-weight: 700;
    line-height: 1.14;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

p { text-wrap: pretty; }

a { color: inherit; }

button, input, textarea, select { font: inherit; color: inherit; }

/* Visible focus for keyboard users, on every interactive element. */
:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
    border-radius: 2px;
}

::selection { background: var(--cmh-red); color: #fff; }

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Skip link — first tab stop, so keyboard/screen-reader users reach content
   without walking the whole nav. */
.skip-link {
    position: absolute;
    left: 0.5rem;
    top: -4rem;
    z-index: 200;
    background: var(--cmh-red);
    color: #ffffff;
    padding: 0.7rem 1.1rem;
    font-weight: 600;
    transition: top 0.18s var(--ease);
}
.skip-link:focus { top: 0.5rem; }

.wrap {
    width: 100%;
    max-width: 78rem;
    margin-inline: auto;
    padding-inline: var(--gutter);
}

/* Anchor targets must clear the sticky header, or a tap on a nav link
   leaves the heading hidden underneath it. Header padding grows by
   env(safe-area-inset-top) on notched phones, so this margin has to match
   that or a nav tap on those devices still leaves the heading tucked under
   the header's real (larger) height. */
section[id] {
    scroll-margin-top: calc(var(--header-h) + env(safe-area-inset-top) + 0.5rem);
}

/* --------------------------------------------------------------------------
   3. Header — sticky, so all five destinations stay one tap away
   -------------------------------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--header-bg);
    backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid transparent;
    transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
    padding-top: env(safe-area-inset-top);
}
.site-header.is-stuck {
    border-bottom-color: var(--border);
    box-shadow: var(--shadow);
}

.header-inner {
    min-height: var(--header-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* The wordmark rule, from brand.css and non-negotiable: "Chowdiah Memorial
   Hall" is ALWAYS set in white on a field of --cmh-red, identically in both
   themes. Never red type on a light ground. */
/* The wordmark must be allowed to give way. It previously carried
   `flex-shrink: 0`, which made it claim its full max-content width and push
   the theme toggle and hamburger clean off the right edge — 87px of
   horizontal overflow at 320px, 47px at 360px, 18px at 390px, i.e. the menu
   button was unreachable on most phones sold. The nav controls are the one
   thing that must never be squeezed, so the wordmark yields instead. */
.brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    min-height: var(--tap);
    min-width: 0;               /* lets the flex item shrink below max-content */
    flex-shrink: 1;
    background: var(--cmh-red);
    color: #ffffff;
    padding: 0.3rem 0.6rem 0.3rem 0.4rem;
    border-radius: var(--radius);
}
.brand img { width: 1.9rem; height: 1.9rem; flex-shrink: 0; }
.brand-text { display: flex; flex-direction: column; line-height: 1.12;
              min-width: 0; }
.brand-name {
    font-family: "Playfair Display", Georgia, serif;
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: -0.01em;
}
/* Below ~360px the name takes two lines rather than truncating — the hall's
   full name is the brand and must stay legible. Two lines still clear the
   4rem header. */
.brand-sub {
    font-size: 0.58rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.78);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The controls hold their size no matter what. */
.header-actions { display: flex; align-items: center; gap: 0.35rem;
                  flex-shrink: 0; }

/* Icon buttons: 44x44 minimum, always. */
.icon-btn {
    width: var(--tap);
    height: var(--tap);
    display: grid;
    place-items: center;
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    color: var(--text);
    transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
}
.icon-btn:hover { background: var(--bg-2); border-color: var(--text-2); }
.icon-btn svg { width: 1.15rem; height: 1.15rem; fill: none;
                stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }

.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun  { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* Desktop nav + desktop CTA are hidden on phones.
   Scoped to .site-header so this beats the later `.btn { display:inline-flex }`
   rule — both are single-class otherwise, and source order would win. */
.site-header .nav-desktop,
.site-header .header-cta { display: none; }

/* --------------------------------------------------------------------------
   4. Mobile menu — the thing the wireframe was missing entirely
   (its CSS said `display:none` on .nav-links with no replacement, so a phone
   had no navigation at all)
   -------------------------------------------------------------------------- */
.menu-panel {
    position: fixed;
    inset: 0;
    z-index: 150;
    background: var(--overlay);
    backdrop-filter: blur(6px);
    display: flex;
    flex-direction: column;
    padding: calc(env(safe-area-inset-top) + 0.75rem) var(--gutter)
             calc(env(safe-area-inset-bottom) + 1.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    /* visibility is stepped, never interpolated: it flips instantly on open
       and waits out the slide on close. Interpolating it means a stalled or
       interrupted transition can strand the menu open-but-invisible. */
    transition: transform 0.32s var(--ease),
                opacity 0.24s var(--ease),
                visibility 0s linear 0.32s;
}
.menu-panel[data-open="true"] {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
    transition: transform 0.32s var(--ease),
                opacity 0.24s var(--ease),
                visibility 0s linear 0s;
}

.menu-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--header-h);
    margin-bottom: 1rem;
}

.menu-list { list-style: none; padding: 0; }
.menu-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 3.5rem;              /* 56px — comfortable thumb target */
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--border);
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    text-decoration: none;
}
.menu-list a::after {
    content: "";
    width: 0.55rem; height: 0.55rem;
    border-right: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(-45deg);
    flex-shrink: 0;
}
.menu-cta { margin-top: 1.75rem; }
.menu-cta .btn { width: 100%; }

.menu-meta {
    margin-top: auto;
    padding-top: 2rem;
    font-size: var(--step--1);
    color: var(--text-2);
}
.menu-meta a { text-decoration: none; display: inline-flex;
               align-items: center; min-height: var(--tap); }

body.menu-open { overflow: hidden; }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: var(--tap);
    padding: 0.7rem 1.5rem;
    border-radius: var(--radius);
    border: 1px solid transparent;
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.16s var(--ease), background 0.2s var(--ease),
                color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn-primary {
    background: var(--btn-bg);
    color: var(--btn-text);
    border-color: var(--btn-border);
}
.btn-primary:hover { filter: brightness(1.1); }

.btn-outline {
    background: transparent;
    color: var(--text);
    border-color: currentColor;
}
.btn-outline:hover { background: var(--text); color: var(--bg); }

.btn-on-dark { color: #fff; border-color: rgba(255, 255, 255, 0.75); }
.btn-on-dark:hover { background: #fff; color: #0a0a0a; }

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */
.hero {
    position: relative;
    min-height: 34rem;
    /* svh keeps the hero from jumping when mobile browser chrome hides. */
    height: 82svh;
    max-height: 46rem;
    display: grid;
    align-items: end;
    overflow: hidden;
    isolation: isolate;
}
.hero-media {
    position: absolute;
    inset: 0;
    z-index: 0;
}
/* <picture> is the img's actual parent, so it has to fill the box too —
   otherwise height:100% on the img resolves against an auto-height parent
   and silently falls back to the image's intrinsic height. */
.hero-media picture { display: block; width: 100%; height: 100%; }
.hero-media img { width: 100%; height: 100%; object-fit: cover;
                  object-position: 50% 58%; }

/* Two-layer scrim. The approved wireframe put pale text straight onto a busy
   photo and the headline was unreadable; this guarantees contrast without
   flattening the image. */
.hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        linear-gradient(to top, rgba(0,0,0,0.95) 0%, rgba(0,0,0,0.88) 30%,
                                rgba(0,0,0,0.62) 50%, rgba(0,0,0,0.26) 74%,
                                rgba(0,0,0,0.45) 100%),
        radial-gradient(130% 90% at 30% 95%, rgba(0,0,0,0.62), transparent 68%);
}

.hero-body {
    position: relative;
    z-index: 2;                       /* above the scrim */
    padding-block: 0 clamp(2.5rem, 8vw, 5rem);
    color: #fff;
}
/* Hairline-dash label, shared with .eyebrow below — the site's one
   recurring "this is a label" device, used consistently instead of each
   spot inventing its own treatment (this used to be a vertical bar). */
.hero-kicker {
    display: inline-flex;
    align-items: center;
    gap: 0.65em;
    font-size: var(--step--1);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--accent-text);
    margin-bottom: 1rem;
}
.hero-kicker::before {
    content: "";
    width: 1.5rem;
    height: 1px;
    background: currentColor;
    opacity: 0.7;
    flex-shrink: 0;
}
.hero h1 { font-size: var(--step-4); color: #fff; max-width: 20ch; }
.hero-lede {
    margin-top: 1.15rem;
    max-width: 46ch;
    color: rgba(255, 255, 255, 0.9);
    font-size: var(--step-1);
    font-weight: 300;
}
.hero-actions {
    margin-top: 1.9rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}
.hero-actions .btn { flex: 1 1 13rem; }

/* The hero's rotating background (see "Home slideshow" below for the shared
   .slide/.slideshow__* rules). .hero-media carries [data-slideshow] itself —
   its images must stay under the scrim, but the prev/next/dot controls the
   script appends into it need to paint above the scrim and the headline, so
   they get an explicit stacking-context-escaping z-index here. */
.hero-media .slides { position: absolute; inset: 0; aspect-ratio: auto; }
.hero .slideshow__btn,
.hero .slideshow__dots { z-index: 3; }

/* --------------------------------------------------------------------------
   7. Section furniture
   -------------------------------------------------------------------------- */
.section { padding-block: var(--section-y); }
.section-tint { background: var(--bg-2); }

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.65em;
    font-size: var(--step--1);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--accent-text);
    font-weight: 600;
}
.eyebrow::before {
    content: "";
    width: 1.5rem;
    height: 1px;
    background: currentColor;
    opacity: 0.7;
    flex-shrink: 0;
}
.section-title { font-size: var(--step-3); margin-top: 0.6rem; }
.section-lede {
    margin-top: 1rem;
    max-width: var(--measure);
    color: var(--text-2);
    font-size: var(--step-1);
    font-weight: 300;
}
.section-head { margin-bottom: clamp(1.75rem, 4vw, 3rem); }

.rule {
    height: 1px;
    background: var(--border);
    border: 0;
    margin-block: var(--section-y) 0;
}

/* --------------------------------------------------------------------------
   8. What's On
   -------------------------------------------------------------------------- */
/* 2-up from the base width, not just from 34em — at 320px+ two ~145px
   columns are still comfortable — except these particular images are scans
   of dense text posters (award name, artist names), and a 2-up grid crops
   them to illegibility. A horizontal swipe carousel keeps each poster at
   full, readable width instead: one card fills most of the screen, the next
   peeks at the edge as an affordance, and it never turns into a wall of
   cropped thumbnails. Below 62em only — the desktop grid further down still
   has the room to show all four at once. */
.invite-grid {
    display: flex;
    gap: 0.85rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    padding-bottom: 0.35rem;             /* clears the hidden scrollbar area */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.invite-grid::-webkit-scrollbar { display: none; }
.invite {
    flex: 0 0 78%;
    scroll-snap-align: start;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform 0.22s var(--ease), border-color 0.22s var(--ease);
}
.invite:hover { transform: translateY(-3px); border-color: var(--accent); }
/* The invitation cards are 2:1. Declaring it stops the browser reflowing
   when they load, and stops them being squashed by a fixed height. */
.invite img { width: 100%; aspect-ratio: 2 / 1; object-fit: cover; }
.invite-body { padding: 1.1rem 1.25rem 1.35rem; }
.invite-date {
    display: inline-block;
    font-size: var(--step--1);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent-text);
    font-weight: 600;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
}
.invite-body h3 { font-size: var(--step-1); margin-top: 0.4rem; }
.invite-body p { margin-top: 0.5rem; color: var(--text-2);
                 font-size: var(--step--1); }

/* The festival schedule scan is square (1400x1400). The wireframe forced it
   into a 1713x278 letterbox, which made it unreadable — here it keeps its
   own aspect ratio and can be opened full size. */
.schedule {
    margin-top: 2rem;
    display: grid;
    gap: 1.5rem;
    align-items: center;
    padding: clamp(1.25rem, 4vw, 2.5rem);
    background: var(--bg-3);
    border-radius: var(--radius);
}
.schedule img {
    width: 100%;
    max-width: 30rem;
    margin-inline: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    background: #fff;
    border-radius: var(--radius);
}
.schedule h3 { font-size: var(--step-2); }
.schedule p { margin-top: 0.75rem; color: var(--text-2); }

/* Featured event card — AIM BIAF 2026 */
.featured-event {
    margin-top: 2rem;
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent-text, #800000);
    border-radius: var(--radius);
    background: var(--card);
    overflow: hidden;
}
.featured-event__badge {
    padding: 0.85rem clamp(1.25rem, 4vw, 2rem) 0;
}
.featured-event__body {
    padding: 0.5rem clamp(1.25rem, 4vw, 2rem) clamp(1.25rem, 4vw, 2rem);
}
.featured-event__body h3 {
    font-size: var(--step-2);
    margin-top: 0.4rem;
    margin-bottom: 1.25rem;
}
.featured-event__programmes {
    display: grid;
    gap: 1.25rem;
}
.featured-event__prog {
    padding: 1rem 1.25rem;
    background: var(--bg-3);
    border-radius: calc(var(--radius) - 2px);
    font-size: var(--step-0);
}
.featured-event__prog strong { display: block; margin-bottom: 0.4rem; }
.featured-event__prog p { margin-top: 0.5rem; color: var(--text-2); line-height: 1.55; }
.featured-event__lineup {
    font-size: var(--step--1);
    color: var(--text-2);
    margin-top: 0.6rem !important;
    line-height: 1.7;
}
.featured-event__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}


.drama {
    margin-top: 1.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--card);
}
/* 3:2 source — never letterboxed to 4.8:1 as the wireframe did. */
.drama img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.drama-body { padding: clamp(1.25rem, 4vw, 2rem); }
.drama-body h3 { font-size: var(--step-2); margin-top: 0.5rem; }
.drama-body p { margin-top: 0.75rem; color: var(--text-2); max-width: var(--measure); }
.drama-body .btn { margin-top: 1.35rem; }

/* Drama Festival 2026 scroll gallery — photos + video slides */
.drama-gallery {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 0 clamp(1.25rem, 4vw, 2rem) clamp(1.25rem, 4vw, 2rem);
    margin: 0;
    scrollbar-width: none;
}
.drama-gallery::-webkit-scrollbar { display: none; }
.drama-gallery figure {
    flex: 0 0 78vw;
    scroll-snap-align: start;
    margin: 0;
    border-radius: calc(var(--radius) - 2px);
    overflow: hidden;
    cursor: zoom-in;    /* signals the photo is tappable */
    position: relative; /* for the video play badge */
}
.drama-gallery img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    transition: transform 0.25s var(--ease);
}
.drama-gallery figure:hover img { transform: scale(1.03); }

/* Video slides — same 4:3 frame, video fills it */
.drama-gallery video {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    background: #000;
}
/* Play badge overlaid on video thumbnails */
.drama-gallery__vid-fig { cursor: pointer; }
.drama-gallery__play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    color: #fff;
    background: rgba(0, 0, 0, 0.32);
    pointer-events: none; /* let clicks pass through to the figure */
    transition: background 0.2s;
}
.drama-gallery__vid-fig:hover .drama-gallery__play { background: rgba(0, 0, 0, 0.5); }

/* --------------------------------------------------------------------------
   Lightbox — fullscreen overlay
   Clicking the dark backdrop (outside the media) closes it.
   Wired to .drama-gallery figures and .committee-card a by main.js.
   -------------------------------------------------------------------------- */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 600;
    background: rgba(0, 0, 0, 0.92);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    cursor: zoom-out; /* clicking anywhere outside the media closes it */
    padding: 1rem;
}
.lightbox[hidden] { display: none; }

.lightbox__content {
    max-width: min(92vw, 1100px);
    max-height: 85vh;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: default; /* clicks on the media itself don't close */
}
.lightbox__content img {
    display: block;
    max-width: 100%;
    max-height: 85vh;
    object-fit: contain;
    border-radius: 4px;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.7);
}
.lightbox__content video {
    display: block;
    max-width: 100%;
    max-height: 85vh;
    border-radius: 4px;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.7);
    cursor: default;
}

.lightbox__close {
    position: absolute;
    top: clamp(0.75rem, 2vw, 1.25rem);
    right: clamp(0.75rem, 2vw, 1.25rem);
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.4);
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s;
    z-index: 10;
}
.lightbox__close:hover { background: rgba(0, 0, 0, 0.8); border-color: rgba(255, 255, 255, 0.8); }

.lightbox__hint {
    font-size: var(--step--1);
    color: rgba(255, 255, 255, 0.45);
    margin: 0;
    user-select: none;
    pointer-events: none;
}


/* --------------------------------------------------------------------------
   9. The Hall
   -------------------------------------------------------------------------- */
.hall-grid { display: grid; gap: clamp(1.75rem, 5vw, 3.5rem); }
.hall-copy p + p { margin-top: 1rem; }
.hall-copy p { color: var(--text-2); }
.hall-figure img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
                   border-radius: var(--radius); }
.hall-figure figcaption {
    margin-top: 0.6rem;
    font-size: var(--step--1);
    color: var(--text-2);
    font-style: italic;
}

/* Home page — one large image that rotates through the views of the hall.
   Without JS only the first slide shows (the rest stay at opacity 0). */
.slideshow {
    position: relative;
    max-width: 68rem;      /* ~ the images' native width, so they stay sharp */
    overflow: hidden;
    border-radius: var(--radius);
    background: var(--bg-3);
}
.slides { position: relative; aspect-ratio: 16 / 10; }
.slide {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    transition: opacity 0.9s var(--ease);
}
.slide.is-active { opacity: 1; }
.slide picture { display: block; height: 100%; }
.slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slide figcaption {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    padding: 2.5rem 1.25rem 1rem;
    font-size: var(--step--1);
    font-style: italic;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.68), rgba(0, 0, 0, 0));
}
.slideshow__btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: var(--tap);
    height: var(--tap);
    display: grid;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    cursor: pointer;
    transition: background 0.18s var(--ease);
}
.slideshow__btn:hover { background: rgba(0, 0, 0, 0.7); }
.slideshow__btn--prev { left: 0.75rem; }
.slideshow__btn--next { right: 0.75rem; }
.slideshow__btn svg { width: 1.15rem; height: 1.15rem; fill: none;
                      stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.slideshow__dots {
    position: absolute;
    right: 0.75rem; bottom: 0.4rem;
    display: flex;
}
.slideshow__dot {
    width: var(--tap); height: var(--tap);
    display: grid; place-items: center;
    background: none; border: 0; cursor: pointer; padding: 0;
}
.slideshow__dot::before {
    content: "";
    width: 0.6rem; height: 0.6rem;
    border-radius: 50%;
    border: 1.5px solid #fff;
    background: transparent;
    transition: background 0.2s var(--ease);
}
.slideshow__dot[aria-current="true"]::before { background: #fff; }
@media (min-width: 48em) {
    .slides { aspect-ratio: 2 / 1; }
    .slide figcaption { padding: 3rem 1.75rem 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
    .slide { transition: none; }
}

.specs { margin-top: 2rem; border-top: 1px solid var(--border); }
.spec-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    justify-content: space-between;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--border);
}
.spec-label { color: var(--text-2); font-size: var(--step--1);
              letter-spacing: 0.06em; text-transform: uppercase; }
.spec-value { font-weight: 600; }

.hall-features-grid {
    display: grid;
    gap: 0.85rem;
    margin-top: 1.5rem;
    grid-template-columns: 1fr;
}
@media (min-width: 38em) {
    .hall-features-grid {
        grid-template-columns: 1fr 1fr;
    }
}
.hall-feature-item {
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1rem 1.15rem;
}
.hall-feature-item h4 {
    font-size: var(--step-0);
    margin-bottom: 0.35rem;
    color: var(--text);
}
.hall-feature-item p {
    font-size: var(--step--1);
    color: var(--text-2);
    line-height: 1.5;
    margin: 0;
}

/* --------------------------------------------------------------------------
   10. Architecture strip
   -------------------------------------------------------------------------- */
/* Faint numeral before each card — counted in CSS so the markup stays plain
   text (renumbers itself automatically if a card is ever added/removed).
   Uses --text-2 (the site's existing muted-text token) at reduced opacity
   for a "ghost index, not a headline" look — var(--border) was tried first
   but measured under 2:1 contrast against the dark-theme background,
   i.e. functionally invisible rather than subtle; confirmed by live
   in-browser testing, not just a color-value guess. */
.arch-grid { display: grid; gap: 1.25rem; counter-reset: arch; }
.arch-card figure { margin: 0; }
.arch-card img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
                 border-radius: var(--radius); }
.arch-card::before {
    counter-increment: arch;
    content: counter(arch, decimal-leading-zero);
    display: block;
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    line-height: 1;
    color: var(--text-2);
    opacity: 0.4;
    margin-bottom: 0.5rem;
}
.arch-card h3 { font-size: var(--step-1); margin-top: 0.85rem; }
.arch-card p { margin-top: 0.4rem; color: var(--text-2);
               font-size: var(--step--1); }

/* --------------------------------------------------------------------------
   10b. About the Academy
   -------------------------------------------------------------------------- */
.about-subheading {
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-1);
    margin-top: 2.25rem;
    margin-bottom: 0.85rem;
    color: var(--text);
}
.about-genesis__grid {
    display: grid;
    gap: 1.5rem;
    margin-top: 1rem;
}
@media (min-width: 52em) {
    .about-genesis__grid {
        grid-template-columns: 1fr 1fr;
        gap: 2.5rem;
    }
}
.about-genesis__col p + p {
    margin-top: 1rem;
}
.about-genesis__col p {
    color: var(--text-2);
    line-height: 1.6;
}
.about-genesis__col strong {
    color: var(--text);
}

.medha-feature {
    margin-top: 2.5rem;
    padding: clamp(1.25rem, 3vw, 2rem);
    background: var(--card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
}
.medha-feature__title {
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    margin: 0.35rem 0 0.85rem;
}
.medha-feature p {
    color: var(--text-2);
    line-height: 1.6;
}
.medha-feature p + p {
    margin-top: 0.75rem;
}
.medha-feature strong {
    color: var(--text);
}

.about-honours {
    margin-top: 2.5rem;
    padding-top: 2rem;
    border-top: 1px solid var(--border);
}
.about-honours__intro {
    color: var(--text-2);
    max-width: var(--measure);
    margin-bottom: 1.25rem;
    line-height: 1.6;
}
.awardees-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    list-style: none;
    padding: 0;
    margin: 0;
}
.awardees-list li {
    font-size: var(--step--1);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    line-height: 1.4;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}
.awardees-list li:hover {
    border-color: var(--accent);
}
.awardees-list li.awardees-more {
    background: var(--bg-3);
    font-style: italic;
    color: var(--text-2);
}

.about-future {
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--border);
}
.about-future p {
    color: var(--text-2);
    max-width: var(--measure);
    line-height: 1.6;
}
.about-honours__more { margin-top: 1.25rem; }

/* --------------------------------------------------------------------------
   10c. Awards
   -------------------------------------------------------------------------- */
.awards-group {
    margin-top: clamp(2.25rem, 5vw, 3.25rem);
    padding-top: clamp(1.75rem, 4vw, 2.5rem);
    border-top: 1px solid var(--border);
}
.awards-group__title {
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    margin-bottom: 1.5rem;
}
.awards-cols { display: grid; gap: 2rem; }
.awards-label {
    font-size: var(--step--1);
    letter-spacing: 0.13em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: 0.5rem;
}
.awards-list { list-style: none; padding: 0; margin: 0; counter-reset: award; }
.awards-list li {
    counter-increment: award;
    display: grid;
    grid-template-columns: 2.25rem 1fr;
    column-gap: 0.5rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border);
    line-height: 1.4;
}
.awards-list li::before {
    content: counter(award, decimal-leading-zero);
    color: var(--text-2);
    font-size: var(--step--1);
    font-variant-numeric: tabular-nums;
    padding-top: 0.12em;
}
.awards-list--plain li { grid-template-columns: 1fr; }
.awards-list--plain li::before { content: none; }
.awards-list--year li { grid-template-columns: 2.25rem 1fr auto; }
.awards-year {
    color: var(--text-2);
    font-size: var(--step--1);
    font-variant-numeric: tabular-nums;
    padding-left: 1rem;
    padding-top: 0.12em;
}
.awards-sub { display: block; color: var(--text-2); font-size: var(--step--1); }

.awards-years { display: grid; gap: 1.25rem; }
.awards-year-card {
    padding: clamp(1.25rem, 3vw, 1.75rem);
    background: var(--card);
    border: 1px solid var(--border);
    border-top: 3px solid var(--accent);
    border-radius: var(--radius);
}
.awards-year-card__year {
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    margin-bottom: 0.75rem;
}
.awards-year-card .awards-label { margin-top: 1rem; }
.awards-year-card ul { list-style: none; padding: 0; margin: 0; }
.awards-year-card li { padding: 0.25rem 0; line-height: 1.4; }

@media (min-width: 48em) {
    .awards-cols  { grid-template-columns: 1fr 1fr; gap: 3rem; }
    .awards-years { grid-template-columns: 1fr 1fr; }
    .awards-list--cols { display: grid; grid-template-columns: 1fr 1fr; column-gap: 3rem; }
}

/* --------------------------------------------------------------------------
   11. Legacy
   -------------------------------------------------------------------------- */
.legacy { background: var(--bg-3); }
.legacy-body { max-width: var(--measure); }
.legacy-body p + p { margin-top: 1rem; }
.legacy-body p { color: var(--text-2); }
.pull {
    margin-top: 2rem;
    padding-left: clamp(1rem, 3vw, 1.75rem);
    border-left: 3px solid var(--accent);
    font-family: "Playfair Display", Georgia, serif;
    font-size: var(--step-2);
    font-style: italic;
    line-height: 1.35;
}

/* Founder's account — a short condensed extract in Sri K. K. Murthy's own
   words. Runs full-width in two columns at desktop (echoing the souvenir's
   own print layout); single column, capped at --measure, below. */
.legacy-account {
    max-width: var(--measure);
    margin-top: clamp(2.5rem, 5vw, 3.75rem);
    padding-top: clamp(1.5rem, 3.5vw, 2.25rem);
    border-top: 1px solid var(--border);
}
.legacy-account-meta {
    font-size: var(--step--1);
    letter-spacing: 0.01em;
    color: var(--text-2);
}
.legacy-account-body { margin-top: 1.2rem; }
.legacy-account-body p { color: var(--text-2); }
.legacy-account-body p + p { margin-top: 1rem; }
.legacy-account-sign {
    margin-top: 1.25rem;
    font-style: italic;
    color: var(--text-2);
}

/* Founder portraits. Edges are feathered with a mask so the cream photo
   melts into the section background in either theme (no frame, no shadow). */
.legacy-portrait { margin: 0 auto 1.5rem; max-width: min(70%, 18rem); }
.legacy-portrait img {
    width: 100%; height: auto;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent),
                        linear-gradient(to bottom, transparent, #000 10%, #000 88%, transparent);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent),
                linear-gradient(to bottom, transparent, #000 10%, #000 88%, transparent);
    mask-composite: intersect;
}
/* Captions: left-aligned to the photo's left edge, never wider than the photo.
   Same three styles in both captions; they differ only in line order. */
.legacy-portrait figcaption {
    margin-top: 0.8rem;
    max-width: 100%;
    text-align: left;
    display: flex; flex-direction: column; gap: 0.2rem;
}
.legacy-portrait .cap-eyebrow {
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: 600;
    line-height: 1.5;
    color: var(--text-2);
}
.legacy-portrait .cap-name {
    font-family: "Playfair Display", Georgia, serif;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
    white-space: nowrap;
    color: var(--text);
}
.legacy-portrait .cap-years {
    font-size: 0.875rem;
    color: var(--text-2);
    font-variant-numeric: lining-nums;
}
.legacy-portrait .cap-nowrap { white-space: nowrap; font-variant-numeric: lining-nums; }
.legacy-account-head { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
.legacy-account-head .legacy-portrait { margin-bottom: 0; max-width: min(60%, 14rem); }
.legacy-account-head .legacy-account-meta { font-size: var(--step-1); font-family: "Playfair Display", Georgia, serif; font-style: italic; text-align: center; }

@media (min-width: 900px) {
    .legacy-body {
        max-width: none;
        display: grid;
        grid-template-columns: minmax(0, var(--measure)) minmax(14rem, 22rem);
        justify-content: space-between;
        gap: clamp(2rem, 5vw, 4rem);
        align-items: start;
    }
    .legacy-text { grid-column: 1; grid-row: 1; }
    .legacy-portrait--chowdiah {
        grid-column: 2; grid-row: 1;
        position: sticky;
        top: calc(var(--header-h) + env(safe-area-inset-top) + 24px);
        max-width: none; width: 100%; margin: 0;
    }
    .legacy-account-head { flex-direction: row; align-items: center; gap: clamp(1.5rem, 4vw, 2.5rem); }
    .legacy-account-head .legacy-portrait { flex: 0 0 clamp(12.5rem, 16vw, 15rem); max-width: none; }
    .legacy-account-head .legacy-account-meta { text-align: left; max-width: 28ch; font-size: var(--step-2); }
}

/* --------------------------------------------------------------------------
   11b. Academy of Music / managing committee
   Native JPEGs are served directly from the supplied archive: no derivative
   export, upscaling, or additional compression is introduced. On narrow
   screens the cards retain a comfortable portrait width and scroll-snap;
   desktop returns to an even grid.
   -------------------------------------------------------------------------- */
.committee-lead {
    display: grid;
    gap: 0.65rem;
    max-width: var(--measure);
    margin: 2rem 0;
    padding: 1.25rem;
    background: var(--bg-3);
    border-left: 3px solid var(--accent);
}
.committee-lead p { color: var(--text-2); }
.committee-lead strong { color: var(--text); }
.committee-grid {
    display: flex;
    gap: 0.85rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    padding-bottom: 0.5rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.committee-grid::-webkit-scrollbar { display: none; }
.committee-card {
    flex: 0 0 min(74vw, 18rem);
    align-self: start;
    scroll-snap-align: start;
    padding-bottom: 1.1rem;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.committee-card a {
    display: block;
    aspect-ratio: 3 / 4;
    overflow: hidden;
}
.committee-card img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: center top;
}
.committee-card h3 { margin: 0.9rem 1rem 0; font-size: var(--step-0); }
.committee-card p {
    margin: 0.25rem 1rem 0;
    color: var(--accent-text);
    font-size: var(--step--1);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

@media (min-width: 62em) {
    .legacy-account { max-width: 100%; }
    .legacy-account-meta,
    .legacy-account-sign { max-width: var(--measure); }
    .legacy-account-body {
        margin-top: 1.4rem;
        columns: 2;
        column-gap: clamp(2rem, 4vw, 3.5rem);
    }
    .legacy-account-sign { margin-top: 1.6rem; }
}

/* --------------------------------------------------------------------------
   12. Visit — calendar + practical detail
   -------------------------------------------------------------------------- */
.visit-grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); }

.cal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}
.cal-head h3 { font-size: var(--step-1); }
.cal-nav { display: flex; gap: 0.4rem; }

.cal {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.3rem;
}
.cal-dow {
    text-align: center;
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-2);
    padding-bottom: 0.35rem;
}
/* Square cells that stay legible at 320px — the wireframe collapsed the whole
   calendar to one stacked column on mobile and hid the day headings. */
.cal-day {
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    font-size: var(--step--1);
    font-variant-numeric: tabular-nums;
    border: 1px solid var(--border);
    border-radius: 2px;
    background: var(--card);
}
.cal-day.is-empty { border-color: transparent; background: none; }
.cal-day.is-available { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.cal-day.is-today { outline: 2px solid var(--accent); font-weight: 700; }
.cal-legend {
    margin-top: 0.9rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.1rem;
    font-size: var(--step--1);
    color: var(--text-2);
}
.swatch { display: inline-block; width: 0.75rem; height: 0.75rem;
          border: 1px solid var(--accent); border-radius: 2px;
          margin-right: 0.4rem; vertical-align: -1px; }

.visit-facts dt {
    font-size: var(--step--1);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent-text);
    font-weight: 600;
    margin-top: 1.35rem;
}
.visit-facts dt:first-child { margin-top: 0; }
.visit-facts dd { margin: 0.3rem 0 0; }
.visit-facts a { text-decoration: none; border-bottom: 1px solid var(--border);
                 display: inline-flex; align-items: center; min-height: var(--tap); }
.visit-facts a:hover { border-bottom-color: var(--accent); }

/* --------------------------------------------------------------------------
   13. Gallery
   -------------------------------------------------------------------------- */
/* Same carousel as .invite-grid above, and for the same reason: eight
   photos stacked (or even paired) on a phone read as a wall of thumbnails
   rather than a gallery. One photo at a time, swiped through, does the
   collection more justice. Grid returns at 62em, where there's room for
   all eight at once. */
.gallery-grid {
    display: flex;
    gap: 0.6rem;
    align-items: start;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    padding-bottom: 0.35rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.gallery-grid::-webkit-scrollbar { display: none; }
.gallery-grid figure {
    flex: 0 0 72%;
    aspect-ratio: 4 / 3;
    scroll-snap-align: start;
}
.gallery-grid img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    border-radius: var(--radius);
    transition: transform 0.3s var(--ease), filter 0.3s var(--ease);
}
.gallery-grid figure { margin: 0; overflow: hidden; border-radius: var(--radius); }
.gallery-grid figure:hover img { transform: scale(1.035); }

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */
.site-footer {
    background: var(--footer-bg);
    color: var(--footer-text);
    padding-block: var(--section-y) 0;
}
.footer-grid { display: grid; gap: 2.25rem; }
.footer-col h4 {
    font-size: var(--step--1);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-family: Inter, sans-serif;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.65);
    margin-bottom: 0.9rem;
}
.footer-col ul { list-style: none; padding: 0; }
.footer-col li a,
.footer-col address a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    text-decoration: none;
    color: rgba(255, 255, 255, 0.92);
    border-bottom: 1px solid transparent;
}
.footer-col li a:hover,
.footer-col address a:hover { border-bottom-color: currentColor; }
.footer-col address { font-style: normal; line-height: 1.7;
                      color: rgba(255, 255, 255, 0.92); }

.socials { display: flex; gap: 0.5rem; margin-top: 0.25rem; }
.socials a {
    width: var(--tap); height: var(--tap);
    display: grid; place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: var(--radius);
    color: #fff;
    transition: background 0.2s var(--ease), border-color 0.2s var(--ease),
                transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.socials a:hover,
.socials a:focus-visible { background: rgba(255, 255, 255, 0.18);
                           border-color: rgba(255, 255, 255, 0.8);
                           box-shadow: 0 0.4rem 1rem rgba(0, 0, 0, 0.2);
                           transform: translateY(-3px); }
.socials svg { width: 1.1rem; height: 1.1rem; fill: currentColor; }

.footer-badge {
    display: inline-block;
    margin-top: 0.9rem;
    font-size: var(--step--1);
    color: rgba(255, 255, 255, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 999px;
    padding: 0.3rem 0.85rem;
}

.footer-bottom {
    margin-top: 2.5rem;
    padding-block: 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    justify-content: space-between;
    font-size: var(--step--1);
    color: rgba(255, 255, 255, 0.72);
}

/* Back to top — keeps the nav one tap away after a long scroll. */
.to-top {
    position: fixed;
    right: var(--gutter);
    bottom: calc(1rem + env(safe-area-inset-bottom));
    z-index: 90;
    width: var(--tap); height: var(--tap);
    display: grid; place-items: center;
    background: var(--btn-bg);
    color: var(--btn-text);
    border: none;
    border-radius: 50%;
    box-shadow: var(--shadow);
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.5rem);
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease),
                visibility 0.25s;
}
.to-top[data-show="true"] { opacity: 1; visibility: visible; transform: none; }
.to-top svg { width: 1.15rem; height: 1.15rem; fill: none;
              stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* --------------------------------------------------------------------------
   14b. Music player
   Reethigowla, played by Maestro Chowdiah. Starts muted (browsers allow
   muted autoplay without a gesture) and loops; one tap unmutes and fades
   the volume in. Bottom-left, opposite the to-top button.
   -------------------------------------------------------------------------- */
.player {
    position: fixed;
    /* Left, not right: at common phone viewport heights the hero's own CTA
       ("Explore the hall") lands at roughly this height, and a bottom-right
       player sat directly on top of it, blocking the tap on the very first
       screen a visitor sees. To-top lives on the right and only appears
       after scrolling past the hero, so the two never collide. */
    left: var(--gutter);
    bottom: calc(1rem + env(safe-area-inset-bottom));
    z-index: 90;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.player-btn {
    position: relative;
    width: var(--tap);
    height: var(--tap);
    display: grid;
    place-items: center;
    flex-shrink: 0;
    background: var(--cmh-red);
    color: #ffffff;
    border: 1px solid var(--cmh-red-lift);
    border-radius: 50%;
    box-shadow: var(--shadow);
    cursor: pointer;
}
.player-btn svg { width: 1.15rem; height: 1.15rem; fill: currentColor; }
.player-btn .icon-unmuted { display: none; }
.player[data-muted="false"] .player-btn .icon-muted { display: none; }
.player[data-muted="false"] .player-btn .icon-unmuted { display: block; }

/* Pulse only while muted, to say "there is sound here". */
.player[data-muted="true"] .player-btn::after {
    content: "";
    position: absolute;
    width: var(--tap); height: var(--tap);
    border-radius: 50%;
    border: 2px solid var(--cmh-red-lift);
    animation: player-pulse 2.4s var(--ease) infinite;
}
@keyframes player-pulse {
    0%   { transform: scale(1);    opacity: 0.75; }
    70%  { transform: scale(1.55); opacity: 0; }
    100% { transform: scale(1.55); opacity: 0; }
}

.player-label {
    /* Always visible — hover-only was invisible on touch devices.
       The label is the only affordance explaining what the button does. */
    max-width: 15rem;
    overflow: hidden;
    white-space: nowrap;
    font-size: var(--step--1);
    color: var(--text);
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    opacity: 1;
    padding: 0.45rem 0.75rem;
}

@media (prefers-reduced-motion: reduce) {
    .player[data-muted="true"] .player-btn::after { animation: none; }
}

/* --------------------------------------------------------------------------
   15. Reveal-on-scroll
   -------------------------------------------------------------------------- */
/* Scoped to .js (set by an inline script in <head>). Without it the reveal
   state never applies, so if JavaScript is blocked, fails, or the observer
   never fires, every section is simply visible rather than stuck at
   opacity:0. Content must never depend on an animation completing. */
.js .reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   16. Breakpoints (min-width only — mobile is the base case)
   -------------------------------------------------------------------------- */

/* Large phone / small tablet */
@media (min-width: 34em) {
    /* .invite-grid and .gallery-grid stay carousels through this breakpoint
       — they only switch to a grid at 62em, where there's room for all of
       them at once (see that block). Nothing to add here for either. */
    .arch-grid    { grid-template-columns: repeat(2, 1fr); }
    .hero-actions .btn { flex: 0 0 auto; }
}

/* Tablet */
@media (min-width: 48em) {
    :root { --header-h: 4.5rem; }
    .brand img { width: 2.6rem; height: 2.6rem; }
    .brand-name { font-size: 1.2rem; }
    .arch-grid  { grid-template-columns: repeat(3, 1fr); }
    .schedule   { grid-template-columns: 0.9fr 1.1fr; }
    .schedule img { margin-inline: 0; }
    .featured-event__programmes { grid-template-columns: 1fr 1fr; }
    .visit-grid { grid-template-columns: 1.15fr 0.85fr; }
    .footer-grid { grid-template-columns: repeat(2, 1fr); }
    .cal-day { font-size: var(--step-0); }
}

/* Wide desktop — swap the hamburger for the inline nav. Brand + 8 links +
   Enquire/theme need ~1320px, more than the 78rem content column, so the
   header is allowed to be wider than the page. Below this width the
   hamburger stays, otherwise links wrap and crowd the logo. main.js matches
   this query. */
@media (min-width: 84em) {
    .site-header .menu-btn { display: none; }
    .site-header .header-inner { max-width: 90rem; gap: 2rem; }
    .brand-name { white-space: nowrap; }
    .site-header .nav-desktop { display: flex; align-items: center; gap: 1.25rem; }
    .nav-desktop a {
        display: inline-flex;
        align-items: center;
        min-height: var(--tap);
        font-size: var(--step--1);
        letter-spacing: 0.1em;
        text-transform: uppercase;
        font-weight: 500;
        text-decoration: none;
        white-space: nowrap;
        position: relative;
    }
    .nav-desktop a::after {
        content: "";
        position: absolute;
        left: 0; right: 0; bottom: 0.55rem;
        height: 2px;
        background: var(--accent);
        transform: scaleX(0);
        transform-origin: left;
        transition: transform 0.24s var(--ease);
    }
    .nav-desktop a:hover::after,
    .nav-desktop a[aria-current="true"]::after { transform: scaleX(1); }
    .site-header .header-cta { display: inline-flex; }
}

/* Desktop */
@media (min-width: 62em) {
    /* Back to a grid: there's room for all four/eight at once, and the
       carousel's swipe affordance would be wasted on a mouse. */
    .invite-grid  { display: grid; grid-template-columns: repeat(4, 1fr);
                    overflow-x: visible; scroll-snap-type: none; }
    .invite       { flex: initial; }
    .gallery-grid { display: grid; grid-template-columns: repeat(4, 1fr); align-items: start;
                    overflow-x: visible; scroll-snap-type: none; }
    .gallery-grid figure { flex: initial; }
    .committee-grid { display: grid; grid-template-columns: repeat(3, 1fr); align-items: start; overflow-x: visible; scroll-snap-type: none; }
    .committee-card { flex: initial; }
    .hall-grid    { grid-template-columns: 1.05fr 0.95fr; align-items: start; }
    .drama        { display: grid; grid-template-columns: 1.1fr 0.9fr;
                    align-items: stretch; }
    .drama img    { height: 100%; aspect-ratio: auto; min-height: 22rem; }
    .drama-body   { align-self: center; }
    /* Span both drama grid columns so the gallery sits below picture + copy */
    .drama-gallery { display: grid; grid-template-columns: repeat(3, 1fr);
                     grid-column: 1 / -1;
                     gap: 0.5rem;
                     overflow-x: visible; scroll-snap-type: none;
                     padding: 0 clamp(1.25rem, 4vw, 2rem) clamp(1.25rem, 4vw, 2rem); }
    .drama-gallery figure { flex: initial; cursor: zoom-in; }
    .footer-grid  { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; }
}

@media (min-width: 80em) {
    .hero { max-height: 50rem; }
}

/* --------------------------------------------------------------------------
   17. Preferences & print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .js .reveal { opacity: 1; transform: none; }
}


@media print {
    .site-header, .menu-panel, .to-top, .hero-actions { display: none !important; }
    body { background: #fff; color: #000; }
    .hero { height: auto; min-height: 0; }
}

/* --------------------------------------------------------------------------
   18. FAQ Chatbot
   Keyword-matching venue assistant — no API dependency, fully static.
   Positioned bottom-right (to-top is also right, but only shows when
   scrolled; the FAB is always visible. At <48em they stack — FAB first,
   then the to-top above it when it appears.)
   -------------------------------------------------------------------------- */
.cmh-chat {
    position: fixed;
    right: var(--gutter);
    bottom: calc(1rem + env(safe-area-inset-bottom));
    z-index: 200;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.75rem;
}

.cmh-chat__fab {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    background: var(--accent-text, #800000);
    color: #fff;
    font-size: 1.25rem;
    line-height: 1;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
    transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
    display: flex;
    align-items: center;
    justify-content: center;
}
.cmh-chat__fab:hover,
.cmh-chat__fab:focus-visible {
    transform: translateY(-2px) scale(1.05);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4);
}

.cmh-chat__panel {
    width: min(320px, 85vw);
    max-height: 430px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    font-family: var(--sans, Inter, sans-serif);
}
.cmh-chat__panel[hidden] { display: none; }

.cmh-chat__head {
    background: var(--accent-text, #800000);
    color: #fff;
    padding: 0.75rem 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    flex-shrink: 0;
}
.cmh-chat__close {
    background: none;
    border: none;
    color: #fff;
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
    opacity: 0.85;
}
.cmh-chat__close:hover { opacity: 1; }

.cmh-chat__list {
    flex: 1;
    overflow-y: auto;
    padding: 0.85rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    min-height: 160px;
    scroll-behavior: smooth;
}

.cmh-chat__msg {
    max-width: 86%;
    padding: 0.55rem 0.8rem;
    border-radius: 10px;
    font-size: 0.84rem;
    line-height: 1.45;
}
.cmh-chat__msg--bot {
    align-self: flex-start;
    background: var(--surface, var(--bg));
    color: var(--text);
    border: 1px solid var(--border);
}
.cmh-chat__msg--user {
    align-self: flex-end;
    background: var(--accent-text, #800000);
    color: #fff;
}

.cmh-chat__form {
    display: flex;
    border-top: 1px solid var(--border);
    flex-shrink: 0;
}
.cmh-chat__form input {
    flex: 1;
    border: none;
    padding: 0.75rem 0.9rem;
    font: inherit;
    font-size: 0.84rem;
    background: var(--card);
    color: var(--text);
    outline: none;
}
.cmh-chat__form input::placeholder { color: var(--text-2); opacity: 0.7; }
.cmh-chat__form button {
    border: none;
    background: none;
    color: var(--accent-text, #800000);
    font-size: 1.15rem;
    padding: 0 0.9rem;
    cursor: pointer;
    transition: opacity 0.15s;
}
.cmh-chat__form button:hover { opacity: 0.75; }

/* Stack to-top above the chatbot FAB so they don't overlap */
.to-top { bottom: calc(1rem + env(safe-area-inset-bottom) + 4rem); }


/* Home banner announcing Chowdiah Utsava 2026 (page styles: css/utsava.css) */
.utsava-banner { background: #2e7a78; color: #fff; }
.utsava-banner a { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.35rem 1rem; padding-block: 0.9rem; text-decoration: none; text-align: center; }
.utsava-banner strong { font-family: "Playfair Display", Georgia, serif; font-size: var(--step-1); }
.utsava-banner span { font-size: var(--step--1); }
.utsava-banner__cta { font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; border-bottom: 1px solid currentColor; }
.utsava-banner a:hover .utsava-banner__cta { border-bottom-width: 2px; }
