/* Minimal Phase 3 production component set.
 * Owners: actions.css (actions), library.css (card/filter/accordion/status),
 * layout.css and page-layouts.css (composition and responsive behaviour). */

/* Action / button */
:is(.btn, .lca-button) {
  --action-bg: var(--color-teal);
  --action-fg: var(--color-paper);
  --action-hover-bg: var(--color-ink);
  --action-hover-fg: var(--color-paper);
  --action-edge: transparent;
  box-sizing: border-box;
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--action-height);
  max-width: 100%;
  gap: var(--action-gap);
  padding: var(--action-padding-y) var(--action-padding-x);
  overflow: hidden;
  border: 1px solid var(--action-edge);
  border-radius: 0;
  background: var(--action-bg);
  color: var(--action-fg);
  /* The clip is expanded by the 1px border on all four sides. Clipping exactly on the
     border-box edges means a bordered action never paints its left and right borders (the
     polygon's vertical edges sit on top of them), which left chamfered outlines reading as
     though a whole side were missing. A filled action is unaffected: it has no border to
     reveal, and the 1px of extra clip lies outside the painted box. */
  clip-path: polygon(
    -1px -1px,
    calc(100% - var(--action-chamfer) + 1px) -1px,
    calc(100% + 1px) calc(var(--action-chamfer) - 1px),
    calc(100% + 1px) calc(100% + 1px),
    calc(var(--action-chamfer) - 1px) calc(100% + 1px),
    -1px calc(100% - var(--action-chamfer) + 1px)
  );
  font-family: var(--font-body);
  font-size: var(--action-label-size);
  font-weight: var(--action-label-weight);
  line-height: var(--action-label-leading);
  letter-spacing: var(--action-letter-spacing);
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--duration-hover) var(--easing-emphasis);
}
:is(.btn, .lca-button)::before { content: ''; position: absolute; inset: -50% auto -50% -70%; width: 45%; z-index: -1; background: currentColor; opacity: .04; transform: skewX(-20deg); transition: transform var(--duration-sweep) var(--easing-emphasis); }
:is(.btn, .lca-button):not(:disabled):not([aria-disabled='true']):hover { background: var(--action-hover-bg); color: var(--action-hover-fg); transform: translateY(var(--action-lift)); }
:is(.btn, .lca-button):not(:disabled):not([aria-disabled='true']):hover::before { transform: translateX(430%) skewX(-20deg); }
:is(.btn, .lca-button):focus-visible { outline: 3px solid currentColor; outline-offset: -6px; box-shadow: inset 0 0 0 3px currentColor; text-decoration: underline; }
:is(.btn, .lca-button):is(:disabled, [aria-disabled='true']) { background: var(--action-disabled-bg); color: var(--action-disabled-text); border-color: var(--action-disabled-border); cursor: not-allowed; transform: none; }
.btn-dark { --action-bg: var(--color-ink); --action-hover-bg: var(--color-yellow); --action-hover-fg: var(--color-ink); }
:is(.btn-yellow, .lca-button--emphasis) { --action-bg: var(--color-yellow); --action-fg: var(--color-ink); --action-hover-bg: var(--color-paper); --action-hover-fg: var(--color-ink); }
:is(.btn-light, .lca-button--inverse) { --action-bg: var(--color-paper); --action-fg: var(--color-ink); --action-hover-bg: var(--color-yellow); --action-hover-fg: var(--color-ink); }
.btn-outline { --action-bg: transparent; --action-fg: var(--color-ink); --action-edge: var(--color-ink); --action-hover-bg: var(--color-ink); --action-hover-fg: var(--color-paper); }
.arrow { width: 18px; height: 18px; flex: none; }
:is(.btn, .text-link):not(:has(.arrow))::after { content: '→'; flex: none; font-size: 1rem; line-height: 1; }
.action-group { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* Retained no-JavaScript navigation specimen */
.skip-link { position: fixed; z-index: 100; top: var(--space-3); left: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--color-yellow); color: var(--color-ink); transform: translateY(-180%); }
.skip-link:focus { transform: none; }
.site-header { position: relative; z-index: 30; border-bottom: var(--border); background: var(--color-paper); color: var(--color-ink); }
.header-inner { display: flex; min-height: 5.5rem; align-items: center; justify-content: space-between; gap: var(--space-8); }
.brand { display: block; flex: 0 0 auto; width: 11.5625rem; text-decoration: none; }
.brand img { width: 100%; height: auto; }
.site-nav, .site-nav ul { display: flex; align-items: center; }
.site-nav { gap: clamp(1rem, 2.2vw, 2rem); }
.site-nav ul { gap: clamp(1rem, 1.8vw, 1.75rem); margin: 0; padding: 0; list-style: none; }
.site-nav li { margin: 0; }
.site-nav a:not(.btn) { position: relative; display: block; padding-block: var(--space-4); font-size: .8125rem; font-weight: 550; text-decoration: none; }
.site-nav a[aria-current='page']::after { content: ''; position: absolute; right: 0; bottom: .5rem; left: 0; height: 3px; background: var(--color-coral); }

