/* Kinopanorama — our styles. Linked last on every page, so these win.
   Never regenerated by the pipeline; design work goes here. */

/* Backstop for the "Made in Webflow" badge (customise.py removes its trigger). */
.w-webflow-badge { display: none !important; }

/* --- Colours ------------------------------------------------------------------
   Light site: the template's two neutrals are swapped and recoloured, so every
   "dark" surface becomes light #F9F8F3 and every "light" text, logo and line
   becomes dark #171616. Declared on :root AND body — Webflow re-declares the
   tokens on body inside its breakpoints (see TOKENS.md).
   Three places keep the template's original mapping, in the new colours:
   the footer (dark #171616 band, light #F9F8F3 type), the text on the
   featured-work photos, and the yellow contact section (dark type on yellow).
   Footer and card text inherited their colour from body, so it is set here
   explicitly; the yellow section sets its own from the tokens. */
:root, body {
  --swatch--neutral-dark: #F9F8F3;
  --swatch--neutral-light: #171616;
  --body--background: var(--swatch--neutral-dark);
  --body--color: var(--swatch--neutral-light);
}
footer.section, .featured-work_content-wrapper, .section-primary {
  --swatch--neutral-dark: #171616;
  --swatch--neutral-light: #F9F8F3;
}
footer.section, .featured-work_content-wrapper { color: var(--swatch--neutral-light); }
footer.section { background-color: var(--swatch--neutral-dark); }

/* --- Logo ------------------------------------------------------------------
   tools/brand.py swaps the template's "FH" / "FRAMEHAUS" text for the
   Kinopanorama wordmark (inline SVG, ink = currentColor, so each animation
   layer keeps its template colour). The wordmark is 93 x 13 — very wide
   and low — so its boxes are widened here: about 29px tall in the
   header and footer mark, about 12cqw in the big ones (full template letter
   height would be wider than the screen). */
.kp-logo { display: block; width: 100%; height: auto; }

/* Header + footer mark: the box was a 54px / 60px square for "FH". */
.logo-link { max-width: 13rem; flex: none; width: 13rem; }
.logo-wrapper.is-layer1.is-footer { min-width: 13rem; max-width: 13rem; }
.logo { width: 100%; line-height: 0; padding-block: .3125rem; }

/* Home hero + footer base: "FRAMEHAUS" was 15.75cqw type. */
.hero_heading { line-height: 0; padding-block: 2.5cqw; }
.hero_heading .kp-logo { width: 84cqw; margin-inline: auto; }
/* Home hero: half that size. */
.hero_heading-wrapper .kp-logo { width: 42cqw; }
/* Phones: 40% bigger, it read too small; then 30% more (2026-10-19). */
@media screen and (max-width: 767px) { .hero_heading-wrapper .kp-logo { width: 76.44cqw; } }
/* Footer wordmark: 24px lower, so its bottom runs off the page edge (the footer crops it). */
.footer_heading-wrapper .kp-logo { transform: translateY(1.5rem); }

/* No "echo": the template slides copies of the big wordmark out above and
   below it (layers 2 + 3); they don't suit this logo. They are absolutely
   positioned, so hiding them leaves the layout as it was. */
.hero_heading-wrapper.is-layer2, .hero_heading-wrapper.is-layer3,
.footer_heading-wrapper.is-layer2, .footer_heading-wrapper.is-layer3 { display: none; }

/* --- Header: no logo, three links spread across ---------------------------
   The wordmark is gone from the top bar (the footer keeps its own). The links
   sit in three columns: About on the left edge, Partnerships in the centre,
   Contact on the right edge. `order` also sets the phone menu's order.
   min-height keeps the bar as tall as it was with the logo in it. */
.nav .logo-link { display: none; }
.nav_container.container { min-height: 4.125rem; }
.nav .nav-menu a[href$="about.html"], .nav .nav-menu a[data-href$="about.html"] { order: 1; }
.nav .nav-menu a[href$="services.html"], .nav .nav-menu a[data-href$="services.html"],
.nav .nav-menu a[href="#partnerships"] { order: 2; }
.nav .nav-menu a[href$="contact.html"], .nav .nav-menu a[data-href$="contact.html"] { order: 3; }
@media screen and (min-width: 480px) {
  .nav .nav-menu {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
  }
  .nav .nav-link.is-nav { margin: 0; }
  .nav .nav-menu a[href$="services.html"], .nav .nav-menu a[data-href$="services.html"],
  .nav .nav-menu a[href="#partnerships"] {
    justify-self: center;
  }
  .nav .nav-menu a[href$="about.html"], .nav .nav-menu a[data-href$="about.html"] {
    justify-self: start; padding-left: 0;
  }
  .nav .nav-menu a[href$="contact.html"], .nav .nav-menu a[data-href$="contact.html"] {
    justify-self: end; padding-right: 0;
  }
}
/* Inner pages (tools/pages.py) add Home: four links spread evenly, Home on
   the left edge, Contact on the right; Home is also first in the phone menu. */
