/* ============================================================
   THE CHAIRS THAT MOVE US
   The whole design system for chairsthatmoveus.com.

   One stylesheet, no build step, no framework. Ported in shape from
   opal-website/styles/opal.css (tokens, the focus rules, the
   reduced-motion and forced-colors guards at the end) and then
   repainted, because this is the film's site and not the company's.
   Two differences from every other ATDev site:

     1. The type is IBM Plex, self-hosted in fonts/. It is the film's
        own face: the chapter cards, the object labels and the credit
        roll are all set in it. Not Montserrat and Raleway.
     2. The palette is ink, paper and one vermilion, taken from the
        film's coda (an ink circle closed by a robotic arm) and from
        the seal you would stamp beside one. There is no blue here on
        purpose: ATDev's brand blue would make this read as a product
        page for the machine, which is the posture the film's own
        production notes rule out. See CLAUDE.md.

   Sections: tokens, dark theme, base, focus, layout, nav, buttons,
   hero, status, cards, chapters, table, credits, quote, form,
   footer, motion, forced colors, print.
   ============================================================ */

/* ============ TOKENS (light: paper) ============
   Light is "paper": the calligraphy sheet the film opens on. Every
   pair below is AA or better against its ground and the measured
   ratios are recorded in docs/accessibility.md. Do not introduce a
   color that has not been checked in both themes. */

:root {
  color-scheme: light;

  --bg: #F4F1EA;
  --bg-2: #FFFFFF;
  --bg-3: #EBE7DE;
  --surface: rgba(20, 17, 14, 0.035);
  --surface-2: rgba(20, 17, 14, 0.065);
  --line: rgba(20, 17, 14, 0.13);
  --line-2: rgba(20, 17, 14, 0.26);

  --text: #14110E;
  --muted: #57514A;
  --faint: #6E675E;

  /* The one chromatic token. Vermilion, the color of a seal stamped
     beside an ink circle. It is a text and line color in this theme,
     measured at 6.33:1 on paper and 7.14:1 on white, so unlike the
     sibling ATDev sites there is no separate fill-only variant here
     to get wrong. */
  --signal: #A32D14;
  --signal-deep: #7E220F;
  --signal-rgb: 163, 45, 20;

  --ok: #1B6B3F;
  --warn: #7A4E00;

  --radius: 2px;
  --radius-lg: 3px;
  --container: 1120px;
  --measure: 34rem;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Minimum interactive target. Held at 48px, well above the 24px
     WCAG 2.2 AA floor, because of who reads this site. The reasoning
     is in docs/accessibility.md. */
  --target: 48px;

  --font: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --shadow: 0 1px 2px rgba(20, 17, 14, .05), 0 12px 32px rgba(20, 17, 14, .06);

  --nav-bg: rgba(244, 241, 234, 0.88);
  --nav-bg-solid: rgba(244, 241, 234, 0.98);
}

/* ============ DARK THEME (ink) ============
   The film is watched in the dark, so this is the default: the
   no-FOUC script in every page head falls back to dark rather than
   light, which is the one place this site inverts the house pattern.
   Only the tokens that have to move are redeclared. */

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0B0B0C;
  --bg-2: #121214;
  --bg-3: #15161A;
  --surface: rgba(255, 255, 255, 0.04);
  --surface-2: rgba(255, 255, 255, 0.075);
  --line: rgba(255, 255, 255, 0.13);
  --line-2: rgba(255, 255, 255, 0.26);

  --text: #F2EFE9;
  --muted: #B0AAA1;
  --faint: #928C83;

  --signal: #FF8A66;
  --signal-deep: #FFA98C;
  --signal-rgb: 255, 138, 102;

  --ok: #5FD08A;
  --warn: #E3B341;

  --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 12px 32px rgba(0, 0, 0, .5);

  --nav-bg: rgba(11, 11, 12, 0.84);
  --nav-bg-solid: rgba(11, 11, 12, 0.98);
}