/* Film poster card */
.film-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3.5rem 1.6rem; }
.poster-card { display: flex; min-width: 0; flex-direction: column; gap: var(--space-3); }
.poster-frame { position: relative; overflow: hidden; aspect-ratio: var(--image-ratio-poster-alternate); background: var(--color-ink); }
.poster-frame img { width: 100%; height: 100%; object-fit: contain; }
.poster-fallback { display: grid; place-items: center; padding: var(--space-6); background: var(--color-mist); color: var(--color-muted); text-align: center; }
.poster-fallback span { font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.poster-card h3 { font-size: clamp(1rem, 1.6vw, 1.35rem); line-height: 1.4; }
.poster-card .director, .screening-meta, .qa-small { font-size: .8125rem; }
.poster-card .director { color: var(--color-muted); }
.screening-meta { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); padding-top: var(--space-3); border-top: var(--border); }
.tag { position: absolute; top: var(--space-3); left: var(--space-3); display: inline-flex; padding: .3rem .6rem; background: var(--color-yellow); color: var(--color-ink); font-size: .69rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }

/* Day filter: native controls, not CTA buttons */
.filter-group { display: flex; flex-wrap: wrap; gap: var(--space-2); border: 0; padding: 0; }
.filter { min-height: 48px; padding: .7rem 1rem; border: 1px solid var(--color-ink); background: var(--color-paper); color: var(--color-ink); font-size: .8125rem; cursor: pointer; }
.filter[aria-pressed='true'] { background: var(--color-ink); color: var(--color-paper); }

/* Programme rows */
.programme-list { border-top: var(--border); }
.event { display: grid; grid-template-columns: 9.0625rem minmax(0, 1fr); border-bottom: var(--border); }
.event-time { padding: var(--space-6) var(--space-4) var(--space-6) 0; font-size: .8125rem; font-weight: 700; }
.event-content { min-width: 0; padding: var(--space-6); border-left: var(--border); }
.event-content .eyebrow { margin-bottom: var(--space-2); }
.event-screening .event-content { display: grid; grid-template-columns: minmax(0, 1fr) 5.5rem; gap: var(--space-6); }
.event-poster { width: 5.5rem; height: 8.25rem; object-fit: contain; background: var(--color-ink); }
.event-qa { background: var(--color-mist); }

