/* Chobial — the darkroom stylesheet. The English home page uses it now; the rest of the site
   moves over to it page by page, and site.css goes when the last one has. */
:root {
  --darkroom: #0f0e0d;   /* the room with the lights off */
  --tray: #1a1816;       /* a developing tray */
  --rule: #2b2824;
  --paper: #f2ece1;      /* fixed fibre paper */
  --paper-dim: #a8a196;  /* paper under the safelight */
  --mask: #d9792b;       /* the orange mask of C-41 negative film: the only accent */
  --edge: #e8b04a;       /* edge print on 35 mm film: edge codes only */
  --serif: "Fraunces", "Iowan Old Style", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --display: "Geist", var(--sans); /* headings: clean and upright */
  --max: 1240px;
  --gutter: clamp(16px, 4vw, 40px);
  color-scheme: dark;
}

/* Fraunces and Plex Mono carry Latin and Cyrillic only; Japanese, Korean and Chinese fall back to
   the system's matching faces, serif where the design is serif. */
:lang(ja) { --serif: "Fraunces", "Hiragino Mincho ProN", "Noto Serif JP", "Yu Mincho", serif; --sans: -apple-system, "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP", "Yu Gothic", sans-serif; --mono: "IBM Plex Mono", ui-monospace, "Hiragino Sans", "Noto Sans JP", monospace; }
:lang(ko) { --serif: "Fraunces", "AppleMyungjo", "Noto Serif KR", serif; --sans: -apple-system, "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif; --mono: "IBM Plex Mono", ui-monospace, "Apple SD Gothic Neo", "Noto Sans KR", monospace; }
:lang(zh-Hans) { --serif: "Fraunces", "Songti SC", "Noto Serif SC", serif; --sans: -apple-system, "PingFang SC", "Noto Sans SC", "Microsoft YaHei", sans-serif; --mono: "IBM Plex Mono", ui-monospace, "PingFang SC", "Noto Sans SC", monospace; }
:lang(zh-Hant) { --serif: "Fraunces", "Songti TC", "Noto Serif TC", serif; --sans: -apple-system, "PingFang TC", "Noto Sans TC", "Microsoft JhengHei", sans-serif; --mono: "IBM Plex Mono", ui-monospace, "PingFang TC", "Noto Sans TC", monospace; }
:lang(ja) :is(h1, h2, h3), :lang(ko) :is(h1, h2, h3), :lang(zh) :is(h1, h2, h3) { letter-spacing: 0; line-height: 1.25; word-break: auto-phrase; }
:lang(ja) :is(.label, .nav-links), :lang(ko) :is(.label, .nav-links), :lang(zh) :is(.label, .nav-links) { letter-spacing: .04em; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; background: var(--darkroom); color: var(--paper); font: 17px/1.6 var(--sans); -webkit-font-smoothing: antialiased; overflow-x: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--mask); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
p { margin: 0 0 1em; }
code { font: .88em var(--mono); }
h1, h2, h3 { font-family: var(--display); font-weight: 500; line-height: 1.02; letter-spacing: -0.035em; margin: 0 0 .4em; }
h2 { font-size: clamp(2.2rem, 5.2vw, 4.2rem); }
h3 { font-size: 1.6rem; line-height: 1.15; }
:focus-visible { outline: 2px solid var(--mask); outline-offset: 3px; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
.mono, .cap, .label { font-family: var(--mono); letter-spacing: .02em; }
.cap { font-size: .78rem; line-height: 1.5; color: var(--paper-dim); }
.label { font-size: .74rem; text-transform: uppercase; letter-spacing: .12em; color: var(--paper-dim); }
.lede { font-size: 1.18rem; color: var(--paper-dim); max-width: 34em; }
.prose { max-width: 34em; color: var(--paper-dim); }
.prose strong { color: var(--paper); font-weight: 600; }

/* Buttons: one accent, square shoulders */
.btn { display: inline-flex; align-items: center; gap: 10px; padding: 13px 22px; border-radius: 2px; font: 600 .98rem var(--sans); border: 1px solid transparent; cursor: pointer; }
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--mask); color: #160c03; }
.btn-primary:hover { background: #e68a3e; }
.btn-ghost { border-color: var(--rule); color: var(--paper); }
.btn-ghost:hover { border-color: var(--paper-dim); }

/* Nav: solid, and blurs what scrolls under it */
.nav { position: sticky; top: 0; z-index: 20; background: rgba(15,14,13,.88); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-bottom: 1px solid var(--rule); }
.nav .wrap { display: flex; align-items: center; gap: 24px; height: 56px; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--paper); font: 500 1.15rem var(--serif); }
.brand:hover { text-decoration: none; }
.brand img { width: 26px; height: 26px; border-radius: 6px; }
.nav-links { display: flex; gap: 22px; margin-left: auto; font: .8rem var(--mono); text-transform: uppercase; letter-spacing: .1em; }
.nav-links a { color: var(--paper-dim); }
.nav-links a:hover { color: var(--paper); text-decoration: none; }
@media (max-width: 720px) { .nav-links .hide-sm { display: none; } .nav-links { gap: 14px; } }
@media (max-width: 420px) { .nav-links { gap: 10px; font-size: .72rem; letter-spacing: .06em; } }
.nav-links { align-items: center; }
.nav-links a[aria-current] { color: var(--paper); }
/* The one call to action, set as the page's button rather than another link */
.nav-links .nav-cta { color: #160c03; padding: 7px 14px; font: 600 .86rem var(--sans); text-transform: none; letter-spacing: 0; white-space: nowrap; margin-left: 4px; }
.nav-links .nav-cta:hover { color: #160c03; }
@media (max-width: 420px) { .nav-links .nav-cta { padding: 6px 10px; font-size: .78rem; margin-left: 0; } }
/* On a phone the four don't fit beside the name, so the brand is its icon; the name is still read out */
@media (max-width: 560px) { .nav .wrap { gap: 12px; } .brand { font-size: 0; gap: 0; } .brand img { width: 30px; height: 30px; } }
@media (max-width: 360px) { .nav-links { gap: 8px; letter-spacing: .02em; } }

/* Edge print: the line along the rebate of 35 mm film */
.edge { font: 500 .7rem/1 var(--mono); letter-spacing: .22em; text-transform: uppercase; color: var(--edge); white-space: nowrap; overflow: hidden; }

/* 1 · Hero: one photograph, edge to edge */
.hero { padding: clamp(40px, 8vh, 96px) 0 clamp(48px, 8vh, 96px); }
.hero > .wrap { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(28px, 5vw, 72px); align-items: center; }
.hero h1 { font-size: clamp(2.6rem, 5vw, 4.8rem); line-height: 1; margin: 0 0 .3em; text-wrap: balance; }
.hero h1 em { font-style: normal; color: var(--mask); }
.hero-text p { font-size: 1.12rem; max-width: 30em; color: var(--paper-dim); margin-bottom: 28px; }
/* The hero is a contact sheet of five lines: what it does, then why, in the mask orange */
.hero-list { list-style: none; margin: 0 0 32px; padding: 0; display: grid; grid-template-columns: max-content 1fr; column-gap: .7em; font: 500 clamp(1.3rem, 2vw, 1.95rem)/1.15 var(--display); letter-spacing: -0.03em; }
.hero-list li { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; padding: .45em 0; border-bottom: 1px solid var(--rule); }
.hero-list b { white-space: nowrap; }
@media (max-width: 560px) { .hero-list { grid-template-columns: 1fr; } .hero-list li { grid-template-columns: 1fr; } }
.hero-list li:first-child { border-top: 1px solid var(--rule); }
.hero-list b { font-weight: 500; }
.hero-list em { font-style: normal; color: var(--mask); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* The frame hangs as a print: the edge code on its black rebate, never over the picture */
.hero-print { margin: 0; justify-self: end; width: min(100%, calc((100svh - 260px) * .75)); min-width: min(100%, 300px); }
.hero-print .rebate { background: #050404; padding: 10px 0 12px; box-shadow: 0 30px 60px -30px #000; }
.hero-print .edge { padding: 0 14px 9px; }
.hero-print img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.hero-print .cap { margin-top: 12px; }
@media (max-width: 820px) {
  .hero { padding-top: 0; }
  .hero > .wrap { grid-template-columns: 1fr; gap: 24px; }
  .hero-print { order: -1; justify-self: stretch; width: auto; margin: 0 calc(-1 * var(--gutter)); }
  .hero-print img { aspect-ratio: auto; height: 58svh; min-height: 320px; object-position: 50% 60%; }
  .hero-print .cap { padding: 0 var(--gutter); }
}

/* Chapters */
.chapter { padding: clamp(72px, 11vw, 140px) 0; border-top: 1px solid var(--rule); }
h2 s { color: var(--paper-dim); text-decoration-thickness: .07em; }
.chapter-head { display: grid; grid-template-columns: 180px 1fr; gap: 24px; margin-bottom: clamp(32px, 5vw, 56px); }
.chapter-head .label { padding-top: .9em; }
.chapter-head .label b { display: block; color: var(--mask); font-weight: 500; }
@media (max-width: 760px) { .chapter-head { grid-template-columns: 1fr; gap: 6px; } .chapter-head .label { padding-top: 0; } }
.split { display: grid; grid-template-columns: 7fr 5fr; gap: clamp(28px, 5vw, 64px); align-items: start; }
.split.flip { grid-template-columns: 5fr 7fr; }
@media (max-width: 860px) { .split, .split.flip { grid-template-columns: minmax(0, 1fr); } }

figure { margin: 0; }
figure img { width: 100%; background: var(--tray); }
figcaption { margin-top: 10px; }

/* The develop: a frame comes up from its negative */
.develop { transition: filter .7s cubic-bezier(.3,.6,.2,1); filter: invert(0) sepia(0) saturate(1) hue-rotate(0deg) brightness(1) contrast(1); }
.develop.neg { transition: none; filter: invert(1) sepia(1) saturate(3.2) hue-rotate(-18deg) brightness(.78) contrast(.85); }
@media (prefers-reduced-motion: reduce) { .develop, .develop.neg { transition: none; filter: none; } html { scroll-behavior: auto; } }

/* 2 · The negative: one frame, every film */
.bench { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(24px, 4vw, 56px); align-items: start; }
@media (max-width: 860px) { .bench { grid-template-columns: minmax(0, 1fr); } }
.compare { position: relative; overflow: hidden; aspect-ratio: 3 / 4; background: #000; user-select: none; touch-action: pan-y; }
.compare img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.compare .after { clip-path: inset(0 0 0 var(--pos, 50%)); }
.compare .handle { position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); width: 1px; background: var(--paper); pointer-events: none; }
.compare .handle::after { content: ""; position: absolute; top: 50%; left: -14px; width: 28px; height: 28px; margin-top: -14px; border: 1px solid var(--paper); background: rgba(15,14,13,.6); border-radius: 50%; }
.compare input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: ew-resize; margin: 0; }
.compare .tag { position: absolute; top: 12px; padding: 5px 8px; background: rgba(15,14,13,.72); font: .7rem var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--paper); }
.compare .tag.l { left: 12px; } .compare .tag.r { right: 12px; }
.compare.wide { aspect-ratio: 4 / 3; }

.film-now { border-top: 1px solid var(--rule); padding-top: 18px; margin-bottom: 28px; }
.film-now h3 { font-size: clamp(2rem, 3.4vw, 2.8rem); margin: 6px 0 8px; }
.film-now p { color: var(--paper-dim); margin: 0; min-height: 3.2em; }

/* Cassettes: drawn the way the app draws them (FilmCassette.swift), and loaded the way its film
   strip loads one (FilmStrip.swift). The picked roll stands up out of the row with its leader
   pulled; the rest sit back, tucked in and dimmed. One beat, 0.55 s, so the roll being left winds
   its film back in as the new one comes out. */
.shelf { position: relative; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px 6px; }
@media (max-width: 860px) { .shelf { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; padding: 4px 0 10px; gap: 6px; } .shelf .can { flex: 0 0 74px; scroll-snap-align: start; } }
.can { appearance: none; border: 0; padding: 10px 0 0; background: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 5px; color: var(--paper-dim); font: .66rem var(--mono); letter-spacing: .04em; -webkit-tap-highlight-color: transparent; }
/* The cassette is 44 wide; the leader's 26 units hang off its right. The margin centres the body,
   not the overhang, over the name. */
.can > svg { width: 55.2px; height: 80.24px; margin-left: 11.2px; overflow: visible; opacity: .45;
  transition: transform .55s ease-in-out, opacity .55s ease-in-out, filter .55s ease-in-out; }
.can .tongue { transform: translate(58px, 36px); transition: transform .55s ease-in-out; }
.can .speed { font: 800 19px "Barlow Condensed", "Arial Narrow", sans-serif; text-anchor: middle; dominant-baseline: central; }
.can .code { font: 900 44px "Barlow Condensed", "Arial Narrow", sans-serif; letter-spacing: 1px; text-anchor: middle; dominant-baseline: central; }
.can span { white-space: nowrap; transition: color .55s ease-in-out; }
.can:hover > svg { opacity: .7; }
.can[aria-pressed="true"] > svg { opacity: 1; transform: translateY(-7px); filter: drop-shadow(0 5px 7px rgb(0 0 0 / .7)); }
.can[aria-pressed="true"] .tongue { transform: translate(93px, 36px); }
.can[aria-pressed="true"] span { color: var(--mask); }
@media (prefers-reduced-motion: reduce) { .can > svg, .can .tongue, .can span { transition: none; } }

/* 3 · Shoot: the controls as a spec list, not cards */
.specs { list-style: none; padding: 0; margin: 28px 0 0; border-top: 1px solid var(--rule); }
.specs li { display: grid; grid-template-columns: 9.5em 1fr; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--rule); color: var(--paper-dim); font-size: .95rem; }
.specs li span:first-child { font: .74rem/1.9 var(--mono); text-transform: uppercase; letter-spacing: .1em; color: var(--paper); }
@media (max-width: 480px) { .specs li { grid-template-columns: 1fr; gap: 2px; } }

/* 4 · The data sheet */
.sheet { background: var(--tray); border: 1px solid var(--rule); padding: clamp(20px, 3vw, 36px); }
.sheet-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 8px 24px; border-bottom: 1px solid var(--rule); padding-bottom: 14px; margin-bottom: 22px; }
.sheet-head h3 { margin: 0; font-size: 2.2rem; }
.sheet-grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 28px 36px; }
@media (max-width: 760px) { .sheet-grid { grid-template-columns: 1fr; } }
.sheet h4 { font: .74rem var(--mono); text-transform: uppercase; letter-spacing: .12em; color: var(--paper-dim); margin: 0 0 10px; font-weight: 500; }
.curve { width: 100%; height: auto; aspect-ratio: 1; display: block; }
.curve .grid line { stroke: var(--rule); stroke-width: 1; }
.curve .id { stroke: #4a453e; stroke-dasharray: 3 4; stroke-width: 1; }
.bands { width: 100%; border-collapse: collapse; font: .78rem var(--mono); }
.bands td, .bands th { padding: 5px 0; border-bottom: 1px solid var(--rule); text-align: left; font-weight: 400; }
.bands th { color: var(--paper-dim); font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; }
.bands td:not(:first-child), .bands th:not(:first-child) { text-align: right; }
.sw { display: inline-block; width: 14px; height: 14px; vertical-align: -3px; margin-right: 2px; }
.sheet dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 18px; margin: 0; font: .82rem var(--mono); }
.sheet dt { color: var(--paper-dim); }
.sheet dd { margin: 0; text-align: right; }
.legend { display: flex; gap: 16px; margin-top: 8px; }
.legend span::before { content: ""; display: inline-block; width: 14px; height: 2px; margin-right: 6px; vertical-align: middle; background: currentColor; }