/* ============ BASE ============ */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-weight: 400;
  /* Type is in rem with clamp() throughout, so the page reflows at
     320px and survives 400% zoom with no fixed height anywhere. */
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  line-height: 1.62;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0 0 0.6em;
  font-weight: 500;
  line-height: 1.16;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.1rem, 1.5rem + 3vw, 3.9rem); }
h2 { font-size: clamp(1.6rem, 1.3rem + 1.5vw, 2.35rem); }
h3 { font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem); }
h4 { font-size: 1.02rem; }

p { margin: 0 0 1.15em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--signal); text-underline-offset: 0.18em; }
a:hover { color: var(--signal-deep); }

strong { font-weight: 500; color: var(--text); }

img, svg, video { max-width: 100%; height: auto; }

hr {
  height: 1px;
  margin: 3rem 0;
  border: 0;
  background: var(--line);
}

/* The lede. One paragraph per page, directly under the h1. */
.lede {
  max-width: 38rem;
  color: var(--muted);
  font-size: clamp(1.08rem, 1rem + 0.4vw, 1.28rem);
  font-weight: 300;
  line-height: 1.5;
}

/* A label set in the mono face. This is the film's own convention:
   the object labels in the Chapter Three gallery are set this way. */
.eyebrow {
  display: block;
  margin: 0 0 1rem;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.muted { color: var(--muted); }
.small { font-size: 0.9rem; }
.mono { font-family: var(--font-mono); }

/* ============ FOCUS AND SKIP LINK ============
   The ring is 3px at 3px offset and it is NEVER removed, anywhere,
   for any element, under any circumstance. It is drawn in the signal
   color in both themes and both pass AA against every ground on the
   site. If a component looks wrong with a focus ring on it, the
   component is what is wrong. */

:focus-visible {
  outline: 3px solid var(--signal);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip {
  position: absolute;
  left: 0.5rem;
  top: -100vh;
  z-index: 200;
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  padding: 0 1.25rem;
  background: var(--bg-2);
  border: 2px solid var(--signal);
  color: var(--text);
  font-weight: 500;
  text-decoration: none;
}
.skip:focus { top: 0.5rem; }

/* ============ LAYOUT ============ */

.wrap {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 clamp(1.1rem, 4vw, 2.5rem);
}

main { display: block; }

section { padding: clamp(3.25rem, 8vw, 6rem) 0; }
section + section { border-top: 1px solid var(--line); }

.section-head { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }

.grid {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2rem);
}

/* --trio goes one column to three with nothing in between, so a set
   of three never breaks as two plus an orphan on a tablet. Same rule
   as the sibling sites: use auto-fit only for four or more. */
.grid--trio { grid-template-columns: 1fr; }
.grid--duo { grid-template-columns: 1fr; }

@media (min-width: 46rem) {
  .grid--duo { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 58rem) {
  .grid--trio { grid-template-columns: repeat(3, 1fr); }
}

.split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}
@media (min-width: 62rem) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 20rem); }
}

/* ============ NAV ============ */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--nav-bg);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line);
}
@supports not (backdrop-filter: blur(4px)) {
  .nav { background: var(--nav-bg-solid); }
}

.nav__row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 64px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: var(--target);
  margin-right: auto;
  color: var(--text);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.brand__mark { flex: none; width: 26px; height: 26px; }
.brand__name { white-space: nowrap; }

/* Below 26rem the wordmark would push the two 48px buttons off the
   row. The film's title is four words and cannot be shortened, so
   the mark is what gives way, not the target size. */
@media (max-width: 26rem) {
  .brand__mark { display: none; }
  .brand { font-size: 0.88rem; }
}

.nav__list {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  padding: 0 0.85rem;
  color: var(--muted);
  font-size: 0.94rem;
  text-decoration: none;
}
.nav__link:hover { color: var(--text); background: var(--surface); }
.nav__link[aria-current="page"] {
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--signal);
}

.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--target);
  height: var(--target);
  padding: 0;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
}
.iconbtn:hover { background: var(--surface); border-color: var(--line-2); }
.iconbtn svg { width: 20px; height: 20px; }