/* Unavailable form field specimens */
.form-specimen { display: grid; max-width: 50rem; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.field { display: flex; min-width: 0; flex-direction: column; gap: .45rem; }
.field-wide { grid-column: 1 / -1; }
.field label { font-size: .875rem; font-weight: 600; }
.field :is(input, textarea, select) { width: 100%; min-height: 48px; padding: .75rem; border: 1px solid var(--color-ink); border-radius: 2px; background: var(--color-paper); color: var(--color-ink); }
.field textarea { min-height: 8rem; resize: vertical; }
.field :disabled { border-color: var(--color-line); background: var(--color-mist); color: var(--color-muted); cursor: not-allowed; opacity: 1; }

/* Native no-JS disclosure */
.accordion details { border-top: var(--border); }
.accordion details:last-child { border-bottom: var(--border); }
.accordion summary { display: flex; min-height: 56px; align-items: center; justify-content: space-between; gap: var(--space-4); padding-block: 1.35rem; font-weight: 600; cursor: pointer; }
.accordion summary::after { content: '+'; font-size: 1.5rem; }
.accordion details[open] summary::after { content: '−'; }
.accordion .answer { max-width: 65ch; padding-bottom: 1.35rem; }

/* Truthful unavailable state */
.status-note { max-width: 65ch; padding: var(--space-6); border-left: 4px solid var(--color-teal); background: var(--color-mist); }
.status-note > * + * { margin-top: var(--space-2); }

.component-section { border-top: var(--border); }
.component-label { margin-bottom: var(--space-8); }
.component-meta { color: var(--color-muted); font-size: .875rem; }
.font-fallback-sample { font-family: Georgia, serif; }

@media (max-width: 68.75rem) {
  .film-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 55rem) {
  .header-inner { align-items: flex-start; flex-direction: column; gap: 0; padding-block: var(--space-4); }
  .site-nav { width: 100%; align-items: stretch; flex-direction: column; gap: var(--space-3); }
  .site-nav ul { align-items: stretch; flex-direction: column; gap: 0; }
  .site-nav a:not(.btn) { border-bottom: var(--border); font-size: 1rem; }
  .site-nav a[aria-current='page']::after { right: 0; bottom: 1.4rem; left: auto; width: 1.5rem; }
  .site-nav .btn { align-self: flex-start; }
}
@media (max-width: 50rem) { .film-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.5rem 1rem; } }
@media (max-width: 36.25rem) {
  .event { grid-template-columns: 1fr; }
  .event-time { padding-bottom: 0; }
  .event-content { padding-inline: 0; border-left: 0; }
  .event-screening .event-content { grid-template-columns: minmax(0, 1fr) 4.375rem; gap: var(--space-4); }
  .event-poster { width: 4.375rem; height: 6.5625rem; }
  .form-specimen { grid-template-columns: 1fr; }
  .field-wide { grid-column: auto; }
}
@media (max-width: 21.25rem) { .film-grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { :is(.btn, .lca-button), :is(.btn, .lca-button)::before { transform: none !important; } :is(.btn, .lca-button)::before { display: none; } }
@media (forced-colors: active) { :is(.btn, .lca-button) { clip-path: none; border: 2px solid ButtonText; background: ButtonFace; color: ButtonText; } }

/* Shared site shell: icon-only menu control, off-canvas navigation panel, grouped footer.
 * Menu state (aria-expanded plus .is-open on the navigation) is owned by site.js; the panel
 * geometry, the scrim and the focus/scroll handling only reflect that state. Everything the
 * panel needs is scoped to `.js` and to the mobile breakpoint, so without JavaScript the
 * navigation still renders inline exactly as before. */
.menu-toggle { display: none; min-height: 48px; align-items: center; gap: .65rem; padding: .7rem .9rem; border: 1px solid var(--color-ink); background: transparent; color: var(--color-ink); cursor: pointer; }

/* Borderless control: no tile, no fill, no box. Three 1px rails 6px apart read as a menu at a
   glance; 1px rather than the documented 1.5px icon stroke because at this mark size 1.5px
   reads heavy and rounds to 2px at common pixel ratios. Open, the middle rail retires and the
   outer two cross into a mark. The whole 48px square stays the hit area. */
.js .menu-toggle {
  position: relative;
  z-index: 90;
  width: 48px;
  height: 48px;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--color-ink);
  cursor: pointer;
  transition: color var(--duration-hover) var(--easing-emphasis);
}
.js .menu-toggle:focus-visible { outline: 3px solid currentColor; outline-offset: -6px; }
.js .menu-icon { position: relative; display: block; width: 22px; height: 1px; border: 0; background: currentColor; }
.js .menu-icon::before,
.js .menu-icon::after { content: ''; position: absolute; left: 0; width: 22px; height: 1px; background: currentColor; transition: transform var(--duration-hover) var(--easing-emphasis); }
.js .menu-icon::before { top: -6px; }
.js .menu-icon::after { top: 6px; }
/* Hide only the middle rail's own paint: opacity here would group and take the crossed rails
   with it. */
.js .menu-toggle[aria-expanded='true'] .menu-icon { background: none; transform: none; }
.js .menu-toggle[aria-expanded='true'] { color: var(--color-paper); }
.js .menu-toggle[aria-expanded='true'] .menu-icon::before { top: 0; transform: rotate(45deg); }
.js .menu-toggle[aria-expanded='true'] .menu-icon::after { top: 0; transform: rotate(-45deg); }

/* Approved multicolour strip: closes the Home opening composition and the global footer. */
.approved-colour-strip { display: block; width: 100%; height: clamp(20px, 2.9vw, 56px); flex: 0 0 auto; object-fit: fill; }
.footer-colour-strip { height: .5rem; }

.site-footer { padding-top: 3.5rem; border-top: var(--border); background: var(--color-paper); color: var(--color-ink); }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2.5rem; padding-bottom: var(--space-12); }
.footer-grid > * { min-width: 0; }
/* The brand takes its own masthead row, so all four column titles start on one line and the
   logo no longer pushes "Past years" below the other headings. */