/* 5 · Re-develop: one frame, three times */
.triptych { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 640px) { .triptych { grid-template-columns: 1fr; } }
.triptych img { aspect-ratio: 3 / 4; object-fit: cover; }

/* 6 · Masks */
/* 9:16 columns: a 3:4 frame beside a 4:3 one comes out the same height */
.pairs { display: grid; grid-template-columns: 9fr 16fr; gap: 16px; margin-top: 16px; }
@media (max-width: 640px) { .pairs { grid-template-columns: 1fr; } }

/* 7 · Films by people */
.wall { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 960px) { .wall { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.slot { border: 1px dashed #4a453e; aspect-ratio: 3 / 4; padding: 18px; display: flex; flex-direction: column; justify-content: space-between; }
.slot .num { font: .74rem var(--mono); letter-spacing: .12em; color: var(--edge); }
.slot strong { font: 400 1.5rem/1.15 var(--serif); color: var(--paper); }
.slot.qr { padding: 0; border-style: solid; border-color: var(--rule); overflow: hidden; }
.slot.qr img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }

/* 8 · The small print, set as a data sheet */
.print { display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px; }
@media (max-width: 860px) { .print { grid-template-columns: 1fr; } }
.print dl { margin: 0; }
.print .row { display: grid; grid-template-columns: 11em 1fr; gap: 16px; padding: 13px 0; border-bottom: 1px solid var(--rule); }
.print dt { font: .74rem/1.9 var(--mono); text-transform: uppercase; letter-spacing: .1em; color: var(--paper-dim); }
.print dd { margin: 0; font-size: .95rem; }
@media (max-width: 480px) { .print .row { grid-template-columns: 1fr; gap: 2px; } }
.price { display: grid; grid-template-columns: 1fr 1fr; gap: 0; margin-top: 56px; border: 1px solid var(--rule); }
.price > div { padding: clamp(20px, 3vw, 32px); }
.price > div + div { border-left: 1px solid var(--rule); background: var(--tray); }
@media (max-width: 760px) { .price { grid-template-columns: 1fr; } .price > div + div { border-left: 0; border-top: 1px solid var(--rule); } }
.price h3 { font-size: 2rem; margin-bottom: 4px; }
.price .amount { font: 500 .9rem var(--mono); color: var(--mask); }
.price ul { list-style: none; padding: 0; margin: 16px 0 0; color: var(--paper-dim); font-size: .95rem; }
.price li { padding: 7px 0; border-top: 1px solid var(--rule); }

/* FAQ */
.faq { max-width: 52em; }
.faq details { border-top: 1px solid var(--rule); padding: 16px 0; }
.faq details:last-child { border-bottom: 1px solid var(--rule); }
.faq summary { cursor: pointer; list-style: none; display: flex; justify-content: space-between; gap: 16px; font: 400 1.25rem/1.3 var(--serif); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--mono); color: var(--mask); }
.faq details[open] summary::after { content: "−"; }
.faq details p { color: var(--paper-dim); margin: 10px 0 0; max-width: 40em; }

/* 9 · Get it */
.get { text-align: left; }
/* Two lines, question and answer, on any phone: below about 420px the heading shrinks with the screen */
.get h2 { font-size: min(clamp(2.2rem, 5.2vw, 4.2rem), 8.2vw); }
:lang(ja) .get h2, :lang(zh) .get h2 { font-size: min(clamp(2.2rem, 5.2vw, 4.2rem), 7.4vw); }
.beta { display: flex; flex-wrap: wrap; gap: 10px; max-width: 560px; margin-top: 28px; }
.beta input[type=email] { flex: 1 1 240px; min-width: 0; padding: 13px 16px; border-radius: 2px; border: 1px solid var(--rule); background: var(--tray); color: var(--paper); font: 1rem var(--sans); }
.beta input[type=email]:focus { outline: none; border-color: var(--mask); }
.beta button:disabled { opacity: .6; cursor: default; }
.beta .cf-turnstile { flex-basis: 100%; }
.beta .cf-turnstile:empty { display: none; }
.beta .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.note { font-size: .86rem; color: var(--paper-dim); margin-top: 12px; max-width: 40em; }

/* Footer: the maker, by name */
footer.site { border-top: 1px solid var(--rule); padding: 56px 0 64px; color: var(--paper-dim); font-size: .92rem; }
footer.site .wrap { display: grid; grid-template-columns: 1fr auto; gap: 28px 48px; }
footer.site .maker { font: 400 1.35rem/1.35 var(--serif); color: var(--paper); max-width: 26em; margin: 0; }
footer.site nav { display: flex; flex-wrap: wrap; gap: 8px 20px; font: .78rem var(--mono); text-transform: uppercase; letter-spacing: .08em; align-content: start; }
footer.site a { color: var(--paper-dim); }
footer.site nav.langs { grid-column: 1 / -1; text-transform: none; letter-spacing: 0; font: .82rem var(--sans); gap: 6px 16px; }
footer.site nav.langs a[aria-current] { color: var(--paper); }
@media (max-width: 760px) { footer.site .wrap { grid-template-columns: 1fr; } }

/* The language offer from lang.js */
.lang-banner { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 50; max-width: 560px; margin: 0 auto; display: flex; align-items: center; gap: 12px; padding: 12px 12px 12px 18px; border: 1px solid var(--rule); border-radius: 2px; background: var(--tray); font: .95rem/1.4 var(--sans); }
.lang-banner p { margin: 0; flex: 1; }
.lang-banner .btn { padding: 9px 14px; font-size: .9rem; white-space: nowrap; }
.lang-banner button { flex: none; width: 36px; height: 36px; border: 0; background: transparent; color: var(--paper-dim); font-size: 1.4rem; cursor: pointer; }
@media (max-width: 520px) { .lang-banner { flex-wrap: wrap; } .lang-banner p { flex-basis: calc(100% - 48px); } }

/* Motion. Everything here is extra: it switches on with the .motion class, which the head sets
   only when the reader hasn't asked for less motion, and darkroom.js adds the classes that hide
   anything before it is shown, so the page reads the same without either. */
:root { interpolate-size: allow-keywords; }

/* The safelight: a dim amber glow over the top of each chapter, as if each had its own lamp
   above the trays. It sits behind everything, so the photographs are never tinted. */
.hero, .chapter { position: relative; }
.hero::before, .chapter::before { content: ""; position: absolute; z-index: -1; inset: 0 0 auto; height: 520px; pointer-events: none; background: radial-gradient(ellipse 60% 70% at 30% 0%, rgb(217 121 43 / .13), transparent 70%); }

/* A frame counter along the nav: how far through the roll you are */
@supports (animation-timeline: scroll()) {
  .motion .nav::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--mask); transform-origin: 0 50%; animation: wind linear both; animation-timeline: scroll(root); }
  @keyframes wind { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* The hero comes up in the tray: the lines one after another, the print from its negative */
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }
@keyframes come-up {
  0% { opacity: 0; filter: invert(1) sepia(1) saturate(3.2) hue-rotate(-18deg) brightness(.6) contrast(.85); }
  25% { opacity: 1; filter: invert(1) sepia(1) saturate(3.2) hue-rotate(-18deg) brightness(.78) contrast(.85); }
  100% { opacity: 1; filter: invert(0) sepia(0) saturate(1) hue-rotate(0deg) brightness(1) contrast(1); }
}
.motion .hero-text > :not(.hero-list), .motion .hero-list li, .motion .hero-print .cap { animation: rise .8s cubic-bezier(.2,.7,.2,1) both; }
.motion .hero-text > :nth-child(1) { animation-delay: .05s; }
.motion .hero-text > :nth-child(2) { animation-delay: .15s; }
.motion .hero-text > :nth-child(3) { animation-delay: .25s; }
.motion .hero-list li:nth-child(1) { animation-delay: .1s; }
.motion .hero-list li:nth-child(2) { animation-delay: .18s; }
.motion .hero-list li:nth-child(3) { animation-delay: .26s; }
.motion .hero-list li:nth-child(4) { animation-delay: .34s; }
.motion .hero-list li:nth-child(5) { animation-delay: .42s; }
.motion .hero-list + .btn { animation-delay: .55s; }
.motion .hero-print .cap { animation-delay: 1.4s; }
.motion .hero-print img { animation: come-up 2.2s cubic-bezier(.3,.6,.2,1) .2s both; }
/* The edge print runs past, as the film would through the gate */
.edge-run { display: inline-flex; animation: run 60s linear infinite; }
.edge-run > span { padding-right: 2.4em; }
@keyframes run { to { transform: translateX(-50%); } }
@media (hover: hover) and (pointer: fine) {
  .motion .hero-print .rebate { transition: transform .6s cubic-bezier(.2,.7,.2,1); transform: perspective(1200px) rotateX(var(--ty, 0deg)) rotateY(var(--tx, 0deg)); }
  .motion .hero-print.tilting .rebate { transition-duration: .12s; }
}
/* Everything below the fold rises into place as it comes into view, siblings a beat apart */
.reveal { transition: opacity .9s cubic-bezier(.2,.7,.2,1), transform .9s cubic-bezier(.2,.7,.2,1); transition-delay: calc(var(--i, 0) * 70ms); }
.reveal:not(.in) { opacity: 0; transform: translateY(26px); }
/* Prints are pinned to the wall a little crooked, then straightened */
.wall .reveal:not(.in) { transform: translateY(26px) rotate(var(--tilt, 0deg)); }
/* Photographs develop as they arrive: faint and warm under the safelight, then up to full */
.reveal img.latent { transition: filter 1.6s cubic-bezier(.3,.6,.2,1) .15s; }
.reveal:not(.in) img.latent { filter: brightness(.45) contrast(.5) sepia(.7); }