/* The nav toggle exists only below the breakpoint, and the list
   ships visible. scripts/chairs.js collapses it only once the toggle
   is known to be wired up, so the nav works with JavaScript off. */
.nav__toggle { display: none; }

@media (max-width: 52rem) {
  .nav__toggle { display: inline-flex; }
  .nav__list {
    position: absolute;
    left: calc(clamp(1.1rem, 4vw, 2.5rem) * -1);
    right: calc(clamp(1.1rem, 4vw, 2.5rem) * -1);
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem clamp(1.1rem, 4vw, 2.5rem) 1rem;
    background: var(--nav-bg-solid);
    border-bottom: 1px solid var(--line);
  }
  .nav__list[hidden] { display: none; }
  .nav__link { padding: 0 0.25rem; }
}

/* Theme button icons: exactly one shows, chosen by the root theme. */
.icon-sun { display: none; }
:root[data-theme="dark"] .icon-sun { display: block; }
:root[data-theme="dark"] .icon-moon { display: none; }

/* ============ BUTTONS ============ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: var(--target);
  padding: 0 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}

.btn--primary {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--bg);
}
.btn--primary:hover {
  background: var(--signal-deep);
  border-color: var(--signal-deep);
  color: var(--bg);
}

.btn--ghost {
  background: transparent;
  border-color: var(--line-2);
  color: var(--text);
}
.btn--ghost:hover { background: var(--surface); color: var(--text); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

/* ============ HERO ============ */

.hero { padding: clamp(3.5rem, 10vw, 7rem) 0 clamp(3rem, 7vw, 5rem); }

.hero__inner {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
}
@media (min-width: 62rem) {
  .hero__inner { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}

/* The title is the film's title card: flat, unornamented, one
   weight. It is not a logo and it is not a gradient. The coda's own
   line, "not a logo, not a letter, a circle", is a standing caution
   against display typography carrying this film's weight. */
.hero h1 {
  margin-bottom: 0.35em;
  font-weight: 400;
  letter-spacing: -0.02em;
}

.hero__subtitle {
  margin: 0 0 1.5rem;
  color: var(--signal);
  font-size: clamp(1.05rem, 0.98rem + 0.4vw, 1.3rem);
  font-style: italic;
  font-weight: 300;
}

/* The enso. An ink circle, drawn once, sitting in the hero where a
   poster frame would go if one existed. It is the film's closing
   image and the only ornament on the site. Decorative, so it carries
   aria-hidden in the markup and the title beside it is the real
   content. Replace it with key art when there is key art; TODO.md
   tracks that. */
.enso {
  display: block;
  width: min(100%, 22rem);
  margin-inline: auto;
  color: var(--text);
  opacity: 0.9;
}
.enso__seal { color: var(--signal); }

/* ============ STATUS ============
   Words, never a colored dot alone. Nothing on this site conveys
   meaning by color by itself. The dot is decoration beside a word
   that already says it. */

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.status::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  background: var(--signal);
  border-radius: 50%;
}

/* ============ CARDS ============ */