.footer-masthead { grid-column: 1 / -1; margin-bottom: var(--space-4); }
.footer-brand { width: 11.5625rem; max-width: 100%; margin-bottom: var(--space-8); }
.footer-column { min-width: 0; }
.footer-newsletter { min-width: 0; }
.footer-title { margin-bottom: var(--space-4); font-size: .75rem; font-weight: 650; letter-spacing: .1em; text-transform: uppercase; }
h2.footer-title { font-family: var(--font-body); line-height: var(--leading-body); text-wrap: wrap; }
.footer-subtitle { margin-top: var(--space-6); }
.archive-years { display: grid; max-width: 14.375rem; grid-template-columns: repeat(auto-fit, minmax(3rem, 1fr)); gap: var(--space-2); }
/* Past years as quiet chamfered chips: still actions, no longer the loudest thing here. The
   clip is expanded by the border width so all four hairline borders paint. */
.archive-years a {
  display: flex;
  min-height: 40px;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(16, 16, 16, .34);
  border-radius: 0;
  color: var(--color-ink);
  font-size: .75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  text-decoration: none;
  clip-path: polygon(
    -1px -1px,
    calc(100% - 7px) -1px,
    calc(100% + 1px) 7px,
    calc(100% + 1px) calc(100% + 1px),
    7px calc(100% + 1px),
    -1px calc(100% - 7px)
  );
  transition: background-color var(--duration-hover) var(--easing-emphasis), color var(--duration-hover) var(--easing-emphasis), border-color var(--duration-hover) var(--easing-emphasis);
}
.archive-years a:is(:hover, :focus-visible) { border-color: var(--color-ink); background-color: var(--color-ink); color: var(--color-paper); }
.footer-links { display: grid; align-items: start; gap: var(--space-2); }
.footer-links a, .legal-links a { align-items: center; }
.footer-links a { display: inline-flex; min-height: 30px; font-size: .8rem; }