/* The data sheet: the curves draw themselves, and each hue turns from its input to its output */
.sheet polyline.draw { stroke-dasharray: 1; stroke-dashoffset: 0; transition: stroke-dashoffset 1.8s cubic-bezier(.45,.05,.25,1); }
.sheet polyline.draw:nth-of-type(1) { transition-delay: .5s; }
.sheet polyline.draw:nth-of-type(2) { transition-delay: .35s; }
.sheet polyline.draw:nth-of-type(3) { transition-delay: .2s; }
.sheet:not(.in) polyline.draw { stroke-dashoffset: 1; }
.sheet .sw.turn { transition: background-color 1.2s ease-in-out; transition-delay: calc(.8s + var(--i, 0) * 90ms); }

/* The compare slider: arrows on the knob, which grows under a finger, and the line glows */
.compare .handle::after { background: rgba(15,14,13,.6) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28' fill='none' stroke='%23f2ece1' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 10l-4 4 4 4M17 10l4 4-4 4'/%3E%3C/svg%3E") center / 100% no-repeat; transition: transform .25s cubic-bezier(.2,.7,.2,1), background-color .25s; }
.compare.dragging .handle::after { transform: scale(1.35); background-color: rgba(217,121,43,.85); }
.compare.dragging .handle { box-shadow: 0 0 12px rgba(242,236,225,.5); }
.compare { cursor: ew-resize; }
/* Under a finger darkroom.js does the dragging; the range input would jump to wherever a scroll began */
@media (pointer: coarse) { .compare input { pointer-events: none; } }

/* A new film's name comes up with the frame */
@keyframes swap { from { opacity: 0; transform: translateY(8px); } }
.motion .film-now.swapped :is(h3, p, .label) { animation: swap .5s cubic-bezier(.2,.7,.2,1) both; }
.motion .film-now.swapped p { animation-delay: .06s; }
/* On phones the strip fades at its ends, so it reads as something to swipe */
@media (max-width: 860px) { .shelf { -webkit-mask-image: linear-gradient(90deg, transparent, #000 20px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, transparent, #000 20px, #000 calc(100% - 28px), transparent); } }

/* FAQ answers open rather than appear */
.faq details::details-content { block-size: 0; overflow: clip; transition: block-size .35s cubic-bezier(.2,.7,.2,1), content-visibility .35s allow-discrete; }
.faq details[open]::details-content { block-size: auto; }
.faq summary:hover { color: #fff; }

/* The one button glints as you reach for it */
.btn-primary { position: relative; overflow: hidden; transition: background-color .2s, transform .2s; }
.btn-primary::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 30%, rgb(255 255 255 / .35) 50%, transparent 70%); transform: translateX(-120%); pointer-events: none; }
.btn-primary:hover::after { transform: translateX(120%); transition: transform .7s ease; }
.btn-primary:active { transform: scale(.97); }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal:not(.in), .wall .reveal:not(.in) { opacity: 1; transform: none; transition: none; }
  .reveal:not(.in) img.latent { filter: none; }
  .sheet:not(.in) polyline.draw { stroke-dashoffset: 0; }
  .edge-run { animation: none; }
  .faq details::details-content, .btn-primary::after { transition: none; }
}

/* Framed prints on the wall: each at its own shape, standing on a common line */
.wall.framed-prints { margin-top: 16px; align-items: end; }
.slot.framed { border: 0; padding: 0; aspect-ratio: auto; gap: 10px; justify-content: flex-end; }
.slot.framed img { width: 100%; height: auto; box-shadow: 0 24px 50px -24px rgba(0,0,0,.9); }