.card {
  padding: clamp(1.25rem, 3vw, 1.75rem);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.card h3 { margin-bottom: 0.4em; }
.card p { color: var(--muted); }

/* ============ CHAPTERS ============
   The film's five intertitles in one flat sequence, the way the film
   runs them. The number is set in the mono face and the title in
   caps, which is the chapter card's own geometry. Do not centre
   these: a centred title over a centred rule reads as a chapter
   card, and the film has exactly five of those. */

.chapters { margin: 0; padding: 0; list-style: none; max-width: 46rem; }

.chapter {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0 1.25rem;
  padding: 1.5rem 0;
  border-top: 1px solid var(--line);
}
.chapter:last-child { border-bottom: 1px solid var(--line); }

.chapter__no {
  padding-top: 0.35em;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.1em;
}
.chapter__title {
  margin: 0 0 0.4em;
  font-size: 1.02rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.chapter__body { margin: 0; color: var(--muted); }

@media (max-width: 34rem) {
  .chapter { grid-template-columns: 1fr; gap: 0.35rem; }
  .chapter__no { padding-top: 0; }
}

/* ============ SPEC TABLE ============ */

.table-scroll { overflow-x: auto; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
caption {
  margin-bottom: 0.9rem;
  color: var(--faint);
  font-size: 0.9rem;
  text-align: left;
}
th, td {
  padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
th {
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
tbody th { width: 13rem; }

/* ============ CREDITS ============
   Title over names, the shape credits.txt uses and the tail roll
   draws. A credit with no name yet is left off the page entirely
   rather than shown as an empty bracket, which is the same rule
   credit_roll.html follows in the film repo. */

.credits {
  columns: 2;
  column-gap: clamp(1.5rem, 4vw, 3rem);
  max-width: 46rem;
}
@media (max-width: 40rem) { .credits { columns: 1; } }

.credit {
  break-inside: avoid;
  margin: 0 0 1.4rem;
}
.credit dt {
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.credit dd {
  margin: 0.25rem 0 0;
  color: var(--text);
}

/* ============ QUOTE ============ */

blockquote.pull {
  max-width: 40rem;
  margin: 0;
  padding-left: clamp(1rem, 3vw, 1.75rem);
  border-left: 2px solid var(--signal);
  font-size: clamp(1.1rem, 1rem + 0.55vw, 1.45rem);
  font-weight: 300;
  line-height: 1.45;
}
blockquote.pull p { max-width: none; }
blockquote.pull cite {
  display: block;
  margin-top: 1rem;
  color: var(--faint);
  font-size: 0.9rem;
  font-style: normal;
}

/* ============ FORM ============ */

.form { max-width: 34rem; }

.field { margin-bottom: 1.4rem; }

.field label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.94rem;
  font-weight: 500;
}

.field .hint {
  margin: 0 0 0.5rem;
  max-width: none;
  color: var(--faint);
  font-size: 0.85rem;
}

input[type="text"],
input[type="email"],
select,
textarea {
  width: 100%;
  min-height: var(--target);
  padding: 0.7rem 0.9rem;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  color: var(--text);
  font-family: inherit;
  font-size: 1rem;
}
textarea { min-height: 9rem; resize: vertical; }

/* The honeypot. Positioned off-screen rather than display:none,
   because some bots skip anything hidden outright. Real people never
   reach it: it is last in the DOM, its label says plainly what it
   is, and tabindex="-1" plus autocomplete="off" keep a keyboard or
   switch user out of it. */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============ FOOTER ============ */

.footer {
  padding: clamp(2.5rem, 6vw, 4rem) 0;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.92rem;
}
.footer__row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  justify-content: space-between;
}
.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  color: var(--muted);
}
.footer__links a:hover { color: var(--text); }
.footer__fine { max-width: 32rem; color: var(--faint); font-size: 0.85rem; }

/* ============ MOTION ============
   Everything that moves on this site is listed here, and every one
   of these declarations sits inside the no-preference guard. There
   is no scroll-triggered animation and no autoplay anywhere. */

@media (prefers-reduced-motion: no-preference) {
  a,
  .nav__link,
  .iconbtn,
  .btn,
  .footer__links a {
    transition: color .18s var(--ease), background-color .18s var(--ease),
                border-color .18s var(--ease);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ============ FORCED COLORS ============
   Windows High Contrast throws away every color above, so anything
   whose only affordance is a background has to grow a real border
   here. Nothing on this site is background-only; these rules are the
   belt to that braces. */

@media (forced-colors: active) {
  .btn, .card, .iconbtn, .status, input, select, textarea {
    border: 1px solid CanvasText;
  }
  .nav__link[aria-current="page"] { box-shadow: inset 0 -2px 0 CanvasText; }
  :focus-visible { outline: 3px solid Highlight; }
  .enso { forced-color-adjust: none; }
}

/* ============ PRINT ============
   A programmer or a journalist printing the press page should get
   the words, not the chrome. */

@media print {
  .nav, .skip, .btn-row, .footer__links { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  section { padding: 1rem 0; border: 0; }
  a { color: #000; text-decoration: underline; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