.nav .nav-menu.kp-has-home a[href$="index.html"] { order: 0; }
@media screen and (min-width: 480px) {
  .nav .nav-menu.kp-has-home { display: flex; justify-content: space-between; }
  .nav .nav-menu.kp-has-home a[href$="index.html"] { padding-left: 0; }
}
/* Phones: the open menu is a plain block, which ignores `order` — make it a
   column so it lists the links in the desktop order. Its "Close" label was
   white on the light page; it takes the menu's dark ink instead. */
.w-nav-overlay .nav-menu[data-nav-menu-open] { display: flex !important; flex-direction: column; gap: 0; }   /* Webflow sets block !important; its gap only applies once it is flex */
.nav .menu-text_label-2 { color: var(--swatch--neutral-light); }
/* Phones: with the logo gone, keep the Menu button on the right. */
.nav .nav-menu_button { margin-left: auto; }

/* Menu hover (header + footer): a 1.5px underline draws in from the left
   (ease-in) instead of the template's yellow text — black in the header,
   the footer's own light colour there. The line is a background clipped to
   the text box, so the links' side padding doesn't stretch it; only
   background-size animates — a tiny repaint, nothing on scroll. The current
   page shows the finished state. */
.nav-link.is-footer {
  background: linear-gradient(currentColor, currentColor) no-repeat left bottom / 0 1.5px;
  background-origin: content-box;
  background-clip: content-box;
  padding-bottom: .25rem;
  transition: background-size .3s ease-in;
}
.nav-link.is-footer:hover, .nav-link.is-footer:focus-visible, .nav-link.is-footer.w--current {
  color: inherit;
  background-size: 100% 1.5px;
}
.nav .nav-link.is-nav {
  background: linear-gradient(#000000, #000000) no-repeat left bottom / 0 1.5px;
  background-origin: content-box;
  background-clip: content-box;
  padding-bottom: .25rem;
  transition: background-size .3s ease-in, color .3s ease-in;
}
.nav .nav-link.is-nav:hover, .nav .nav-link.is-nav:focus-visible, .nav .nav-link.is-nav.w--current {
  color: #000000;
  background-size: 100% 1.5px;
}
@media (prefers-reduced-motion: reduce) {
  .nav .nav-link.is-nav, .nav-link.is-footer, .menu-text, .social-link { transition: none; }
}

/* --- No yellow hovers ----------------------------------------------------------
   The template turns things yellow on hover / current page. Yellow stays only
   as the contact sections' background. Elsewhere:
   - the phone "Menu" button and the footer social icons fade a little;
   - form-field hover borders and keyboard-focus rings go dark;
   - the password page's buttons are dark instead of yellow. */
.menu-text, .social-link { transition: opacity .3s ease-in; }
.menu-text:hover, .menu-text.w--current,
.social-link:hover, .social-link.w--current { color: inherit; opacity: .6; }
:root, body { --swatch--utility-focus: #171616; }
.btn { border-color: #171616; color: #171616; }
.btn:hover { background-color: #171616; color: #F9F8F3; }
.btn.btn-submit { background-color: #171616; color: #F9F8F3; }
.btn.btn-submit:hover { background-color: transparent; color: #171616; }

/* Header menu: 16px at every width (template 12px). */
.nav .nav-link.is-nav { font-size: 1rem; }

/* Featured-card review quotes: 16px on 20px lines, 14px on 18px lines on
   phones (template 18 / 16px at 1.7). The source line under each quote is
   unchanged (12px). */
.featured-work_review-wrapper .paragraph-lg { font-size: 1rem; line-height: 1.25rem; }
@media screen and (max-width: 479px) {
  .featured-work_review-wrapper .paragraph-lg { font-size: .875rem; line-height: 1.125rem; }
}

/* --- Featured work: cards with a light photo --------------------------------
   The template's card text is light, written for dark photos. On a light
   photo the left column (year, award, type, title, director) switches to the
   template's dark; the right column (reviews, Explore) stays light.
   Add a photo here when another light one goes into a card. */
.work-feature_card:has(img[src*="andrey-zyvagintsev"]) .featured-work_content-row:first-child {
  color: var(--swatch--neutral-dark);
}
/* Gaspar Noé: the photo is light edge to edge, so the whole card goes dark,
   Explore included (the template sets its colour on the button itself). */
.work-feature_card:has(img[src*="gaspar-noe"]) .featured-work_content-wrapper,
.work-feature_card:has(img[src*="gaspar-noe"]) .text-button {
  color: var(--swatch--neutral-dark);
}

/* --- Featured work: the whole card is the link ---------------------------------
   A director card with a page (its Explore button has a real href) is
   clickable anywhere: the button's link is stretched over the card through
   its ::after, sized by the card's text layer (position: relative, z-index
   10, full card). Hovering anywhere shows the button's own hover state. */
.featured-work_content-wrapper a.text-button[href]:not([href="#"])::after {
  content: ""; position: absolute; inset: 0;
}

/* --- Featured work: long titles ---------------------------------------------
   The template sizes card titles by breakpoint (80 / 64 / 32px), which suits
   short titles like "FEVER COAST". A long word ("ZVYAGINTSEV") ran past the
   card edge between ~480 and ~990px. The title keeps the template's size but
   is capped at 12.5% of the text column's width, so the longest word always
   fits. The cap only bites between ~480 and ~760px, where all three card
   titles drop from 64px to ~43px together; desktop (80px) and phones (32px)
   keep the template's sizes. */
.featured-work_content-wrapper { container-type: inline-size; }
/* Names 20% bigger than the template's sizes (2026-10-19): 96 / 77 / 38px,
   cap 15% of the column. */
.featured-work_heading-wrapper .heading-4xl {
  font-size: min(calc(var(--_responsive---heading-4xl--font-size) * 1.2), 15cqi);
}
/* The template caps the title box at 34rem (544px); 20% wider to match, or
   "ZVYAGINTSEV" at 96px runs past it. */
.featured-work_heading-wrapper { max-width: 40.8rem; }

/* --- Staging (for now) -------------------------------------------------------
   tools/staging.py hides sections with the `hidden` attribute and switches
   links off (href -> data-href). Webflow's own display rules would beat the
   browser's [hidden]; and some template buttons force a pointer cursor. */
[hidden] { display: none !important; }
a[aria-disabled="true"] { cursor: default; }
/* Home Partnerships: in the template it sat under the sticky title and
   relied on it for top spacing. That section is deleted (tools/prune.py), so
   it gets the template's large top padding itself (136px desktop, 80px phone). */
section[hidden] + section > .container,
.section:has(#partnerships) > .container { padding-top: var(--_responsive---padding-vertical--lg); }

/* Keeps a word with a hyphen ("Oscar-nominated") from splitting across lines. */
.kp-nowrap { white-space: nowrap; }

/* Menu "Partnerships" jumps here; the fixed top bar must not cover the heading. */
#partnerships { scroll-margin-top: 6rem; }

/* --- Section heading: "Partnerships" ----------------------------------------
   Longer than the template's "Services", so on screens ~480–760px wide the
   template's 64px ran off the edge. Capped at 10.5% of the screen width;
   desktop (80px) and phones (32px) keep the template's sizes. */
.service_heading-wrapper .heading-4xl {
  font-size: min(var(--_responsive---heading-4xl--font-size), 10.5vw);
}

/* --- Featured work: photo crops ----------------------------------------------
   Cards are 16:9 on desktop and fill by cropping. A portrait photo shows only a
   horizontal band, so centre that band on the subject instead of the middle.
   Gaspar Noé: set for the earlier 800x1200 portrait; the photo is now a
   1800x1200 landscape, where this still keeps the face in frame. */
.featured-work_image[src*="gaspar-noe"] { object-position: 50% 69%; }

/* --- Permanent Marker -------------------------------------------------------
   Home: the two featured names (Andrey Zvyagintsev, Gaspar Noé); director
   pages: the name in the big hero heading (all its animation layers).
   Self-hosted, css/webfonts.css; the class is added by rewrite-content.py.
   The face has one weight, so 400 avoids a faked bold; the template's
   tracking is dropped — spaced-out marker strokes stop reading as
   handwriting. Sizes stay the template's. */
.kp-marker, .kp-page-guest .work-hero_heading {
  font-family: 'Permanent Marker', var(--font--primary-family), cursive;
  font-weight: 400;
  letter-spacing: normal;
}

/* Home cards: several awards / nominations stack, one per line. */
.featured-work_date-wrapper.kp-highlights { flex-direction: column; align-items: flex-start; flex-wrap: nowrap; }

/* "Great cinema. In person." — template Satoshi style, just bigger. */
.title_heading.kp-title { font-size: 1.5rem; }   /* 24px */
@media screen and (max-width: 767px) {
  .title_heading.kp-title { font-size: calc(var(--size--16px) * 1.25); }   /* 20px */
}
@media screen and (max-width: 479px) {
  .title_heading.kp-title { font-size: calc(var(--size--12px) * 1.25); }   /* 15px */
}

/* --- Scroll progress ----------------------------------------------------------
   A 4px (6px on phones) #171616 bar fixed to the top edge that grows left → right as the page
   scrolls. It sits over the sticky (light) header, so it always shows.
   Only `transform` changes, so the browser can move it without repainting the
   page. Where CSS scroll-linked animation exists (Chrome, Edge, Safari 26+)
   the browser drives it with no script at all; elsewhere js/custom.js sets
   --kp-scroll once per frame while scrolling. */
body::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: #171616;
  transform-origin: 0 50%;
  transform: scaleX(var(--kp-scroll, 0));
  z-index: 2001;   /* above the header and the open phone menu */
  pointer-events: none;
}
@media screen and (max-width: 767px) { body::before { height: 6px; } }   /* phones */
@keyframes kp-scroll { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@supports (animation-timeline: scroll()) {
  body::before {
    animation: kp-scroll linear both;
    animation-timeline: scroll(root block);
  }
}

/* --- Contact form: taller message box -----------------------------------------
   The template's textarea is two lines high. Start it at 12rem (192px); people
   can still drag it taller. */
textarea.field { min-height: 12rem; resize: vertical; }

/* --- Partnerships: logos next to each category name ---------------------------
   On desktop the name and its partner logos sit on one line; on narrower
   screens the logos go under the name. Logos are the partners' own artwork (white / grey for a
   dark band), shown as images at one shared height. */
.sevice_item-title-wrapper.kp-partner-row {
  flex-flow: column;
  align-items: flex-start;
  align-self: center;
  max-width: none;
}
/* The category name's line box is taller than its letters; trim it so the
   name centres on the logos by its letters, not by its line height. */
.kp-partner-row > div:first-child { line-height: 1; }
/* Category names: 32px (template 40px), 24px on small tablets, 16px on phones. */
.sevice_item-title-wrapper.kp-partner-row { font-size: 2rem; }
@media screen and (max-width: 767px) { .sevice_item-title-wrapper.kp-partner-row { font-size: 1.5rem; } }
@media screen and (max-width: 479px) { .sevice_item-title-wrapper.kp-partner-row { font-size: 1rem; } }
/* Each group starts under the "N" of the PARTNERSHIPS heading. The heading
   sits in a centred 70.625rem box; its N starts 2.612 x the heading's font
   size in from the box edge (Satoshi, all caps, at every width). */
.service_list-item:has(.kp-partner-row) {
  padding-left: calc(max(0px, (100% - 70.625rem) / 2)
    + 2.612 * min(var(--_responsive---heading-4xl--font-size), 10.5vw));
}
.kp-partner-logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem 2rem;
}
.kp-partner-logo { display: block; height: 3rem; width: auto; }
@media screen and (max-width: 767px) {
  .kp-partner-logo { height: 2.25rem; }
  .kp-partner-logos { gap: 1rem 1.5rem; }
}
/* Desktop: name and logos on one line. The name gets one fixed-width slot
   (fits "Institutions") so every row's logos start on the same line. Narrower
   screens keep the logos under the name on every row. */
@media screen and (min-width: 1200px) {
  .sevice_item-title-wrapper.kp-partner-row { flex-flow: row; align-items: center; column-gap: 2.5rem; }
  .kp-partner-row > div:first-child { flex: 0 0 15rem; }
}
/* Media logos (BNT, KINO, L'Europeo) are wide, so they read 20% smaller. */
.kp-partner-logo.is-bnt, .kp-partner-logo.is-kino-magazine, .kp-partner-logo.is-leuropeo { height: 2.4rem; }
@media screen and (max-width: 767px) {
  .kp-partner-logo.is-bnt, .kp-partner-logo.is-kino-magazine, .kp-partner-logo.is-leuropeo { height: 1.8rem; }
}
/* NAFTA: its small lettering reads 15% bigger (35% on phones). */
.kp-partner-logo.is-natfa { height: 3.45rem; }
@media screen and (max-width: 767px) { .kp-partner-logo.is-natfa { height: 3.0375rem; } }
/* Sofia coat of arms: tall and detailed, so it reads about 20% bigger. */
.kp-partner-logo.is-sofia { height: 3.625rem; }
@media screen and (max-width: 767px) { .kp-partner-logo.is-sofia { height: 2.75rem; } }

/* --- Pages: Andrey Zvyagintsev + About Us (tools/pages.py) --------------------
   Built from the template's sections; these rules only add what it lacks. */

/* Image placeholder: a soft tint of the text colour, works on light and dark. */
.kp-placeholder {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  border-radius: var(--radius--lg);
  background-color: color-mix(in srgb, currentColor 7%, transparent);
}
.kp-placeholder > .label { opacity: .55; }
.kp-placeholder.is-wide { aspect-ratio: 16 / 9; height: auto; }

/* Guest pages: names are long, so the hero heading is smaller than the
   template's 15cqw (which would run edge to edge). pages.py sets --kp-hero
   from the name's length (Andrey Zvyagintsev: 10.5cqw). */
.kp-page-guest .work-hero_heading { font-size: var(--kp-hero, 10.5cqw); }
/* No "echo": the copies of the name that slide out below it (layers 2 + 3). */
.kp-page-guest .work-hero_heading-wrapper.is-layer2,
.kp-page-guest .work-hero_heading-wrapper.is-layer3 { display: none; }

/* First edition: text beside the photo. The text is long, so on wide screens
   the photo stays in view (position: sticky, no script) while it scrolls. */
.kp-bio .split_wrapper { align-items: start; max-width: 70.625rem; margin-inline: auto; }   /* same width as the sections below */
@media screen and (min-width: 992px) {
  .kp-bio .split_slot:last-child { position: sticky; top: 6rem; }
}
.kp-bio .copy_wrapper p { margin: 0; }
.kp-bio_image { aspect-ratio: 3 / 2; display: block; }

/* Films: one block per film, a line above, then year, title, award, carousel. */
.kp-film-list {
  max-width: 70.625rem; margin-inline: auto;
  display: flex; flex-direction: column; gap: var(--_responsive---gap--xl);
}
.kp-film_head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  column-gap: 1.5rem; row-gap: .5rem; padding-top: 1.5rem;
}
.kp-film_award { flex-basis: 100%; }
/* Films: the year/title/award block, with a festival logo on the right. */
.kp-films .kp-film_head { flex-wrap: nowrap; justify-content: space-between; align-items: center; column-gap: 2rem; }
.kp-film_text { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 1.5rem; row-gap: .5rem; }
.kp-festival { display: flex; align-items: center; gap: 1rem; flex: none; }
.kp-festival_award { font-size: .875rem; line-height: 1.125rem; text-align: right; white-space: nowrap; }   /* 14px, lines 18px apart; breaks set in pages.py */
.kp-festival-logo { display: block; height: 2.6875rem; width: auto; flex: none; }   /* 43px, was 61 */
/* Phones and small tablets (2026-10-19): no festival logo — the award text
   alone, on the right of the row; the title goes under the year. */
@media screen and (max-width: 767px) {
  .kp-festival-logo { display: none; }
  .kp-films .kp-film_head { column-gap: 1rem; align-items: center; }
  .kp-film_text { flex-direction: column; align-items: flex-start; row-gap: .25rem; }
  .kp-festival { flex: none; }
}
@media screen and (max-width: 479px) {
  .kp-festival_award { font-size: .75rem; line-height: 1rem; }   /* 12px, lines 16px apart */
}
/* Film titles: as typed (not all caps), letters 2px tighter at 56px (scales with size). */
.kp-film_title { letter-spacing: -.0357em; }
/* The template's 2xl heading is too wide for "The Banishment" on small screens. */
@media screen and (max-width: 767px) { .kp-film_head .heading-2xl { font-size: var(--size--40px); } }
@media screen and (max-width: 479px) { .kp-film_head .heading-2xl { font-size: var(--size--32px); } }

/* Carousel: native horizontal scroll that snaps to each image (swipe, trackpad,
   arrow keys), the next image peeking in. Buttons + counter: js/custom.js. */
.kp-carousel { margin-top: 1.5rem; }
.kp-carousel_track {
  display: flex; gap: 1.5rem;
  overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.kp-carousel_track::-webkit-scrollbar { display: none; }
.kp-carousel_slide {
  flex: 0 0 min(85%, 56rem); aspect-ratio: 16 / 9;
  scroll-snap-align: start; border-radius: var(--radius--lg); overflow: hidden;
}
/* The event: the photos are 3:2 (camera), so its frames are too. */
.kp-event .kp-carousel_slide { aspect-ratio: 3 / 2; }
.kp-carousel_image { display: block; width: 100%; height: 100%; object-fit: cover; }
.kp-carousel_nav { display: flex; align-items: center; gap: 1rem; margin-top: 1rem; }
.kp-carousel_button {
  display: grid; place-items: center; width: 3rem; height: 3rem;
  border: 2px solid currentColor; border-radius: 50%;
  background: transparent; color: inherit; font-size: 1.25rem; cursor: pointer;
  transition: opacity .2s;
}
.kp-carousel_button:disabled { opacity: .25; cursor: default; }
.kp-carousel_button:focus-visible, .kp-carousel_track:focus-visible {
  outline: 2px solid currentColor; outline-offset: 4px;
}

/* Read by screen readers, not shown (About Us page title). */
.kp-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* About Us: lead paragraphs, then the team as rows (name | text). */
.kp-lead {
  max-width: 56rem; margin: 0 auto;
  font-size: var(--size--32px); line-height: 1.3;
}
.kp-lead.is-closing { text-align: center; }
.kp-team {
  max-width: 70.625rem; margin-inline: auto;
  display: flex; flex-direction: column; gap: 3rem;
}
.kp-team > .kp-lead { margin: 0; }
.kp-person_row { display: grid; grid-template-columns: 1fr 2fr; gap: 2rem; padding-top: 1.5rem; }
.kp-person_row .label { margin-top: .75rem; opacity: .7; }
.kp-person_row .paragraph-lg { margin: 0; }
@media screen and (max-width: 767px) {
  .kp-lead { font-size: var(--size--24px); }
  .kp-person_row { grid-template-columns: 1fr; gap: 1rem; }
}
@media screen and (max-width: 479px) {
  .kp-lead { font-size: 1.25rem; }
}

/* Interview video (tools/pages.py video(), js/custom.js "Video"): the cover
   with a round play button; the YouTube player replaces it on click. */
.kp-video {
  position: relative; aspect-ratio: 16 / 9; margin-top: 1.5rem;
  border-radius: var(--radius--lg); overflow: hidden; background-color: #171616;
}
.kp-video_cover, .kp-video iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
.kp-video_cover { object-fit: cover; }
.kp-video_play {
  position: absolute; inset: 0; display: grid; place-items: center;
}
.kp-video_play > span {
  width: 5.5rem; height: 5.5rem; border-radius: 50%;
  background-color: rgb(23 22 22 / .75); border: 2px solid #F9F8F3;
  transition: transform .2s ease-out, background-color .2s ease-out;
}
/* The triangle: a CSS shape, nudged right so it looks centred. */
.kp-video_play > span::after {
  content: ""; display: block; margin: 1.9rem 0 0 2.25rem;
  border-style: solid; border-width: .85rem 0 .85rem 1.4rem;
  border-color: transparent transparent transparent #F9F8F3;
}
.kp-video_play:hover > span, .kp-video_play:focus-visible > span {
  transform: scale(1.06); background-color: #171616;
}
.kp-video_play:focus-visible { outline: 2px solid #F9F8F3; outline-offset: -6px; }
@media screen and (max-width: 479px) {
  .kp-video_play > span { width: 4rem; height: 4rem; }
  .kp-video_play > span::after { margin: 1.35rem 0 0 1.6rem; border-width: .65rem 0 .65rem 1.05rem; }
}
@media (prefers-reduced-motion: reduce) { .kp-video_play > span { transition: none; } }

/* Andrey Zvyagintsev page: section titles (First edition, The event, The
   interview, Films) at half their earlier size — 32px (was 64px); on phones
   First edition 20px (was 40px), the others 16px (was 32px). */
.kp-bio .heading-3xl,
.kp-event .heading-4xl, .kp-interview .heading-4xl, .kp-films .heading-4xl { font-size: 2rem; }
@media screen and (max-width: 479px) {
  .kp-bio .heading-3xl { font-size: 1.25rem; }
  .kp-event .heading-4xl, .kp-interview .heading-4xl, .kp-films .heading-4xl { font-size: 1rem; }
}

/* --- Handwriting: a director's name written with a marker ----------------------
   tools/handwriting.py makes the SVG: the Permanent Marker letters, masked by
   pen strokes down the middle of each letter. Each stroke draws in turn
   (stroke-dashoffset, its own --d delay and --t length), revealing the letter
   under it — about 3 s, once. Then the unmasked letters fade in (--total) to
   catch any crumb the pen missed. Sized in em so it matches the heading's
   font-size: --em is the name's width in em. Only an SVG mask repaints while it
   draws; nothing runs after it finishes. */
.kp-handwriting {
  display: block; margin-inline: auto; overflow: visible;
  width: calc(var(--em) * 1em); height: calc(var(--lines) * 1em);
}
.kp-hw-pen path {
  stroke-dasharray: 1 2; stroke-dashoffset: 1.02;
  animation: kp-hw-draw var(--t) linear calc(var(--d) + .35s) forwards;
}
@keyframes kp-hw-draw { to { stroke-dashoffset: 0; } }
.kp-hw-final { opacity: 0; animation: kp-hw-show .4s ease-out calc(var(--total) + .35s) forwards; }
@keyframes kp-hw-show { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .kp-hw-pen path { animation: none; stroke-dashoffset: 0; }
  .kp-hw-final { animation: none; opacity: 1; }
}

/* Contact page: heading + form in one centred column, heading centred (no side column since the
   phone number and social icons went, 2026-10-18). Same width as the films. */
.kp-contact .contact_wrapper { grid-template-columns: 1fr; width: 100%; max-width: 45rem; margin-inline: auto; }
.kp-contact .contact_wrapper > .split_slot:empty { display: none; }
/* "Contact Us": the same size as the team names on About (.heading-lg). */
.kp-contact h1 {
  font-family: var(--heading-lg--font-family);
  font-size: var(--_responsive---heading-lg--font-size);
  line-height: var(--heading-lg--line-height);
  font-weight: var(--heading-lg--font-weight);
  letter-spacing: var(--heading-lg--letter-spacing);
  text-align: center;
}

/* --- Square corners -------------------------------------------------------------
   Nikolay (2026-10-18): no rounded corners on images, nor on the small bars
   that sit opposite each other (left/right of the Partnerships rows, the home
   title line and "Explore"). The rounded edge of the photo cards is drawn by
   the Lottie frame laid over them, so the frame goes and the photo shows square. */
.image, .featured-work_image, .post_rich-text img, .sticky-titile_image,
.service_image-hover, .numbers_cta-image,
.kp-placeholder, .kp-carousel_slide, .kp-video,
.title_perf, .small_perf, .service_perf, .award_perf { border-radius: 0; }
.lottie-frame, .lottie-frame.is-desktop, .lottie-frame.is-mls, .team_lottie { display: none; }

/* --- Footer (tools/footer.py) ------------------------------------------------
   The logo, with "© 2027 KINOPANORAMA" under it, links home; the logo sits
   8px further left than the template put it. No social icons, no lines. */
.kp-footer-brand { display: flex; flex-flow: column; align-items: flex-start; gap: .75rem; }
.kp-footer-home { display: block; margin-left: -.5rem; color: inherit; }
/* "© 2027" was Black (900); the whole line is Medium (500), the lightest Satoshi loaded. */
.kp-footer-brand .foote-meta strong { font-weight: var(--font--primary-medium); }
/* The menu links sit on the same line as "© 2027 KINOPANORAMA" (its last text line). */
.footer_row:has(.kp-footer-brand) { align-items: flex-end; align-items: last baseline; }
/* The last link ends on the page edge, like "Contact" in the top bar (its side padding pushed it 16px in). */
.footer_row:has(.kp-footer-brand) .nav-link.is-footer:last-child { padding-right: 0; }