/* Icon-only profile links, shared by the footer and the Home conversation band. */
.social-live { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.social-live-link { display: inline-flex; width: 44px; height: 44px; align-items: center; justify-content: center; border-radius: 50%; color: currentColor; transition: background-color var(--duration-hover) var(--easing-emphasis); }
.social-live-link svg { display: block; width: 21px; height: 21px; fill: currentColor; }
.social-live-link:is(:hover, :focus-visible) { background-color: rgba(16, 16, 16, .1); }
/* Lighter in the footer: the glyphs stay legible but stop outweighing the text links. */
.site-footer .social-live { gap: 0; margin-top: var(--space-1); }
.site-footer .social-live-link { width: 34px; height: 34px; }
.site-footer .social-live-link svg { width: 17px; height: 17px; }

/* Newsletter signup. The heading, body, field and action are unchanged from the accepted
   design; the connection lives in the footer partial's form element, which is gated by
   data-form-active until the CRM team confirms the endpoint is live. */
.footer-newsletter-body { max-width: 34ch; font-size: .82rem; line-height: 1.6; }
.footer-newsletter-field { margin-top: var(--space-4); }
.newsletter-control {
  display: flex;
  align-items: center;
  padding: 4px;
  border: 1px solid var(--color-ink);
  background: var(--color-paper);
  clip-path: polygon(
    -1px -1px,
    calc(100% - 11px) -1px,
    calc(100% + 1px) 11px,
    calc(100% + 1px) calc(100% + 1px),
    11px calc(100% + 1px),
    -1px calc(100% - 11px)
  );
}
/* The wrapper carries the focus ring, because a clipped container would crop a ring drawn on
   the input itself. */
.newsletter-control:focus-within { outline: 3px solid currentColor; outline-offset: -6px; }
.newsletter-control input { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: .5rem .75rem; border: 0; border-radius: 0; background: transparent; color: var(--color-ink); font: inherit; font-size: .85rem; }
.newsletter-control input::placeholder { color: var(--color-muted); }
.newsletter-control input:focus-visible { outline: none; }
.newsletter-submit { flex: 0 0 auto; width: 44px; height: 44px; min-height: 44px; padding: 0; --action-chamfer: 8px; }
.footer-newsletter-state, .footer-newsletter-consent { margin-top: var(--space-4); color: var(--color-muted); font-size: .7rem; line-height: 1.6; }
.footer-newsletter-consent a { color: inherit; font-weight: 550; }

.footer-bottom { display: flex; align-items: center; justify-content: space-between; gap: var(--space-6); padding-block: var(--space-6); border-top: var(--border); font-size: .72rem; }
.legal-links { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.legal-links a { display: inline-flex; min-height: 30px; }

/* Scroll reveals. The hidden state is applied BY SCRIPT (`.reveal-item`); nothing is hidden
   in the markup, so without JavaScript — and under reduced motion — every section is simply
   present. Only opacity and transform animate, so a reveal can never cause layout shift. */
.reveal-item {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition:
    opacity var(--duration-reveal) var(--easing-emphasis),
    transform var(--duration-reveal) var(--easing-emphasis);
  transition-delay: var(--reveal-delay, 0ms);
}
.is-revealed .reveal-item { opacity: 1; transform: none; }

@media (min-width: 66.3125rem) {
  .footer-grid { grid-template-columns: 1.15fr .72fr .72fr 1.15fr; }
  .archive-years { max-width: 21rem; grid-template-columns: repeat(auto-fit, minmax(4rem, 1fr)); }
}

@media (max-width: 66.25rem) {
  .brand { width: 10rem; }
  .header-inner, .site-nav { gap: 1.2rem; }
  .site-nav ul { gap: var(--space-4); }
  .footer-grid { gap: var(--space-6); }
}
@media (max-width: 55rem) {
  .header-inner { flex-wrap: wrap; min-height: 5.125rem; align-items: center; flex-direction: row; justify-content: space-between; padding-block: 1.1rem; }
  .site-header .brand { max-width: calc(100% - 110px); width: 10.5rem; }
  .js .menu-toggle { display: inline-flex; }
  .site-nav { width: 100%; align-items: stretch; flex-direction: column; gap: var(--space-3); padding-block: var(--space-4); }
  .site-nav ul { align-items: stretch; flex-direction: column; gap: 0; }
  .site-nav a:not(.btn) { border-bottom: var(--border); font-size: 1rem; }
  .site-nav a[aria-current='page']::after { right: 0; bottom: 1.4rem; left: auto; width: 1.5rem; }
  .site-nav .btn { align-self: flex-start; }

  /* The navigation leaves the header's flow entirely and arrives as an ink panel from the
     right over a scrim. `visibility` (not display) keeps it out of the tab order while closed
     and still lets the 420ms slide run. */
  .js .site-nav {
    position: fixed;
    z-index: 80;
    top: 0;
    right: 0;
    bottom: 0;
    left: auto;
    display: flex;
    width: min(22rem, 88vw);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 5.75rem 1.75rem 2rem;
    overflow-y: auto;
    background: var(--color-ink);
    color: var(--color-paper);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 420ms var(--easing-emphasis), visibility 0s linear 420ms;
  }
  .js .site-nav.is-open { transform: translateX(0); visibility: visible; transition: transform 420ms var(--easing-emphasis), visibility 0s; }
  .js .site-nav ul { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; }
  .js .site-nav a:not(.btn) { display: block; padding-block: 1.05rem; border-bottom: 1px solid rgba(254, 254, 254, .18); color: var(--color-paper); font-size: 1.0625rem; font-weight: 550; text-decoration: none; }
  .js .site-nav a[aria-current='page']::after { display: none; }
  .js .site-nav a[aria-current='page'] { color: var(--color-yellow); }
  .js .site-nav .btn { align-self: stretch; margin-top: 1.75rem; }

  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-8); }
  /* Nine year chips and the newsletter need the full width once the grid is two columns. */
  .footer-column--archive,
  .footer-newsletter { grid-column: 1 / -1; }
  .footer-newsletter-body { max-width: 44ch; }
  .archive-years { max-width: 100%; grid-template-columns: repeat(auto-fit, minmax(4rem, 1fr)); }
}
/* The header stays above the panel so the now-crossed control can close it. */
.is-menu-open .site-header { position: relative; z-index: 100; }
/* Scrim over the page, and no background scrolling while the panel is out. */
.is-menu-open::before { content: ''; position: fixed; z-index: 70; inset: 0; background: rgba(16, 16, 16, .55); }
.is-menu-open { overflow: hidden; }

@media (max-width: 28.125rem) {
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-8) var(--space-4); }
  .footer-bottom { align-items: flex-start; flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
  .js .site-nav, .js .menu-icon::before, .js .menu-icon::after, .social-live-link, .archive-years a { transition: none; }
  .reveal-item { opacity: 1; transform: none; transition: none; }
}
@media (forced-colors: active) {
  .menu-toggle, .archive-years a { border: 2px solid ButtonText; }
}
@media print {
  .site-nav, .menu-toggle, .site-footer { display: none !important; }
  .site-header { position: static !important; }
  /* A printed page has no observer, so nothing may stay hidden waiting for one. */
  .reveal-item { opacity: 1; transform: none; }
}
