/* ==========================================================================
   Brand tokens. LOCKED.
   The only colours on this site are the three brand colours and Warm Ivory.
   Tints are alpha steps of those four values and are declared only here.
   tools/verify.py fails the build if any other colour value appears.
   ========================================================================== */
:root {
  --gold: #C8A96B;        /* Regal Gold */
  --aubergine: #533340;   /* Deep Aubergine */
  --graphite: #252526;    /* Graphite */
  --ivory: #F3EFE9;       /* Warm Ivory: supporting neutral, not a fourth signature colour */

  --graphite-72: rgb(37 37 38 / 0.72);
  --graphite-16: rgb(37 37 38 / 0.16);
  --ivory-72: rgb(243 239 233 / 0.72);
  --ivory-16: rgb(243 239 233 / 0.16);
  --gold-55: rgb(200 169 107 / 0.55);
  --aubergine-55: rgb(83 51 64 / 0.55);

  /* Type families. Fallbacks only cover the moment before the web fonts load. */
  --font-display: "Bodoni Moda", "Bodoni 72", Didot, "Times New Roman", serif;
  --font-ui: "Manrope", "Helvetica Neue", Arial, sans-serif;

  /* Layout */
  --nav-h: 72px;
  --gutter: clamp(1.25rem, 5vw, 5.5rem);
  --wrap-max: 1680px;
  --measure: 34rem;

  /* Fluid space scale */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: clamp(1.25rem, 2vw, 1.75rem);
  --space-4: clamp(2rem, 3.5vw, 3rem);
  --space-5: clamp(3rem, 6vw, 5.5rem);
  --space-6: clamp(4.5rem, 10vw, 9rem);
  --space-7: clamp(6rem, 15vw, 14rem);

  /* Motion: "silk, not software". No overshoot: both y values stay inside 0..1. */
  --ease-silk: cubic-bezier(0.22, 0.7, 0.2, 1);
  --dur-reveal: 1200ms;
  --dur-ui: 420ms;
}

@media (max-width: 959px) {
  :root {
    --nav-h: 60px;
  }
}

/* Self-hosted, open-licence (SIL OFL 1.1) fonts. No third-party font requests.
   Licences: assets/fonts/LICENSE-Bodoni-Moda.txt, LICENSE-Manrope.txt */
@font-face {
  font-family: "Bodoni Moda";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("../fonts/bodoni-moda-latin-opsz-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Bodoni Moda";
  font-style: italic;
  font-weight: 400 900;
  font-display: swap;
  src: url("../fonts/bodoni-moda-latin-opsz-italic.woff2") format("woff2");
}

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-latin-wght-normal.woff2") format("woff2");
}

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

html {
  background: var(--ivory);
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* clip, not hidden: clip does not create a scroll container, so the pinned
   cinematic (position: sticky) keeps working in Checkpoint 3. */
html,
body {
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--ivory);
  color: var(--graphite);
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.7;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

main {
  flex: 1 0 auto;
  padding-top: var(--nav-h);
}

main:focus {
  outline: none;
}

h1,
h2,
h3,
h4,
p,
figure,
blockquote,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

body,
a,
button {
  -webkit-tap-highlight-color: transparent;
}

::selection {
  background: var(--aubergine);
  color: var(--ivory);
}

/* Focus: always visible, colour chosen per surface so it clears 3:1.
   Gold on ivory is 1.96:1, so ivory surfaces use aubergine. */
:focus-visible {
  outline: 2px solid var(--focus, var(--aubergine));
  outline-offset: 4px;
}

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.85rem 1.25rem;
  background: var(--ivory);
  color: var(--graphite);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
  outline: 2px solid var(--aubergine);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Surfaces set text, accent, muted and focus colours together, so no
   component has to choose a colour pair on its own. */
.surface-ivory {
  background: var(--ivory);
  color: var(--graphite);
  --display-weight: 500;
  --display-optical: none;
  --display-variation-large: "opsz" 20;
  --display-variation-medium: "opsz" 14;
  --display-variation-small: "opsz" 11;
  --accent: var(--aubergine);
  --muted: var(--graphite-72);
  --hairline: var(--graphite-16);
  --ornament: var(--gold);
  --focus: var(--aubergine);
}

.surface-aubergine {
  background: var(--aubergine);
  color: var(--gold);
  --display-weight: 500;
  --display-optical: none;
  --display-variation-large: "opsz" 16;
  --display-variation-medium: "opsz" 11;
  --display-variation-small: "opsz" 9;
  --accent: var(--gold);
  --muted: var(--ivory-72);
  --hairline: var(--gold-55);
  --ornament: var(--gold);
  --focus: var(--gold);
}

.surface-graphite {
  background: var(--graphite);
  color: var(--ivory);
  --display-weight: 500;
  --display-optical: none;
  --display-variation-large: "opsz" 16;
  --display-variation-medium: "opsz" 11;
  --display-variation-small: "opsz" 9;
  --accent: var(--gold);
  --muted: var(--ivory-72);
  --hairline: var(--ivory-16);
  --ornament: var(--gold);
  --focus: var(--gold);
}

.wrap {
  width: 100%;
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Type hierarchy. LOCKED by owner ruling, 2026-10-02.

   Bodoni Moda = editorial and display: large headlines, Shirin's name,
     recognition statements, short expressive lines, the mobile menu.
   Manrope     = functional and readable: body copy, longer paragraphs, forms,
     utility navigation, listing metadata, legal and supporting copy.

   Bodoni Moda on graphite or aubergine
   Tested 2026-10-02 (see docs/TYPOGRAPHY.md). Weight 500 on its own does not
   make the hairlines sturdier: they stay near 0.4 px at wordmark size, because
   in this typeface hairline thickness is set by the optical-size axis, not the
   weight axis. So on dark grounds display type steps up to weight 500 AND is
   pinned to a sturdier optical size. The values live on the surface classes in
   base.css, so the nearest ground always decides. On Warm Ivory (ruling of
   2026-10-09, 10:31 PM) display type is weight 500 too, pinned at 20 for XL and L,
   14 for M and 11 for S: hairlines that hold, with more contrast kept than on dark.
   The mobile menu is exempt by ruling and stays exactly as designed. */

.t-display-xl,
.t-display-l,
.t-display-m,
.t-display-s {
  font-family: var(--font-display);
  font-weight: var(--display-weight, 400);
  font-optical-sizing: var(--display-optical, auto);
  text-wrap: balance;
}

.t-display-xl,
.t-display-l {
  font-variation-settings: var(--display-variation-large, normal);
}

.t-display-m {
  font-variation-settings: var(--display-variation-medium, normal);
}

.t-display-s {
  font-variation-settings: var(--display-variation-small, normal);
}

/* Recognition scale: may nearly fill the viewport. */
.t-display-xl {
  font-size: clamp(3rem, 10.5vw, 11.5rem);
  line-height: 0.94;
  letter-spacing: -0.015em;
}

.t-display-l {
  font-size: clamp(2.6rem, 7vw, 7rem);
  line-height: 1;
  letter-spacing: -0.012em;
}

.t-display-m {
  font-size: clamp(2rem, 4.6vw, 4.25rem);
  line-height: 1.06;
  letter-spacing: -0.008em;
}

.t-display-s {
  font-size: clamp(1.4rem, 2.5vw, 2.15rem);
  line-height: 1.24;
}

.t-italic {
  font-family: var(--font-display);
  font-style: italic;
}

/* The name, set as on the brand sheet: Bodoni capitals, open tracking. */
.t-wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  /* tracking adds space after the last letter; pull it back so the word
     sits optically flush on both sides */
  margin-right: -0.14em;
}

.t-body-l {
  font-family: var(--font-ui);
  font-size: clamp(1.0625rem, 1.25vw, 1.25rem);
  line-height: 1.65;
  max-width: var(--measure);
}

.t-body {
  font-family: var(--font-ui);
  font-size: 1rem;
  line-height: 1.7;
  max-width: var(--measure);
}

.t-label {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.t-muted {
  color: var(--muted);
}

.t-accent {
  color: var(--accent);
}

/* Navigation. LOCKED treatment: aubergine field, gold key, gold text.
   No pills, no boxes, no CTA button, no dividers. */

.site-nav {
  --focus: var(--gold);
  position: fixed;
  z-index: 60;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  height: var(--nav-h);
  padding-inline: var(--gutter);
  background: var(--aubergine);
  color: var(--gold);
}

.site-nav__brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  flex: 0 0 auto;
}

/* Canonical key artwork, inlined by the build. Size only; geometry untouched. */
.key-logo {
  display: block;
  height: 36px;
  width: auto;
  aspect-ratio: 1057 / 570;
}

.site-nav__links {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.3vw, 2.6rem);
}

.site-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  /* letter-spacing trails the last glyph; cancel it so the underline is optically true */
  margin-right: -0.2em;
  text-transform: uppercase;
  white-space: nowrap;
}

.site-nav__link::after {
  content: "";
  position: absolute;
  right: 0.2em;
  bottom: 9px;
  left: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--dur-ui) var(--ease-silk);
}

.site-nav__link:hover::after,
.site-nav__link:focus-visible::after,
.site-nav__link[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.site-nav__toggle {
  display: none;
}

/* ---------- Small screens: same identity, full aubergine sheet ---------- */
@media (max-width: 959px) {
  .key-logo {
    height: 30px;
  }

  .site-nav__toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.9rem;
    min-height: 44px;
    min-width: 44px;
    margin-right: -0.25rem;
    padding-inline: 0.25rem;
    color: var(--gold);
    font-family: var(--font-ui);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
  }

  .site-nav__toggle-mark {
    position: relative;
    display: block;
    width: 22px;
    height: 9px;
  }

  .site-nav__toggle-mark i {
    position: absolute;
    left: 0;
    width: 100%;
    height: 1px;
    background: currentColor;
    transition: transform var(--dur-ui) var(--ease-silk), top var(--dur-ui) var(--ease-silk);
  }

  .site-nav__toggle-mark i:first-child {
    top: 0;
  }

  .site-nav__toggle-mark i:last-child {
    top: 8px;
  }

  .site-nav.is-open .site-nav__toggle-mark i:first-child {
    top: 4px;
    transform: rotate(45deg);
  }

  .site-nav.is-open .site-nav__toggle-mark i:last-child {
    top: 4px;
    transform: rotate(-45deg);
  }

  .site-nav__menu {
    position: fixed;
    top: var(--nav-h);
    right: 0;
    bottom: 0;
    left: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-4) var(--gutter) calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
    background: var(--aubergine);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-ui) var(--ease-silk), visibility 0s linear var(--dur-ui);
  }

  .site-nav.is-open .site-nav__menu {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--dur-ui) var(--ease-silk), visibility 0s linear 0s;
  }

  .site-nav__links {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  .site-nav__links li {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
    transition: opacity 700ms var(--ease-silk), transform 700ms var(--ease-silk);
  }

  .site-nav.is-open .site-nav__links li {
    opacity: 1;
    transform: none;
    transition-delay: calc(var(--i, 0) * 55ms + 80ms);
  }

  .site-nav__link {
    min-height: 0;
    margin-right: 0;
    padding-block: 0.32em;
    font-family: var(--font-display);
    font-size: clamp(2rem, 9vw, 3.1rem);
    font-weight: 400;
    line-height: 1.12;
    letter-spacing: 0;
    text-transform: none;
  }

  .site-nav__link::after {
    right: 0;
    bottom: 0.3em;
  }

  html.menu-open {
    overflow: hidden;
  }
}

/* Without JavaScript the sheet cannot open, so the links sit in the flow. */
@media (max-width: 959px) {
  html:not(.js) .site-nav {
    position: static;
    height: auto;
    flex-wrap: wrap;
    padding-block: 0.5rem;
  }

  html:not(.js) .site-nav__toggle {
    display: none;
  }

  html:not(.js) .site-nav__menu {
    position: static;
    width: 100%;
    padding: 0 0 0.5rem;
    opacity: 1;
    visibility: visible;
    overflow: visible;
  }

  html:not(.js) .site-nav__links {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0 1.5rem;
  }

  html:not(.js) .site-nav__links li {
    opacity: 1;
    transform: none;
  }

  html:not(.js) .site-nav__link {
    min-height: 44px;
    padding-block: 0;
    font-family: var(--font-ui);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
  }

  html:not(.js) main {
    padding-top: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav__link::after,
  .site-nav__toggle-mark i,
  .site-nav__menu,
  .site-nav__links li,
  .site-nav.is-open .site-nav__links li {
    transition-duration: 1ms;
    transition-delay: 0s;
  }

  .site-nav__links li {
    transform: none;
  }
}

/* Footer: an editorial closing page, set on graphite. */

.site-footer {
  flex: 0 0 auto;
  padding-block: var(--space-6) var(--space-4);
}

/* The name runs the full width of the page frame. --wordmark-em is the
   measured width of "SHIRIN ATAIE" in em at this tracking, so the size is
   derived from the frame and can never overflow it. */
.site-footer__wordmark {
  --wordmark-em: 8.03;
  --frame: min(100vw, var(--wrap-max));
  font-family: var(--font-display);
  /* Owner ruling 2026-10-02: optically sturdier. Weight 500, tracking reduced
     from 0.14em to 0.10em, optical size 14. Thin strokes measure about 2.7 px
     at a 1440 px window (previously 1.3 px). Scale was not reduced: the name
     still spans the frame. Test record: docs/TYPOGRAPHY.md. */
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 14;
  font-size: calc((var(--frame) - 2 * var(--gutter)) / var(--wordmark-em));
  line-height: 1;
  letter-spacing: 0.1em;
  margin-right: -0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ivory);
}

.site-footer__body {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-5);
  margin-top: var(--space-5);
}

.site-footer__sentence {
  max-width: 22ch;
  font-family: var(--font-display);
  /* Bodoni on graphite: weight 500 and a sturdier optical size (see type.css). */
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 10;
  font-size: clamp(1.35rem, 2.1vw, 1.95rem);
  line-height: 1.3;
  text-wrap: balance;
  color: var(--ivory);
}

.site-footer__groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: start;
}

.site-footer__stack {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: var(--space-3);
  align-self: stretch;
}

/* The brokerage block: three lines, anchored in the footer's lower right (refinement ruling of 2026-10-10, next
   round, after the owner's footer edit). It sits at the foot of the last column, on that column's own left edge
   under the phone and email, its last line level with the navigation's last item. Plain lines, not touch targets,
   so they keep one even rhythm. */
.site-footer__professional {
  align-self: end;
}

.site-footer__group.site-footer__professional li {
  display: block;
  min-height: 0;
}

.site-footer__line {
  display: block;
}

.site-footer__group li {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--muted);
}

.site-footer__group li + li {
  margin-top: 0.15rem;
}

.site-footer__group a,
.site-footer__legal a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  color: var(--ivory);
  transition: color var(--dur-ui) var(--ease-silk);
}

.site-footer__group a:hover,
.site-footer__legal a:hover,
.site-footer__group a[aria-current="page"],
.site-footer__legal a[aria-current="page"] {
  color: var(--gold);
}

.site-footer__group--plain li {
  display: flex;
  align-items: center;
  min-height: 36px;
}

.site-footer__close {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
  font-size: 0.8125rem;
  color: var(--muted);
}

.site-footer__legal {
  display: flex;
  gap: var(--space-3);
}

.site-footer__copyright {
  color: var(--muted);
}

@media (max-width: 959px) {
  .site-footer__body {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    margin-top: var(--space-4);
  }

  .site-footer__groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4) var(--space-3);
  }

  .site-footer__stack {
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: none;
    gap: var(--space-3);
  }

  .site-footer__group a,
  .site-footer__legal a,
  .site-footer__group--plain li {
    min-height: 44px;
  }

  .site-footer__close {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Owner polish 2026-10-11; all prior styles retained. */
.site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) li+li {margin-top:0;}
.site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) li {min-height:0;}
.site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) a {min-height:44px;line-height:1.35;}
.site-footer__group li {font-size:clamp(1rem,1.1vw,1.1rem);line-height:1.45;}

/* Oct16: tighten only the second direct-contact row. Phone stays in place.
   The full-size phone hit target is unchanged. */
.site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) li+li {margin-top:-.35rem;}
.site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) li+li a {min-height:36px;}
@media (pointer:coarse) {
 .site-footer__stack>.site-footer__group--plain:not(.site-footer__professional) li+li a {min-height:44px;}
}

/* Motion primitives. One restrained family; no bounce, overshoot, zoom or
   letter effects. Elements are only hidden once JavaScript has confirmed it
   is running (html.js), so content is never lost if a script fails.

   Usage
     data-reveal="float"        small rise with soft opacity
     data-reveal="materialize"  almost pure opacity
     data-reveal="drift-left"   large statement entering from the left
     data-reveal="drift-right"  large statement entering from the right
     data-stagger="120"         on a parent: children reveal in sequence (ms step)
     data-reveal-delay="200"    on an element: extra delay in ms            */

.js [data-reveal] {
  opacity: 0;
  transition:
    opacity var(--dur-reveal) var(--ease-silk) var(--reveal-delay, 0ms),
    transform var(--dur-reveal) var(--ease-silk) var(--reveal-delay, 0ms);
}

.js [data-reveal="float"] {
  transform: translate3d(0, 24px, 0);
}

.js [data-reveal="materialize"] {
  transform: translate3d(0, 6px, 0) scale(0.996);
}

.js [data-reveal="drift-left"] {
  transform: translate3d(-3.5vw, 0, 0);
}

.js [data-reveal="drift-right"] {
  transform: translate3d(3.5vw, 0, 0);
}

.js [data-reveal="drift-left"],
.js [data-reveal="drift-right"] {
  --dur-reveal: 1500ms;
}

.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* Reduced motion: nothing travels. Content resolves with a brief fade only. */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    transform: none;
    transition: opacity 200ms linear;
  }

  html {
    scroll-behavior: auto;
  }
}

/* Placeholders. Deliberately designed, unmistakably unfinished.
   Written in page sources as [[LABEL]]; the build renders the token below
   and lists every one in docs/PLACEHOLDERS.md. Never replace a token with an
   invented fact. */

.ph {
  display: inline-block;
  padding: 0.42em 0.7em 0.38em;
  border: 1px dashed var(--ph-edge, var(--aubergine-55));
  color: var(--accent, var(--aubergine));
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  font-weight: 600;
  font-style: normal;
  line-height: 1.3;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}

.surface-graphite .ph,
.surface-aubergine .ph {
  --ph-edge: var(--gold-55);
}

/* Recognition panel. LOCKED by owner rulings, 2026-10-02, 4:39, 4:51 and
   4:58 PM (docs/rulings/2026-10-02_ruling-recognition-panel-locked.txt,
   -final.txt and -alignment.txt).
   Record, principles and measurements: docs/RECOGNITION-PANEL.md.

   SCOPE. This is the base language for ONE recognition moment (BusinessRate,
   Best of 2026). Other recognition statements keep the same editorial system
   but are to vary in space; they are not built yet. Do not reuse this layout
   for them as it stands: see docs/RECOGNITION-PANEL.md, section 0.

   Owner's terms            class
     headline               .recog__statement   BEST OF 2026
     supporting line        .recog__role        Real Estate Agent in Calabasas
     source line            .recog__source      the small gold line

   One treatment on every screen size: one left edge, the block set low, an
   open field above. The headline dominates. The supporting line is 60 percent
   of the headline (the ruling allows 55 to 65) and sits close beneath it, so
   the two read as one statement. The source line stands apart below.

   Nothing else is in the panel: no badge, laurel, numeral, rule, border, card
   or heading. Colours come from .surface-graphite: Warm Ivory text on
   Graphite, Regal Gold for the source line only.

   Hierarchy is carried by size (the ratio), weight (headline 500, supporting
   line 400) and space. Optical sizes are pinned so thin strokes stay near one
   pixel on a standard display.

   VISUALLY LOCKED (ruling of 4:58 PM,
   docs/rulings/2026-10-02_ruling-recognition-panel-alignment.txt). Every
   declaration below is frozen. The gate "recognition" holds a copy of each
   one and fails on any change, addition or removal. Changing anything here
   needs a new owner ruling and a matching edit to the gate's table.

   For the record: the block hangs from the foot of the panel, so where the
   headline and the source line sit depends on the SUM of the two gaps,
   --recog-air and --recog-source-air: 1.75 headline sizes (1.86 on phones). */

.recog {
  --recog-size: clamp(3.25rem, 6.4vw, 7.25rem); /* the headline */
  --recog-ratio: 0.6;                            /* supporting line, as a share of the headline */
  --recog-air: 0.3;                              /* headline to supporting line, in headline ems */
  --recog-source-air: 1.45;                      /* supporting line to source line, in headline ems */
  --recog-statement-opsz: 16;
  --recog-role-opsz: 14;
  --recog-headline-edge: 0.02499;                /* left side bearing of the headline's first letter, in ems */
  --recog-source-edge: 0.77px;                   /* left side bearing of the source line's first letter */
  display: flex;
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
}

.recog__frame {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-block: var(--space-6) clamp(4.5rem, 15vh, 10rem);
}

.recog__statement,
.recog__role {
  font-family: var(--font-display);
  font-optical-sizing: none;
}

.recog__statement {
  font-size: var(--recog-size);
  font-weight: 500;
  font-variation-settings: "opsz" var(--recog-statement-opsz);
  line-height: 1;
  letter-spacing: 0.012em;
}

.recog__role {
  margin-top: calc(var(--recog-size) * var(--recog-air));
  font-size: calc(var(--recog-size) * var(--recog-ratio));
  font-weight: 400;
  font-variation-settings: "opsz" var(--recog-role-opsz);
  line-height: 1.14;
  text-wrap: balance;
}

/* The source line is moved right so the ink of its first letter starts at
   exactly the same x as the ink of the headline's first letter. All three
   lines share one box edge, but a letter's ink starts a little inside its
   box, by an amount that grows with the type size: the big headline starts
   further in than the 11 px source line, which therefore looked slightly
   left. The two bearings are read from the font files for these letters
   (Bodoni Moda "B" at this weight and optical size; Manrope "B"), so they
   belong to this wording. position/left moves the line sideways only: no
   other element, no vertical position and no line break is affected. */
.recog__source {
  position: relative;
  left: calc(var(--recog-size) * var(--recog-headline-edge) - var(--recog-source-edge));
  margin-top: calc(var(--recog-size) * var(--recog-source-air));
  color: var(--accent);
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-wrap: balance;
}

@media (max-width: 719px) {
  .recog {
    --recog-size: clamp(2.25rem, 10.4vw, 3.25rem);
    --recog-air: 0.3;
    --recog-source-air: 1.56;
    --recog-statement-opsz: 12;
    --recog-role-opsz: 10;
    --recog-headline-edge: 0.02795;
  }

  .recog__source {
    letter-spacing: 0.18em;
  }
}

/* ---------- Internal review page (not linked from the site) ---------- */

.review__intro {
  padding-block: var(--space-5) var(--space-4);
}

.review__intro .t-body {
  margin-top: var(--space-2);
}

.review__end {
  padding-block: var(--space-4) var(--space-5);
}

/* Home cinematic: the stage the locked runtime performs on.

   Runtime: reference/Shirin_Playback_Production_Candidate (accepted E2, owner
   ruling 2026-10-03). Its app.js is shipped byte-identical and is the only
   thing that moves anything here. Record: docs/CINEMATIC-INTEGRATION.md.

   PART 1 is ported from the runtime's own styles.css. The gate "runtime"
   compares every rule in Part 1 with that file and fails on any difference
   that is not in its written list of permitted differences. Do not edit
   Part 1 without an owner ruling and a matching entry in that list.

   Five colour values in Part 1 are not brand colours and are kept exactly as
   the runtime has them: #191615, #181413, rgba(17, 12, 11, ...) and
   rgba(16, 12, 11, 0). They are the dark surround and the grade laid over the
   picture, so they belong to the accepted look of the film, not to the site
   palette. The engine itself paints with the same values. The colour gate
   exempts exactly these declarations and nothing else.

   PART 2 is the site's own: the loading poster, the hooks the engine needs
   but the page no longer shows, and one override that keeps the film
   full-window to its end. Nothing in Part 2 is animated. All copy over the
   picture is a separate layer: film.css. */

/* ---------------- PART 1: ported from the runtime ---------------- */

.cinematic {
  position: relative;
  height: 100vh;
  background: var(--graphite);
}

.cinematic__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: #191615;
  color: var(--ivory);
  isolation: isolate;
}

.cinematic__wash {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: var(--ivory);
  opacity: var(--wash-opacity, 0);
  pointer-events: none;
  transition: none;
}

.cinematic__frame {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #181413;
  box-shadow: 0 28px 80px rgba(16, 12, 11, 0);
  transform: translateZ(0);
  will-change: top, left, width, height, border-radius, box-shadow;
}

.hero-video,
.hero-canvas {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  background: #181413;
  image-rendering: auto;
}

.frame-sheen {
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(110deg, rgba(17, 12, 11, 0.08), transparent 38%, rgba(17, 12, 11, 0.18));
  mix-blend-mode: multiply;
}

.arrival-copy {
  position: absolute;
  z-index: 6;
  top: 28.5%;
  left: 58%;
  max-width: 390px;
  color: var(--ivory);
  opacity: 1;
  transform: translate3d(0, 0, 0);
  will-change: opacity, transform;
}

.editorial-heading {
  position: absolute;
  z-index: 7;
  top: 30vh;
  right: 7vw;
  left: 66%;
  display: flex;
  flex-direction: column;
  gap: 23px;
  color: var(--graphite);
  opacity: 0;
  transform: translateY(18px);
  pointer-events: none;
  will-change: opacity, transform;
}

body.motion-reduced .cinematic {
  height: 100vh;
}

body.motion-reduced .cinematic__pin {
  position: relative;
}

body.motion-reduced .arrival-copy,
body.motion-reduced .arrival-footer {
  opacity: 1 !important;
  transform: none !important;
}

body.motion-reduced .timeline-meter,
body.motion-reduced .editorial-caption,
body.motion-reduced .editorial-heading,
body.motion-reduced .handoff-marker {
  display: none;
}

/* ---------------- PART 2: the site's own ---------------- */

/* The film starts at the very top of the page, under the navigation, exactly
   as it sat under the prototype's header. The engine measures from there. */
.page-home main {
  padding-top: 0;
}

/* The engine writes its loading and error wording here. It is not shown
   (owner default: hide developer status text). The element stays because the
   engine needs it, and its "is-ready" class is the signal used just below. */
.video-status {
  display: none;
}

/* First frame, shown only until the engine has drawn its own first frame. */
.cinematic__poster {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

.video-status.is-ready ~ .cinematic__poster {
  display: none;
}

/* THE FILM STAYS FULL-WINDOW TO ITS END (owner ruling 2026-10-03, 8:32 PM,
   items 4 and 5: "keep the cinematic full-frame"; "avoid the current
   intermediate state where the cinematic contracts left").

   Over the last tenth of its travel the engine writes a smaller box onto the
   frame as inline styles (left, top, width, height, a radius and a shadow).
   The engine is locked and is not edited. These six declarations outrank its
   inline values, so the frame keeps the full window while the engine goes on
   running exactly as before: the same frame requests, the same scroll
   mapping, the same values written. Only what the frame's box looks like in
   that last stretch changes. This is the one place the site overrides
   something the engine writes; the gate "runtime" holds these six
   declarations and no others. */
.page-home .cinematic__frame {
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* The film layer: the site's own copy over the cinematic, and its timing.
   Rulings: docs/rulings/2026-10-03_ruling-home-choreography.txt (5:43 PM),
   docs/rulings/2026-10-03_ruling-home-refinement.txt (8:32 PM, after the
   owner's review on his own Mac) and
   docs/rulings/2026-10-03_ruling-home-lock-pass.txt (11:22 PM and 11:49 PM:
   the identity's place, the source line off Home, the question's place).
   Where they differ the later one rules.
   Record, timing table and reasons: docs/HOME-CHOREOGRAPHY.md.

   WHAT THIS FILE MAY DO. It places and moves the site's own elements (class
   names beginning "film"). It does not style, read or move anything the
   engine owns, and the gate "runtime" fails the build if a selector here
   names a stage element. The engine stays the only script on the stage and
   the only animation loop on the page.

   HOW IT MOVES. CSS scroll timelines only. One ruler (.film-ruler) lies
   exactly over the cinematic section; its "contain 0%" to "contain 100%"
   range is the engine's own progress, 0 to 1, because both are the section's
   scroll travel. Every percentage below is therefore engine progress times
   100, and can be read against the engine's scroll stops directly. No clock
   time is involved anywhere: stop scrolling and everything stops.

   WHERE SCROLL TIMELINES ARE MISSING (and for reduced motion) the layer is
   not shown at all. Every line is still in the page for assistive technology
   and crawlers (the block after the pin in pages/index.html). The opening
   identity is the exception: it sits in the engine's opening slot and is
   shown, held and faded by the engine in every browser. */

.film,
.film-ruler {
  display: none;
}

/* Text colours over the picture, set together like the other surfaces. No
   ground of its own: the picture is the ground, protected by the mask. */
.surface-film {
  color: var(--ivory);
  --accent: var(--gold);
  --muted: var(--ivory-72);
  --focus: var(--gold);
}

/* ==========================================================================
   1. The opening identity (ruling of 8:32 PM, item 1)
   SHIRIN ATAIE / LOS ANGELES · REAL ESTATE, and nothing else, at landing.
   It lives in the engine's opening slot, so the engine shows it from the
   first paint and fades it as scrolling begins. The site adds one thing: a
   gentle drift to the right, against the leftward travel of the picture.
   ========================================================================== */
.film-id {
  position: relative;
  margin-top: 7vh;
  white-space: nowrap;
}

/* A soft pool of graphite behind the two lines; no edge. It runs off the
   picture on the right at a fraction of its strength. */
.film-id::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -30vh -34vw -34vh -20vw;
  background: radial-gradient(
    closest-side,
    rgb(37 37 38 / 0.56) 0%,
    rgb(37 37 38 / 0.5) 26%,
    rgb(37 37 38 / 0.36) 48%,
    rgb(37 37 38 / 0.18) 68%,
    rgb(37 37 38 / 0.05) 86%,
    rgb(37 37 38 / 0) 100%
  );
  pointer-events: none;
}

/* The name, as on the brand sheet: Bodoni capitals, open tracking. Held
   small: it establishes, it does not announce. Its size is named on the
   block so the placement in the desk rule below can be measured in it. */
.film-id {
  --film-id-size: clamp(1.75rem, 3.1vw, 3.5rem);
}

.film-id__name {
  font-family: var(--font-display);
  font-size: var(--film-id-size);
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 14;
  line-height: 1.05;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Place and profession, set as the locked source line is set: Manrope
   capitals, wide tracking, a middle dot. */
.film-id__line {
  margin-top: clamp(0.9rem, 1.3vw, 1.4rem);
  padding-left: 0.2em;
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0.26em;
  text-transform: uppercase;
}

/* THE IDENTITY ON A DESK-SHAPED WINDOW (owner rulings of 2026-10-03: 11:22 PM,
   item 1, and the photograph sent at 11:49 PM with "this is the exact
   placement ... match this exactly"; the photograph is in docs/rulings/).

   A desk-shaped window, here and in next.css, is one at least 960 px wide and
   at least 9/8 as wide as it is tall. Every other window (a phone, a tablet
   held upright, a narrow or tall browser window) keeps the identity exactly
   as it was approved at 8:32 PM: the same ruling lists responsive behaviour
   among the things not to touch.

   What the photograph shows, measured letter by letter against this build's
   own type (docs/HOME-CHOREOGRAPHY.md has the figures):
     - the name set close: its letters are at their natural spacing, where
       the build had 0.14 em between them. Same size, weight and cut.
     - the name standing in the right-hand door leaf: its S just right of the
       centre seam, the right edge of its final E on the black door frame,
       about three quarters of the way across it.
     - the second line set flush right under the name, ending a little short
       of the E, and nearer the name than it was. Same size and spacing.

   SETTING. */
@media (min-width: 960px) and (min-aspect-ratio: 9/8) {
  .film-id {
    width: max-content;
    text-align: right;
  }

  .film-id__name {
    letter-spacing: 0.01em;
  }

  .film-id__line {
    margin-top: calc(var(--film-id-size) * 0.19);
    padding-right: 0.4em;
    padding-left: 0;
  }
}

/* PLACEMENT. The frame is part of the picture, so the line the E stands on is
   computed the way the picture is laid out. The canvas covers the window from
   its centre: the picture is as wide as the window, or 16/9 of its height,
   whichever is the greater. In the film's first frame the black frame runs
   from 75.47 to 77.81 percent of the way across the picture; three quarters
   of the way across it is 77.2 percent, which is 27.2 percent of the
   picture's width right of the window's centre. --film-id-trail is what lies
   between the E's ink and the block's own right edge (the letter's side
   bearing and the spacing that follows it), measured on the rendered name.

   HEIGHT. In the photograph the name's baseline stands 86 percent of the way
   down from the top of the door leaf to the tops of the handles, so that
   both lines clear the handles. In the first frame that is 36.0 percent of
   the way down the picture, which is 14 percent of the picture's height
   above the window's middle; the picture's height is 9/16 of its width. The
   name's baseline is 0.8737 of its size below the top of its box, and the
   engine's slot starts 28.5 percent of the way down the window. (Before the
   photograph the block stood 7vh below the slot's top, about one capital's
   height lower.)

   The block is taken out of the flow of the engine's slot so that it can be
   placed by its right edge. The slot itself (the engine's, at 58 percent) is
   not touched; the engine still fades and lifts it, and the drift is as it
   was. The rule applies where the frame can be met inside the page margin,
   which is any window at least 9/8 as wide as it is tall. On a taller window
   the frame is outside the visible part of the picture, and the identity
   stays in the engine's slot, set as it was.

   A FLOOR. On a window so short and wide that the upper part of the door is
   cropped away (more than about three times as wide as it is tall), the
   door's place would put the name under the navigation bar. There the block
   stops one rem below the bar instead. The slot starts 28.5vh down the
   window, so that is var(--nav-h) + 1rem - 28.5vh in the slot's own terms.
   At every ordinary window the first value is the larger and rules. */
@media (min-width: 960px) and (min-aspect-ratio: 9/8) {
  /* The name never crosses the centre seam. From the seam's right edge to
     the line the E stands on is 19.9 percent of the picture's width, and the
     name is 6.97 of its own sizes wide, so it fits while its size is no more
     than 2.85 percent of the picture's width. Where the size it has always
     had is larger than that (a window wider than about 1.63 to 1 and
     narrower than about 1960 px: 8 percent smaller at most) it is held to
     that; everywhere else it is the size it was. */
  .film-id {
    --film-id-size: min(clamp(1.75rem, 3.1vw, 3.5rem), calc(0.028507 * max(100vw, 177.7778vh)));
    --film-id-trail: 0.05;
    --film-id-line: min(
      calc(50vw + 0.272 * max(100vw, 177.7778vh) + var(--film-id-size) * var(--film-id-trail)),
      calc(100vw - var(--gutter))
    );
    position: absolute;
    top: max(
      calc(21.5vh - 0.07875 * max(100vw, 177.7778vh) - var(--film-id-size) * 0.8737),
      calc(var(--nav-h) + 1rem - 28.5vh)
    );
    right: calc(58vw - var(--film-id-line));
    margin-top: 0;
  }
}

@media (max-width: 719px) {
  /* The engine's slot starts at 58 percent of the width, which is off a
     phone's screen for a line this long. The site's block is moved back to
     the left margin; the slot itself is not touched. */
  .film-id {
    margin-left: calc(var(--gutter) - 58vw);
  }

  .film-id::before {
    inset: -30vh -60vw -34vh -30vw;
  }
}

/* ==========================================================================
   2. The layer over the picture
   ========================================================================== */
.film {
  /* the locked headline size of the recognition panel, so the three proof
     moments share one scale */
  --film-size: clamp(3.25rem, 6.4vw, 7.25rem);
  --film-ratio: 0.6;
  --film-air: 0.3;
  /* the sideways feather of the mask: full under the copy, gone before the
     far edge */
  --film-feather: linear-gradient(
    to right,
    rgb(37 37 38) 0%,
    rgb(37 37 38) 50%,
    rgb(37 37 38 / 0.8) 60%,
    rgb(37 37 38 / 0.48) 70%,
    rgb(37 37 38 / 0.18) 80%,
    transparent 90%
  );
  position: absolute;
  z-index: 4;
  inset: 0;
  color: var(--ivory);
  pointer-events: none;
  /* Cuts everything in the layer off at the film's own edge. It matters for
     the bridge (section 6), which is fixed to the window and must be seen
     only where the film is. */
  clip-path: inset(0);
}

.film__beat,
.film__moment,
.film__veil,
.film__swell {
  position: absolute;
  inset: 0;
}

/* ---------- The mask: a feathered wash, never a box ----------
   .film__veil   graphite rising from the foot of the picture and falling
                 away sideways, deepest exactly where the type sits. A
                 gradient in both directions with no edge anywhere.
   .film__swell  the same wash, lighter and reaching higher (same sideways
                 feather). It is brought in only around the two soft camera
                 turns: it deepens just before and through the softest frames
                 and lets go as detail returns (ruling of 8:32 PM, item 3).
   .film__pool   a soft round pool behind copy that does not stand at the
                 foot of the picture (WELCOME HOME., the tagline, the
                 question).
   Nothing darkens the whole picture. */

/* --film-veil is the veil's strength at the foot of the picture; each moment
   sets its own, and no more than its type needs (measured against the film:
   docs/HOME-CHOREOGRAPHY.md). The shape is the same for all three, and it is
   measured in headline sizes above the foot of the copy, so the veil stays
   fitted to the type on a tall phone and on a short, wide window alike. */
.film__veil,
.film__swell {
  --s: var(--film-size);
  --foot: clamp(4.5rem, 15vh, 10rem);
  -webkit-mask-image: var(--film-feather);
  mask-image: var(--film-feather);
}

.film__veil {
  --v: var(--film-veil, 0.8);
  background: linear-gradient(
    to top,
    rgb(37 37 38 / var(--v)) 0,
    rgb(37 37 38 / calc(var(--v) * 0.98)) calc(var(--foot) + var(--s) * 1),
    rgb(37 37 38 / calc(var(--v) * 0.93)) calc(var(--foot) + var(--s) * 2),
    rgb(37 37 38 / calc(var(--v) * 0.82)) calc(var(--foot) + var(--s) * 3),
    rgb(37 37 38 / calc(var(--v) * 0.68)) calc(var(--foot) + var(--s) * 3.7),
    rgb(37 37 38 / calc(var(--v) * 0.44)) calc(var(--foot) + var(--s) * 4.5),
    rgb(37 37 38 / calc(var(--v) * 0.22)) calc(var(--foot) + var(--s) * 5.3),
    rgb(37 37 38 / calc(var(--v) * 0.07)) calc(var(--foot) + var(--s) * 6.1),
    rgb(37 37 38 / 0) calc(var(--foot) + var(--s) * 6.9)
  );
}

/* The swell is lighter than the veil and about two fifths taller. */
.film__swell {
  --v: var(--film-swell, 0.3);
  background: linear-gradient(
    to top,
    rgb(37 37 38 / var(--v)) 0,
    rgb(37 37 38 / calc(var(--v) * 0.96)) calc(var(--foot) + var(--s) * 2.5),
    rgb(37 37 38 / calc(var(--v) * 0.82)) calc(var(--foot) + var(--s) * 4.2),
    rgb(37 37 38 / calc(var(--v) * 0.56)) calc(var(--foot) + var(--s) * 5.8),
    rgb(37 37 38 / calc(var(--v) * 0.28)) calc(var(--foot) + var(--s) * 7.2),
    rgb(37 37 38 / calc(var(--v) * 0.08)) calc(var(--foot) + var(--s) * 8.6),
    rgb(37 37 38 / 0) calc(var(--foot) + var(--s) * 9.8)
  );
}

.film__pool {
  --v: var(--film-pool, 0.6);
  position: absolute;
  top: calc(var(--pool-y) - var(--pool-h) / 2);
  left: calc(var(--pool-x) - var(--pool-w) / 2);
  width: var(--pool-w);
  height: var(--pool-h);
  background: radial-gradient(
    closest-side,
    rgb(37 37 38 / var(--v)) 0%,
    rgb(37 37 38 / calc(var(--v) * 0.92)) 24%,
    rgb(37 37 38 / calc(var(--v) * 0.68)) 46%,
    rgb(37 37 38 / calc(var(--v) * 0.36)) 66%,
    rgb(37 37 38 / calc(var(--v) * 0.11)) 85%,
    rgb(37 37 38 / 0) 100%
  );
}

/* ==========================================================================
   3. WELCOME HOME. (ruling of 8:32 PM, item 2)
   Arrives only as the front doors open, about where the identity's drift
   ends. The quickest beat of the film.
   ========================================================================== */
.film__beat--welcome {
  --pool-x: 76vw;
  --pool-y: calc(28.5% + 40px + var(--film-welcome) * 1);
  --pool-w: 84vw;
  --pool-h: 104vh;
  --film-pool: 0.66;
  --film-welcome: clamp(3.25rem, 6vw, 7.25rem);
}

.film__welcome {
  position: absolute;
  top: calc(28.5% + 40px);
  /* close to where the identity's drift ends (58 percent plus 5vw, so 63) */
  left: 62%;
  font-family: var(--font-display);
  font-size: var(--film-welcome);
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 16;
  line-height: 1;
  letter-spacing: 0.012em;
  white-space: nowrap;
}

/* ==========================================================================
   4. The three proof moments
   ========================================================================== */

/* Where the copy sits. The slot is the recognition panel's own geometry laid
   over the picture: it starts under the navigation and the copy hangs from
   its foot. */
.film__slot {
  position: absolute;
  top: var(--nav-h);
  right: 0;
  bottom: 0;
  left: 0;
}

.film__frame {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
  padding-block: var(--space-6) clamp(4.5rem, 15vh, 10rem);
}

/* The second moment stands on the film's other axis, the 58 percent line.
   The copy alternates sides down the film: right, left, right, left, right. */
.film__frame--right {
  padding-inline: 58% var(--gutter);
}

.film__moment--two {
  --film-feather: linear-gradient(
    to left,
    rgb(37 37 38) 0%,
    rgb(37 37 38) 44%,
    rgb(37 37 38 / 0.8) 53%,
    rgb(37 37 38 / 0.48) 62%,
    rgb(37 37 38 / 0.18) 71%,
    transparent 80%
  );
}

/* The type: one family with the locked panel. Headline as the locked
   headline (Bodoni Moda 500, capitals, the same size, tracking and optical
   size). Supporting line as the locked supporting line, at a ratio each
   moment sets for itself. */
.film__headline,
.film__support {
  font-family: var(--font-display);
  font-optical-sizing: none;
}

.film__headline {
  font-size: var(--film-size);
  font-weight: 500;
  font-variation-settings: "opsz" 16;
  line-height: 1;
  letter-spacing: 0.012em;
}

.film__support {
  margin-top: calc(var(--film-size) * var(--film-air));
  font-size: calc(var(--film-size) * var(--film-ratio));
  font-weight: 400;
  font-variation-settings: "opsz" 14;
  line-height: 1.14;
  text-wrap: balance;
}

/* Moment one: a two-line headline and, as ruled, a smaller supporting line.
   At this size the line is set a step sturdier so its hairlines hold over a
   moving picture. */
.film__moment--one {
  --film-ratio: 0.32;
  --film-air: 0.34;
  --film-veil: 0.72;
}

.film__moment--one .film__support {
  font-size: max(1.125rem, calc(var(--film-size) * var(--film-ratio)));
  font-weight: 500;
  font-variation-settings: "opsz" 10;
  line-height: 1.3;
}

.film__moment--two {
  --film-ratio: 0.52;
  --film-veil: 0.72;
}

/* Moment three. Its veil was set for the small gold source line the locked
   panel carries; it is left as it was. */
.film__moment--three {
  --film-veil: 0.93;
}

/* On Home the panel stands without its source line (owner ruling 2026-10-03,
   11:22 PM, item 3: "remove only that source line ... do not change the
   headline or supporting line"). The panel hangs from the foot of its slot,
   so with the line gone its two remaining lines would settle lower. The slot
   is raised by exactly what the line took up (its gap above, 1.45 headline
   sizes, and its own line box, 1.1rem), so the headline and the supporting
   line stand exactly where they stood. The locked stylesheet is not touched. */
.film__moment--three .film__slot {
  --film-source-room: calc(var(--film-size) * 1.45 + 1.1rem);
  top: calc(var(--nav-h) - var(--film-source-room));
  bottom: var(--film-source-room);
}

/* ==========================================================================
   5. The tagline (ruling of 8:32 PM, item 4)
   Inside the full-window flute frame, in the clear sky on the right. No name,
   no second sentence.
   ========================================================================== */
.film__beat--tagline {
  --pool-x: 76vw;
  --pool-y: calc(var(--film-tag-top) + var(--film-tag) * 1.15);
  --pool-w: 92vw;
  --pool-h: 96vh;
  --film-pool: 0.61;
  --film-tag: clamp(1.75rem, 3.3vw, 3.75rem);
  --film-tag-top: clamp(8.5rem, 23vh, 16rem);
}

.film__tagline {
  position: absolute;
  top: var(--film-tag-top);
  left: 58%;
  font-family: var(--font-display);
  font-size: var(--film-tag);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 14;
  line-height: 1.16;
  white-space: nowrap;
}

/* ==========================================================================
   6. The bridge (ruling of 8:32 PM, item 5; its place on a desk-shaped
   window by the ruling of 11:22 PM, item 5)
   "What's next?" rises into its place (upper right on a desk-shaped window,
   the centre of the window otherwise) over the last of the film. It is fixed
   to the window, not to the film, so when the film lets go and travels up, the question stays where it is. The layer's clip (section
   2) shows this ivory copy only where the film still is; the real heading,
   in graphite, stands on the same spot in the section below and is shown
   only where that section is. The question turns from ivory to graphite
   along the film's own edge. Type and position are next.css's, shared by
   both copies (.next__question, .film__question).
   ========================================================================== */
.film__bridge {
  position: fixed;
  inset: 0;
  --pool-x: 50vw;
  --pool-y: 50vh;
  --pool-w: 124vw;
  --pool-h: 76vh;
  --film-pool: 0.7;
}

/* On a desk-shaped window the question stands upper right (ruling of 11:22 PM,
   item 5; placement in next.css). Its pool goes with it: same size and
   strength, centred on the word. The word is 5.98 of its own sizes wide.
   100% is the width of the bridge, which is the page's width without a
   scrollbar's own; --next-right is measured from the same edge. */
@media (min-width: 960px) and (min-aspect-ratio: 9/8) {
  .film__bridge {
    --pool-x: calc(100% - var(--next-right) - var(--next-size) * 2.99);
    --pool-y: 28vh;
  }
}

@media (max-width: 719px) {
  .film {
    --film-size: clamp(2.25rem, 10.4vw, 3.25rem);
    --film-feather: none;
  }

  .film__moment--two {
    --film-feather: none;
  }

  .film__moment--one {
    --film-ratio: 0.44;
  }

  /* the locked panel's phone optical sizes, so the family holds on a phone */
  .film__headline {
    font-variation-settings: "opsz" 12;
  }

  .film__support {
    font-variation-settings: "opsz" 10;
  }

  /* One column on a phone: every moment stands on the left edge, and lines
     wrap, so the copy stands taller for its size: the veil is stretched to
     match. */
  .film__frame--right {
    padding-inline: var(--gutter);
  }

  .film__veil,
  .film__swell {
    --s: calc(var(--film-size) * 1.3);
  }

  /* the locked panel's phone gap above its source line: 1.56 headline sizes */
  .film__moment--three .film__slot {
    --film-source-room: calc(var(--film-size) * 1.56 + 1.1rem);
  }

  .film__welcome,
  .film__tagline {
    left: var(--gutter);
  }

  .film__tagline {
    white-space: normal;
  }

  /* on a phone the line stands over the lit windows, not the door leaf, so
     its pool is a step deeper */
  .film__beat--welcome {
    --pool-x: 40vw;
    --pool-w: 190vw;
    --film-pool: 0.78;
  }

  .film__beat--tagline {
    --pool-x: 44vw;
    --pool-w: 200vw;
    --film-tag: clamp(1.75rem, 8vw, 2.5rem);
  }

  .film__bridge {
    --pool-w: 240vw;
  }
}

/* Between a phone and a desk (a tablet held upright) the right-hand column is
   too narrow for display capitals at their smallest size: WELCOME and
   PRODUCER would touch the edge. The right-hand pieces start nearer the
   centre line there, and their masks follow. */
@media (min-width: 720px) and (max-width: 959px) {
  .film__welcome {
    left: 50%;
  }

  /* here the line stands over the lit windows, as on a phone */
  .film__beat--welcome {
    --pool-x: 68vw;
    --pool-w: 124vw;
    --film-pool: 0.76;
  }

  .film__frame--right {
    padding-inline: 50% var(--gutter);
  }

  .film__moment--two {
    --film-feather: linear-gradient(
      to left,
      rgb(37 37 38) 0%,
      rgb(37 37 38) 52%,
      rgb(37 37 38 / 0.8) 61%,
      rgb(37 37 38 / 0.48) 70%,
      rgb(37 37 38 / 0.18) 79%,
      transparent 88%
    );
  }

  .film__tagline {
    left: 52%;
  }

  .film__beat--tagline {
    --pool-x: 72vw;
    --pool-w: 104vw;
  }
}

/* ==========================================================================
   7. Timing
   --in-a / --in-b    the scroll range over which a piece arrives
   --out-a / --out-b  the range over which it leaves
   All four are engine progress in percent, written out for every piece.

   Frames, for reading against the film (engine stops):
     the identity has all but gone (under 4 percent)   17.5
     the front doors begin to open        frame  40           15.6
     soft stretch A, foyer into great room          frames  78 to 111   30.0 to 42.9
       its softest frames                           frames  84 to  99   32.3 to 38.2
     soft stretch B, past the kitchen to the terrace frames 141 to 158   55.3 to 62.5
       its softest frames                           frames 144 to 156   56.6 to 61.7
     the first sliver of Shirin shows               frame  177          70.4
     she has settled with the flute                 frame  204          78.5
     the engine's last stretch (the film is held)                       89.5 to 100

   THE THREE PROOF MOMENTS ARE EQUAL (ruling of 8:32 PM, item 3). Each one,
   measured from its own start s:
     veil arrives         s        to s +  2.5
     first line arrives   s +  0.6 to s +  3.1
     last line settles                 s +  5.1     entrance: 4.5
     readable hold        s +  5.1 to s + 11.3      hold:     6.2
     type leaves          s + 11.3 to s + 13.8      exit:     2.5
     veil gone                          s + 14.6    total:   14.6
   s is 26.6, 41.2 and 55.8: one after another, with nothing between. The
   gate "film" recomputes lead, entrance, hold, exit and total for each moment
   and fails if any differs.
   ========================================================================== */

/* WELCOME HOME.: the quickest beat. Type 7.6 in all (2.6 of it fully
   there); 8.9 with its pool. */
.film__beat--welcome .film__pool {
  --in-a: 17%;
  --in-b: 19.5%;
  --out-a: 23.4%;
  --out-b: 25.9%;
}

.film__welcome {
  --in-a: 17.5%;
  --in-b: 20%;
  --out-a: 22.6%;
  --out-b: 25.1%;
}

/* Proof 1, s = 26.6 */
.film__moment--one .film__veil {
  --in-a: 26.6%;
  --in-b: 29.1%;
  --out-a: 38.7%;
  --out-b: 41.2%;
}

.film__moment--one .film__headline {
  --in-a: 27.2%;
  --in-b: 29.7%;
  --out-a: 37.9%;
  --out-b: 40.4%;
}

.film__moment--one .film__support {
  --in-a: 29.2%;
  --in-b: 31.7%;
  --out-a: 37.9%;
  --out-b: 40.4%;
}

/* the swell for soft stretch A: in just before its softest frames, out as
   detail returns */
.film__moment--one .film__swell {
  --in-a: 30%;
  --in-b: 32.3%;
  --out-a: 38.2%;
  --out-b: 41.2%;
}

/* Proof 2, s = 41.2. No swell: these are the crispest frames indoors. */
.film__moment--two .film__veil {
  --in-a: 41.2%;
  --in-b: 43.7%;
  --out-a: 53.3%;
  --out-b: 55.8%;
}

.film__moment--two .film__headline {
  --in-a: 41.8%;
  --in-b: 44.3%;
  --out-a: 52.5%;
  --out-b: 55%;
}

.film__moment--two .film__support {
  --in-a: 43.8%;
  --in-b: 46.3%;
  --out-a: 52.5%;
  --out-b: 55%;
}

/* Proof 3, s = 55.8. It is the locked BusinessRate panel's headline and
   supporting line, declaration for declaration (recognition.css); the source
   line is not shown on Home (ruling of 11:22 PM). With two lines it is timed
   exactly as Proofs 1 and 2 are: headline at s + 0.6, supporting line at
   s + 2.6, so entrance, hold, exit and total stay equal across the three.
   The two rules for its lines move them in and out and set nothing else; the
   gate "film" holds them to motion properties only. */
.film__moment--three .film__veil {
  --in-a: 55.8%;
  --in-b: 58.3%;
  --out-a: 67.9%;
  --out-b: 70.4%;
}

.film__moment--three p:nth-child(1) {
  --in-a: 56.4%;
  --in-b: 58.9%;
  --out-a: 67.1%;
  --out-b: 69.6%;
}

.film__moment--three p:nth-child(2) {
  --in-a: 58.4%;
  --in-b: 60.9%;
  --out-a: 67.1%;
  --out-b: 69.6%;
}

/* the swell for soft stretch B: in just before its softest frames, out as
   the terrace comes into focus */
.film__moment--three .film__swell {
  --in-a: 54.6%;
  --in-b: 56.6%;
  --out-a: 61.7%;
  --out-b: 64.2%;
}

/* The tagline: after she has settled with the flute; gone before the
   question arrives. */
.film__beat--tagline .film__pool {
  --in-a: 79%;
  --in-b: 82%;
  --out-a: 90.5%;
  --out-b: 93%;
}

.film__tagline {
  --in-a: 79.5%;
  --in-b: 83%;
  --out-a: 90%;
  --out-b: 92.5%;
}

/* The bridge arrives and does not leave: the film leaves from under it. */
.film__bridge .film__pool {
  --in-a: 91.5%;
  --in-b: 95.5%;
}

@keyframes film-veil-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes film-veil-out {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}

@keyframes film-text-in {
  from {
    opacity: 0;
    transform: translate3d(0, 22px, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes film-text-out {
  from {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }

  to {
    opacity: 0;
    transform: translate3d(0, -12px, 0);
  }
}

/* the identity's drift: to the right, against the picture's travel */
@keyframes film-drift {
  from {
    transform: translate3d(0, 0, 0);
  }

  to {
    transform: translate3d(5vw, 0, 0);
  }
}

@supports (animation-timeline: view()) and (timeline-scope: --film) {
  body.page-home {
    timeline-scope: --film;
  }

  .film-ruler {
    display: block;
    position: absolute;
    inset: 0;
    visibility: hidden;
    pointer-events: none;
    view-timeline-name: --film;
    view-timeline-axis: block;
    /* 0, not the default "auto": auto would take the page's scroll-padding
       (the navigation's height) off the range and shift every percentage. */
    view-timeline-inset: 0;
  }

  .film {
    display: block;
  }

  .film__veil,
  .film__swell,
  .film__beat .film__pool {
    animation-name: film-veil-in, film-veil-out;
    animation-timing-function: linear;
    animation-fill-mode: both, forwards;
    animation-timeline: --film, --film;
    animation-range: contain var(--in-a) contain var(--in-b), contain var(--out-a) contain var(--out-b);
  }

  .film__welcome,
  .film__headline,
  .film__support,
  .film__moment--three p,
  .film__tagline {
    animation-name: film-text-in, film-text-out;
    animation-timing-function: linear;
    animation-fill-mode: both, forwards;
    animation-timeline: --film, --film;
    animation-range: contain var(--in-a) contain var(--in-b), contain var(--out-a) contain var(--out-b);
  }

  .film__bridge .film__pool {
    animation-name: film-veil-in;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: --film;
    animation-range: contain var(--in-a) contain var(--in-b);
  }

  /* From the first movement of the scroll to the point where the engine has
     faded the opening slot out (19). The engine fades it; this only carries
     it to the right. */
  .film-id {
    animation-name: film-drift;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: --film;
    animation-range: contain 0% contain 19%;
  }

  /* Reduced motion: the engine holds the film on its first frame and the
     section is one window high, so there is no travel to time anything
     against. The layer stays off, exactly as where timelines are missing. */
  @media (prefers-reduced-motion: reduce) {
    .film,
    .film-ruler {
      display: none;
    }

    .film-id {
      animation-name: none;
    }
  }
}

/* After the film: "What's next?", then the way in.
   Rulings: docs/rulings/2026-10-03_ruling-home-choreography.txt (5:43 PM),
   docs/rulings/2026-10-03_ruling-home-refinement.txt (8:32 PM) and
   docs/rulings/2026-10-03_ruling-home-lock-pass.txt (11:22 PM); the later
   one rules. Copy: builder brief, Homepage conversion.
   Record: docs/HOME-CHOREOGRAPHY.md.

   THE BRIDGE. "What's next?" is one question in two copies, set on exactly
   the same spot: upper right on a desk-shaped window (the block "Home on a
   desk-shaped window" below), the middle of the window everywhere else. The ivory copy belongs to the film (film.css) and is seen
   only where the film is. The graphite copy is this section's real heading
   and is seen only where this section is. As the film travels up and away,
   its lower edge passes through the question and the question turns from
   ivory to graphite along that edge. The question then holds in its place on
   the ivory page while the sentence and the sign come up to meet it.

   THE SIGN (.sign) is locked for Home. The line (.cta-line) and the plate
   (.cta-plate) are kept on /_review/cta/ as a record; neither is on Home. */

/* The question's size and its place, for both copies. */
.next,
.film__bridge {
  --next-size: clamp(3.25rem, 8.6vw, 9.5rem);
  --next-top: calc(50vh - var(--next-size) * 0.5);
}

.next {
  /* how far the page travels while the question holds in its place */
  --next-hold: 105vh;
  position: relative;
  z-index: 1;
  /* a formatting context of its own, so the lift's upward margin stays
     inside the section instead of pulling the section up over the film */
  display: flow-root;
  /* nothing of this section is ever seen above its own top edge: that is
     what cuts the graphite question off where the film still is */
  overflow: clip;
}

/* Ruling of 8:32 PM, item 6: stronger and easier to read, same family.
   Bodoni Moda at weight 500 with the optical size pinned low, which is what
   thickens its hairlines (docs/TYPOGRAPHY.md). */
.next__question,
.film__question {
  font-family: var(--font-display);
  font-size: var(--next-size);
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 20;
  line-height: 1;
  letter-spacing: 0;
  text-align: center;
  white-space: nowrap;
}

.film__question {
  position: absolute;
  top: var(--next-top);
  right: 0;
  left: 0;
}

/* The lift is the track the question holds in. It starts above the section's
   top edge by as much as the question's place is short of a full window, so
   that at the moment the film lets go the heading is already standing in its
   place. (For a question in the middle of the window this is the value it
   always was: 50vh less half a line, less 100vh.) */
.next__lift {
  margin-top: calc(var(--next-top) - 100vh);
}

.next__lift::after {
  content: "";
  display: block;
  height: var(--next-hold);
}

.next__question {
  position: sticky;
  top: var(--next-top);
}

.next__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: var(--space-4);
  padding-top: var(--space-4);
}

.next__copy {
  padding-bottom: clamp(9rem, 30vh, 18rem);
}

/* Supporting copy: larger, full graphite, a tighter measure. */
.next__sentence {
  max-width: 17em;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.35vw, 2.5rem);
  font-weight: 500;
  font-optical-sizing: none;
  font-variation-settings: "opsz" 11;
  line-height: 1.26;
  text-wrap: pretty;
}

.next__call {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  min-height: 44px;
  margin-top: var(--space-4);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.next__call a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-bottom: 1px solid currentColor;
  color: var(--graphite);
}

.next__action {
  display: flex;
  align-self: end;
  justify-content: flex-end;
}

/* Call Shirin, the second way in (refinements round and sitewide call ruling, 2026-10-10). One link: the words in
   Display M over the number, which comes from the site's contact data. The call line's row and its locked place are
   untouched: the link stands in that row, and on a desk-shaped window (below) it reaches up over the room above the
   row rather than making the row taller. */
a.home-call,
.home-call {
  display: inline-grid;
  justify-items: start;
  min-height: 44px;
  border-bottom: 0;
  color: var(--graphite);
  letter-spacing: 0;
  text-transform: none;
  transition: color var(--dur-ui) var(--ease-silk);
}

.home-call {
  --home-call-size: clamp(2rem, 4.6vw, 4.25rem);
}

.home-call__words {
  display: block;
  font-size: var(--home-call-size);
  line-height: 1.06;
  white-space: nowrap;
}

.home-call__number {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-ui);
  font-size: clamp(1rem, 1.2vw, 1.25rem);
  font-weight: 600;
  letter-spacing: 0.1em;
}

a.home-call:hover,
a.home-call:focus-visible {
  color: var(--aubergine);
}

/* The one light: when the call line comes into view (the site's own reveal marks it), a single band of gold passes
   across the words, once, the way light passes over a work on the Lit Wall. The words are clipped to a gradient that
   is graphite on both sides of the band; only while the light passes are they painted from it (the transparent fill
   lives in the keyframes), so before and after they are ordinary graphite lettering. Never with reduced motion, and
   never where the system forces its own colours. */
@media (prefers-reduced-motion: no-preference) and (forced-colors: none) {
  .home-call.is-revealed .home-call__words {
    background-image: linear-gradient(105deg, var(--graphite) 0 40%, var(--gold) 50%, var(--graphite) 60% 100%);
    background-size: 300% 100%;
    background-position: 0 0;
    -webkit-background-clip: text;
    background-clip: text;
    animation: home-call-light 2600ms ease-in-out 600ms 1 backwards;
  }
}

@keyframes home-call-light {
  from {
    background-position: 100% 0;
    -webkit-text-fill-color: transparent;
  }

  to {
    background-position: 0 0;
    -webkit-text-fill-color: transparent;
  }
}

/* ---------- The sign (LOCKED for Home: ruling of 2026-10-03, 8:32 PM) ----------
   A white post sign, drawn as a line drawing in the brand's own colours: the
   post, the arm, the hanging board and, beneath it, the rider that carries
   the words to act on. The board reads FOR SALE and turns over to SOLD.

   It turns on hover and on keyboard focus. Where there is no hover (touch),
   it turns once, by itself, shortly after it comes into view. With reduced
   motion the two faces cross-fade and nothing rotates.

   All sizes are in em, so one font-size scales the whole sign. */
.sign {
  --sign-line: var(--graphite);
  position: relative;
  display: block;
  width: 20.5em;
  height: 27.5em;
  font-size: clamp(0.875rem, 1.3vw, 1.25rem);
  color: var(--graphite);
}

.sign__post,
.sign__arm,
.sign__post::before {
  position: absolute;
  border: 1px solid var(--sign-line);
  background: var(--ivory);
}

.sign__post {
  top: 1.1em;
  right: 2.4em;
  bottom: 0;
  width: 0.8em;
  border-bottom: 0;
}

/* the cap on the post */
.sign__post::before {
  content: "";
  top: -0.75em;
  left: -0.3em;
  width: 1.4em;
  height: 0.75em;
  margin-left: -1px;
}

.sign__arm {
  top: 4.2em;
  right: 0.6em;
  left: 0;
  height: 0.6em;
}

.sign__hang {
  position: absolute;
  top: 4.8em;
  left: 1.5em;
  width: 14.5em;
  padding-top: 1.5em;
  perspective: 70em;
}

/* the two hangers between arm and board, and between board and rider */
.sign__hang::before,
.sign__hang::after,
.sign__rider::before,
.sign__rider::after {
  content: "";
  position: absolute;
  width: 1px;
  background: var(--sign-line);
}

.sign__hang::before,
.sign__hang::after {
  top: 0;
  height: 1.5em;
}

.sign__hang::before,
.sign__rider::before {
  left: 16%;
}

.sign__hang::after,
.sign__rider::after {
  right: 16%;
}

.sign__panel {
  position: relative;
  display: block;
  height: 9.4em;
  transform-style: preserve-3d;
  transition: transform 950ms var(--ease-silk);
}

.sign__face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--sign-line);
  background: var(--ivory);
  font-family: var(--font-display);
  font-size: 1.95em;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.14em;
  /* tracking trails the last letter; lead the first by the same to centre it */
  padding-left: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* a fine keyline inside the board, as a painted sign has */
.sign__face::after {
  content: "";
  position: absolute;
  inset: 0.28em;
  border: 1px solid var(--gold);
}

.sign__face--back {
  border-color: var(--aubergine);
  background: var(--aubergine);
  color: var(--gold);
  font-size: 2.7em;
  letter-spacing: 0.2em;
  padding-left: 0.2em;
  transform: rotateX(180deg);
}

.sign__face--back::after {
  inset: 0.2em;
}

.sign__rider {
  position: absolute;
  top: 16.6em;
  left: 1.5em;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 14.5em;
  height: 3.3em;
  min-height: 44px;
  background: var(--graphite);
  color: var(--ivory);
  transition: background-color var(--dur-ui) var(--ease-silk), color var(--dur-ui) var(--ease-silk);
}

.sign__label {
  font-family: var(--font-ui);
  font-size: clamp(0.625rem, 0.7em, 0.75rem);
  font-weight: 600;
  letter-spacing: 0.2em;
  /* tracking trails the last letter; lead the first by the same to centre it */
  padding-left: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
}

.sign__rider::before,
.sign__rider::after {
  bottom: 100%;
  height: 0.9em;
}

.sign:hover .sign__panel,
.sign:focus-visible .sign__panel {
  transform: rotateX(180deg);
}

/* Ruling of 2026-10-03, 8:32 PM, item 7: on hover and focus the rider's field
   turns to Regal Gold, with graphite lettering (6.81 to 1). */
.sign:hover .sign__rider,
.sign:focus-visible .sign__rider {
  background: var(--gold);
  color: var(--graphite);
}

@media (hover: none) {
  .sign.is-revealed .sign__panel {
    transform: rotateX(180deg);
    transition-delay: 1100ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sign__panel {
    transform: none !important;
    transition: none;
  }

  .sign__face {
    transition: opacity 240ms linear;
  }

  .sign__face--back {
    transform: none;
    opacity: 0;
  }

  .sign:hover .sign__face--back,
  .sign:focus-visible .sign__face--back {
    opacity: 1;
  }
}

/* ---------- Option B: the line (review page only) ----------
   No box at all. The words, a hairline, and an arrow that leans forward. */
.cta-line {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 0.6em;
  min-height: 44px;
  padding-bottom: 0.38em;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.3vw, 3.25rem);
  font-weight: 400;
  line-height: 1.1;
  color: var(--graphite);
  transition: color var(--dur-ui) var(--ease-silk);
}

.cta-line::before,
.cta-line::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: var(--graphite);
}

.cta-line::after {
  height: 2px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 700ms var(--ease-silk);
}

.cta-line__arrow {
  position: relative;
  display: inline-block;
  width: 1.1em;
  height: 1px;
  background: currentColor;
  transform: translateY(-0.3em);
  transition: transform 700ms var(--ease-silk);
}

.cta-line__arrow::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 0.34em;
  height: 0.34em;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
}

.cta-line:hover,
.cta-line:focus-visible {
  color: var(--aubergine);
}

.cta-line:hover::after,
.cta-line:focus-visible::after {
  transform: scaleX(1);
}

.cta-line:hover .cta-line__arrow,
.cta-line:focus-visible .cta-line__arrow {
  transform: translate(0.35em, -0.3em);
}

/* ---------- Option C: the plate (review page only) ----------
   A solid aubergine plate with gold lettering and an engraved keyline.
   On hover the plate turns to gold, bottom to top. */
.cta-plate {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 64px;
  padding: 0 3.25rem;
  background: linear-gradient(to top, var(--gold) 50%, var(--aubergine) 50%) 0 0 / 100% 200%;
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background-position 600ms var(--ease-silk), color 600ms var(--ease-silk);
}

.cta-plate::after {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid var(--gold-55);
  transition: border-color 600ms var(--ease-silk);
}

.cta-plate:hover,
.cta-plate:focus-visible {
  background-position: 0 100%;
  color: var(--aubergine);
}

.cta-plate:hover::after,
.cta-plate:focus-visible::after {
  border-color: var(--aubergine-55);
}

@media (prefers-reduced-motion: reduce) {
  .cta-line,
  .cta-line::after,
  .cta-line__arrow,
  .cta-plate,
  .cta-plate::after {
    transition-duration: 1ms;
  }
}

/* ---------- The question's rise, and what happens without it ---------- */

@keyframes next-rise {
  from {
    opacity: 0;
    transform: translate3d(0, 9vh, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@supports (animation-timeline: view()) and (timeline-scope: --film) {
  /* Both copies rise together, on the film's own ruler, over 92.5 to 96.5:
     after the tagline has gone and while the film is still held. */
  .page-home .next__question,
  .film__question {
    animation-name: next-rise;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: --film;
    animation-range: contain 92.5% contain 96.5%;
  }

  @media (prefers-reduced-motion: reduce) {
    .page-home .next__question {
      animation-name: none;
    }
  }
}

/* Without scroll timelines there is no ivory copy over the film, so the
   heading does not reach up over it: it simply opens the section. The same
   for reduced motion. */
@supports not ((animation-timeline: view()) and (timeline-scope: --film)) {
  .next__lift {
    margin-top: 0;
    padding-top: var(--space-6);
  }

  .next__lift::after {
    height: var(--space-4);
  }

  .next__question {
    position: static;
  }
}

@media (prefers-reduced-motion: reduce) {
  .next__lift {
    margin-top: 0;
    padding-top: var(--space-6);
  }

  .next__lift::after {
    height: var(--space-4);
  }

  .next__question {
    position: static;
  }
}

@media (max-width: 899px) {
  .next__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .next__copy {
    padding-bottom: var(--space-5);
  }

  .next__action {
    justify-content: flex-start;
  }

  .sign {
    font-size: clamp(0.8125rem, 3.6vw, 1rem);
  }
}

/* ---------- Home on a desk-shaped window: the locked composition ----------
   Owner ruling 2026-10-03, 11:22 PM, items 5 and 7. A desk-shaped window is
   one at least 960 px wide and at least 9/8 as wide as it is tall, the same
   test the opening identity uses (film.css). Every other window keeps the
   composition approved at 8:32 PM: the same ruling lists responsive behaviour
   among the things not to touch.

   THE QUESTION stands upper right, over the film and then on ivory, in one
   place: both copies use the same two values. Upper: its middle is 28 percent
   of the way down the window, in the sky where the tagline stood. Right: its
   right edge is the right edge of the sign's board and rider, so the question
   and the sign share one line and the post stands clear to the right of it.
   --next-sign-em is the sign's own unit (the font-size of .sign above); the
   board's right edge is 4.5 of them in from the page frame's edge, and the
   page frame is centred once the window is wider than --wrap-max. The 100%
   in --next-right is the width of the box the question stands in, which is
   the page's width without a scrollbar's own, so the question stays on the
   board's line where scrollbars take up room (Windows; a Mac with a mouse).
   --next-optical is the side bearing of the question mark, so that it is the
   ink of the mark, not its box, that meets the line.
   A floor: on a very short window 28 percent of the height would put the
   question under the navigation bar, so its box never starts above the foot
   of the bar. At every ordinary window the first value is the larger.

   CALL SHIRIN stands under the sentence, on the baseline of the rider's
   lettering. The rider's middle is 9.25 sign units above the foot of the
   sign, which is the foot of this row; the call line is a 44 px row with its
   lettering in the middle, so its foot is 22 px lower than that. The 1.15 px
   is the difference between the two baselines that comes from the two type
   sizes (13 px here, 12 px on the rider), measured on the rendered lines. The gap between the sentence and
   the call line takes up whatever the old bottom padding does not need, so
   the row is exactly as tall as it was. */
@media (min-width: 960px) and (min-aspect-ratio: 9/8) {
  .page-home .next,
  .film__bridge {
    --next-top: max(calc(28vh - var(--next-size) * 0.5), var(--nav-h));
    --next-sign-em: clamp(0.875rem, 1.3vw, 1.25rem);
    --next-optical: 0.045;
    --next-right: calc(
      max(0px, (100% - var(--wrap-max)) / 2) + var(--gutter) + var(--next-sign-em) * 4.5
      - var(--next-size) * var(--next-optical)
    );
    --next-call-foot: calc(var(--next-sign-em) * 9.25 - 22px + 1.15px);
  }

  .page-home .next__question {
    padding-right: var(--next-right);
    text-align: right;
  }

  .film__question {
    right: var(--next-right);
    text-align: right;
  }

  .page-home .next__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding-bottom: 0;
  }

  .page-home .next__sentence {
    margin-bottom: calc(var(--space-4) + clamp(9rem, 30vh, 18rem) - var(--next-call-foot));
  }

  .page-home .next__call {
    margin-top: auto;
    margin-bottom: var(--next-call-foot);
  }
}

/* Call Shirin on a desk-shaped window. The number keeps the call line's place, on the baseline of the rider's
   lettering; the words stand over it in the room between the sentence and the row. The link's top margin takes back
   exactly the words' height, so the row stays 44 px tall and nothing around it moves, while the link's own box (its
   focus ring and its touch area) still holds both lines. */
@media (min-width: 960px) and (min-aspect-ratio: 9/8) {
  .page-home .home-call {
    margin-top: calc(var(--home-call-size) * -1.06);
  }

  /* the number's lettering onto the rider's baseline (measured: centred in its 44 px row, the number's baseline
     sits 5 px above the rider's at every desk-shaped size) */
  .page-home .home-call__number {
    position: relative;
    top: 5px;
  }
}

/* ---------- Review page ---------- */

.next--static .next__lift {
  margin-top: 0;
  padding-top: var(--space-4);
}

.next--static .next__lift::after {
  height: 0;
}

.next--static .next__question {
  position: static;
  font-size: clamp(2.75rem, 6.4vw, 6.5rem);
}

.next--static .next__copy {
  padding-bottom: var(--space-5);
}

.next--plain .next__grid {
  grid-template-columns: minmax(0, 1fr);
}

/* stands in for the top edge of the footer, which the options end against */
.review__ground {
  height: var(--space-4);
}

.next__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin-top: var(--space-4);
}

.next__actions .next__call {
  margin-top: 0;
}

.review__option {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
}

/* October 16: prevent the Home closing question from flashing before the
   frozen WebCodecs runtime sets #arrival's real scroll height. This guard
   changes ONLY first paint. Once app.js assigns its height, BOTH existing
   copies of the question resume their exact original CSS and timing.
   No-JS / reduced-motion / browsers without the film timeline are unchanged. */
@supports (animation-timeline: view()) and (timeline-scope: --film) {
  @media (prefers-reduced-motion: no-preference) {
    html.js .page-home #arrival:not([style*="height"]) .film__question,
    html.js .page-home #arrival:not([style*="height"]) + section #next-question {
      visibility: hidden;
    }
  }
}

/* Checkpoint 2 page shells and the internal system page.
   These are scaffolding: each page body is replaced in Checkpoints 3 to 5. */

.shell {
  display: flex;
  align-items: flex-end;
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
  padding-block: var(--space-6) var(--space-5);
}

.shell__name {
  margin-bottom: var(--space-3);
}

/* ---------- Internal system page (not linked from the site) ---------- */

.sys {
  padding-block: var(--space-5) var(--space-6);
}

.sys__intro {
  padding-bottom: var(--space-5);
}

.sys__intro .t-body-l {
  margin-top: var(--space-3);
}

.sys-section {
  padding-block: var(--space-5);
}

.sys-section > .wrap > h2 {
  margin-bottom: var(--space-4);
}

.sys-swatches {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}

.sys-swatch__chip {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--hairline);
}

.sys-swatch__chip--gold {
  background: var(--gold);
}

.sys-swatch__chip--aubergine {
  background: var(--aubergine);
}

.sys-swatch__chip--graphite {
  background: var(--graphite);
}

.sys-swatch__chip--ivory {
  background: var(--ivory);
}

.sys-swatch dt {
  margin-top: var(--space-2);
  font-weight: 600;
}

.sys-swatch dd {
  margin: 0;
  color: var(--muted);
  font-size: 0.875rem;
}

.sys-pairs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.sys-pair {
  padding: var(--space-3);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.sys-pair strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: var(--display-weight, 400);
  font-optical-sizing: var(--display-optical, auto);
  font-variation-settings: var(--display-variation-small, normal);
  line-height: 1.2;
}

.sys-link {
  border-bottom: 1px solid currentColor;
}

.sys-note {
  margin-top: var(--space-3);
}

.sys-reserved {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
}

.sys-pair--gold-on-ivory {
  border: 1px solid var(--hairline);
}

.sys-pair--gold-on-ivory strong {
  /* demonstration of the rule: gold is ornament on ivory, never text */
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.sys-pair--gold-on-ivory strong::before {
  content: "";
  flex: 0 0 3rem;
  height: 1px;
  background: var(--gold);
}

.sys-type > * + * {
  margin-top: var(--space-4);
}

.sys-type__row {
  display: grid;
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: baseline;
}

.sys-motion {
  display: grid;
  gap: var(--space-5);
}

.sys-motion__row {
  display: grid;
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: baseline;
}

.sys-replay {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: var(--space-4);
  border-bottom: 1px solid currentColor;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.sys-logo-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}

.sys-logo-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 9rem;
  padding: var(--space-3);
}

.sys-logo-tile--ivory {
  border: 1px solid var(--hairline);
}

.sys-ph-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.sys-ph-surface {
  padding: var(--space-3);
}

.sys-ph-surface + .sys-ph-surface {
  margin-top: var(--space-2);
}

.sys-capability {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.5rem var(--space-3);
  font-size: 0.9375rem;
}

.sys-capability dt {
  color: var(--muted);
}

.sys-capability dd {
  margin: 0;
  font-weight: 600;
}

@media (max-width: 719px) {
  .sys-swatches {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sys-pairs,
  .sys-logo-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .sys-type__row,
  .sys-motion__row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-1);
  }
}

/* Home on phones.
   Owner ruling 2026-10-04 (docs/rulings/2026-10-04_ruling-mobile-home-pass.txt):
   "adapting the already-approved Shirin Ataie homepage for mobile only";
   "The desktop homepage is now frozen"; "Any mobile work must be scoped
   through: portrait breakpoints, mobile-only CSS, touch-only logic".
   Record: docs/MOBILE-HOME.md.

   HOW THE DESKTOP IS KEPT FROZEN. This file is the whole of the pass. No other
   stylesheet, no page and no script was edited, and this file is appended to
   the end of the built stylesheet, so everything before it is byte for byte
   what it was. Every rule here stands inside one of these media tests:

     (max-width: 719px)
         a phone held upright, and any window that narrow
     (min-width: 568px) and (max-width: 959px) and (max-height: 500px)
     and (orientation: landscape) and (pointer: coarse)
         a phone on its side: a short, wide TOUCH screen, 568 px wide or more
         (the narrowest phone on its side). A browser window on a desk that
         happens to be that shape (a laptop zoomed far in, say) has a fine
         pointer and is left as the desktop master has it. A narrow window
         that is merely a little wider than tall (a phone's split screen) is
         under 568 px and takes the upright phone's rules only.
     the two above, either one
     (max-width: 719px) and (orientation: portrait)
         the first, held upright
     (min-width: 568px) and (max-width: 719px) and (min-aspect-ratio: 3/2)
     and (pointer: coarse)
         a small phone on its side

   None can match a desk-shaped window (at least 960 px wide and at least
   9/8 as wide as tall), nor a tablet held upright (720 px wide or more). The
   gate "mobile" fails the build if a rule here stands outside them.

   THE FILM ON PHONES is the accepted runtime, untouched, as the owner ruled
   for the first real-device test. Nothing here changes how it loads, decodes
   or schedules. */

/* ==========================================================================
   1. A phone held upright, where the film's copy is moved by scroll timelines
   ========================================================================== */
@media (max-width: 719px) {
  /* "What's next?" on a phone. Everything else on a phone stands on the left
     margin (the identity, WELCOME HOME., the three proof moments, the
     tagline, the sentence, Call Shirin, the sign), so the question does too,
     where it was the one centred line. It stands in the sky, where the
     tagline has just stood, as it does on a desk-shaped window. One place for
     both copies, so the hand-over along the film's edge is exactly as it was.
     Its size is the size it has always had, held to the room between the two
     margins: at 3.25rem the word is 314 px wide (6.03 of its own sizes),
     which touched both edges of a 320 px screen. The hold acts on windows
     narrower than 358 px and nowhere else. */
  .page-home .next,
  .film__bridge {
    --next-size: min(clamp(3.25rem, 8.6vw, 9.5rem), calc((100vw - 2 * var(--gutter)) / 6.1));
    --next-top: max(calc(28vh - var(--next-size) * 0.5), var(--nav-h));
  }

  .page-home .next__question {
    padding-left: var(--gutter);
    text-align: left;
  }

  .film__question {
    right: auto;
    left: var(--gutter);
    text-align: left;
  }

  /* its pool goes with it: same size and strength, centred on the word */
  .film__bridge {
    --pool-x: calc(var(--gutter) + var(--next-size) * 3.02);
    --pool-y: 28vh;
  }

  /* The third proof moment stands at the same foot as the first two. Since
     its source line left Home, the room kept for that line (docs/HOME-
     CHOREOGRAPHY.md, 14.3) lifted it about 80 px above them on a phone, over
     an empty dark foot. The ruling: "The three proof beats should still feel
     equally important and evenly paced." */
  .film__moment--three .film__slot {
    --film-source-room: 0px;
  }

  .film__moment--three {
    --film-veil: 0.72;
  }
}

/* ==========================================================================
   2. A phone whose browser has no CSS scroll timelines (and motion is wanted)
   The ruling: "no essential information dependent on animation". Without
   scroll timelines the film's copy has nothing to time itself against, and
   until now such a phone showed the film with the name only: WELCOME HOME.,
   the three proof moments and the tagline were not on screen at all.

   Here the picture stays pinned and the copy travels up over it with the
   page, each piece passing through its own place at its own moment of the
   film. Nothing is animated: the copy is simply part of the page's scroll.

   How, without touching the engine. The engine makes the section 6.6 windows
   tall and the site pins one window of it. On this branch the pin is let out
   to the section's full height and the frame alone is pinned (sticky) inside
   it, so the film layer can lie along the whole section. A piece that should
   fill the window when the film is at progress p starts p x travel down the
   section, and travel is 5.6/6.6 of the section's height: 84.848 percent.
   The engine reads none of this. It still writes the same values to the
   frame, and the frame is still the full window (cinematic.css, the hold).

   Only where the site's scripts run (the page then carries the attribute
   data-cinematic): with scripts off there is no engine to make the section
   6.6 windows tall, and this branch does not apply (the layer stays hidden,
   as on the desktop master).

   In travel two pieces can be on screen at once (one leaving at the top as
   the next comes in at the foot), and held upright the tagline passes over
   Shirin's sleeve on its way up. Each piece stands alone and whole at its
   own place.
   ========================================================================== */
@media (max-width: 719px), (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @supports not ((animation-timeline: view()) and (timeline-scope: --film)) {
    @media (prefers-reduced-motion: no-preference) {
      html[data-cinematic] .page-home .cinematic__pin {
        position: relative;
        height: 100%;
        overflow: clip;
      }

      html[data-cinematic] .page-home .cinematic__frame {
        position: sticky;
        height: 100vh !important;
      }

      /* the engine's opening slot stood 28.5 percent down the pin, which was
         one window; the pin is now the whole section */
      html[data-cinematic] .page-home .arrival-copy {
        top: 28.5vh;
      }

      /* without this the layer stays hidden (film.css), and nothing below
         in this section shows */
      html[data-cinematic] .film {
        display: block;
        overflow: hidden;
      }

      .film__beat,
      .film__moment {
        top: calc(var(--at) * 84.848%);
        bottom: auto;
        height: 100vh;
      }

      /* the middle of each piece's readable hold on the film's own timeline */
      .film__beat--welcome {
        --at: 0.213;
      }

      .film__moment--one {
        --at: 0.348;
      }

      .film__moment--two {
        --at: 0.494;
      }

      .film__moment--three {
        --at: 0.64;
      }

      .film__beat--tagline {
        --at: 0.865;
      }

      /* The shade travels with its copy, so it must be soft at its foot as
         well as above: the veil's own shape ends hard at the foot of the
         picture, which is right when it is pinned there and a seam when it
         moves. Same graphite, same strength, feathered both ways. */
      .film__veil {
        background: linear-gradient(
          to top,
          rgb(37 37 38 / 0) 0%,
          rgb(37 37 38 / calc(var(--v) * 0.55)) 7%,
          rgb(37 37 38 / var(--v)) 15%,
          rgb(37 37 38 / var(--v)) 34%,
          rgb(37 37 38 / calc(var(--v) * 0.6)) 46%,
          rgb(37 37 38 / calc(var(--v) * 0.2)) 58%,
          rgb(37 37 38 / 0) 68%
        );
      }

      /* the swell is timed to the film's soft stretches; the ivory copy of
         the question is the bridge's, and there is no bridge on this branch
         (next.css: the heading simply opens its section) */
      .film__swell,
      .film__bridge {
        display: none;
      }
    }
  }
}

/* The same branch on a phone on its side. On a window that short the copy
   fills more of its piece's height than on a phone held upright, so the shade
   above had faded before the top line of a headline, which then stood on the
   picture's bright sky (measured: docs/MOBILE-HOME.md, 8.7). The same shade,
   the same strength, reaching higher: the shape section 8 uses, and close to
   what the pinned veil covers on such a window where scroll timelines exist. */
@media (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @supports not ((animation-timeline: view()) and (timeline-scope: --film)) {
    @media (prefers-reduced-motion: no-preference) {
      .film__veil {
        background: linear-gradient(
          to top,
          rgb(37 37 38 / 0) 0%,
          rgb(37 37 38 / calc(var(--v) * 0.55)) 6%,
          rgb(37 37 38 / var(--v)) 14%,
          rgb(37 37 38 / var(--v)) 66%,
          rgb(37 37 38 / calc(var(--v) * 0.6)) 78%,
          rgb(37 37 38 / calc(var(--v) * 0.2)) 88%,
          rgb(37 37 38 / 0) 96%
        );
      }
    }
  }
}

/* ==========================================================================
   3. A phone with reduced motion
   The engine holds the film on its first frame and makes the section one
   window high. Until now such a phone showed that frame with the name, then
   the question and the sign: the same lines were missing. Here the first
   frame stays pinned and the same copy follows it as five plain plates, one
   window each, in the film's order. No animation, no film: one still picture
   and the page's own scroll.

   Only where the site's scripts run, as in section 2: with scripts off the
   layer stays hidden and the section stays one window, as on the master.
   ========================================================================== */
@media (max-width: 719px), (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @media (prefers-reduced-motion: reduce) {
    /* the engine writes the section's height inline (one window); the plates
       need the room */
    html[data-cinematic] .page-home .cinematic {
      height: auto !important;
    }

    html[data-cinematic] .page-home .cinematic__pin {
      position: relative;
      height: auto;
      overflow: clip;
    }

    html[data-cinematic] .page-home .cinematic__frame {
      position: sticky;
      height: 100vh !important;
    }

    html[data-cinematic] .page-home .arrival-copy {
      top: 28.5vh;
    }

    /* without this the layer stays hidden (film.css), and nothing below in
       this section, or in section 8, shows */
    html[data-cinematic] .film {
      display: block;
      position: relative;
      inset: auto;
      overflow: hidden;
    }

    .film__beat,
    .film__moment {
      position: relative;
      inset: auto;
      height: 100vh;
      height: 100svh;
    }

    /* nothing here is timed: every piece simply stands */
    .film__veil,
    .film__beat .film__pool,
    .film__welcome,
    .film__headline,
    .film__support,
    .film__moment--three p,
    .film__tagline {
      animation: none;
    }

    .film__veil {
      background: linear-gradient(
        to top,
        rgb(37 37 38 / 0) 0%,
        rgb(37 37 38 / calc(var(--v) * 0.55)) 7%,
        rgb(37 37 38 / var(--v)) 15%,
        rgb(37 37 38 / var(--v)) 34%,
        rgb(37 37 38 / calc(var(--v) * 0.6)) 46%,
        rgb(37 37 38 / calc(var(--v) * 0.2)) 58%,
        rgb(37 37 38 / 0) 68%
      );
    }

    .film__swell,
    .film__bridge {
      display: none;
    }

    /* The sign on a touch screen with reduced motion. With motion, the board
       turns to SOLD once when it comes into view (next.css). Reduced motion
       stops the turn, and the cross-fade that replaces it was tied to hover
       and focus, which a touch screen does not have: the board stayed on FOR
       SALE. Here it cross-fades to SOLD once, on arrival, without turning. */
    @media (hover: none) {
      .page-home .sign.is-revealed .sign__face--back {
        opacity: 1;
        transition-delay: 1100ms;
      }
    }
  }
}

/* ==========================================================================
   4. A phone on its side
   The film's copy is laid out for it already (the 720 to 959 px rules of
   film.css), and Shirin is in the picture. Two things were wrong.

   "What's next?" stood in the middle of the window, which on a window this
   short put its first letter against her hair at the height of her face. It
   stands upper right instead, in the sky, clear of her, as it does on a
   desk-shaped window; one place for both copies. It is a step smaller than
   the centred line was (4.25rem at most, where that was 8.6vw), so that it
   stays right of her.

   The third proof moment stood about 96 px above the first two, as it did on
   a phone held upright (section 1), and for the same reason. It stands on
   their foot here too, under the same strength of shade.
   ========================================================================== */
@media (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  .page-home .next,
  .film__bridge {
    --next-size: clamp(3rem, 7vw, 4.25rem);
    --next-top: max(calc(30vh - var(--next-size) * 0.5), var(--nav-h));
  }

  .page-home .next__question {
    padding-right: var(--gutter);
    text-align: right;
  }

  .film__question {
    right: var(--gutter);
    left: auto;
    text-align: right;
  }

  .film__bridge {
    --pool-x: calc(100% - var(--gutter) - var(--next-size) * 3.02);
    --pool-y: 30vh;
  }

  .film__moment--three .film__slot {
    --film-source-room: 0px;
  }

  .film__moment--three {
    --film-veil: 0.72;
  }
}

/* ==========================================================================
   5. The section's height on a phone
   The engine sets the cinematic section to 6.6 windows, measured from the
   window's height, and measures it again whenever the window is resized. On
   a phone the browser's own bars slide away and back as the visitor scrolls,
   and each time they do the window's height changes and a resize is
   announced. The section would then grow or shrink by 6.6 times the height
   of the bars while the visitor's finger is on it, and the film would jump by
   as much as a tenth of its length when the scroll changes direction.

   Here the section is 6.6 times the window's full height (the "vh" unit,
   which on a phone does not change when the bars move), whatever the engine
   writes. The engine is not edited and takes its travel from the section as
   it finds it. Where the window's height does not change (every browser on a
   desk, and the review rig) the two values agree to within half a pixel:
   the engine writes a whole number of pixels, and this is the same length
   unrounded.

   Only where the site's scripts run (the page then carries data-cinematic):
   with scripts off there is no engine, and the section is left as it is.

   NOT VERIFIED ON A DEVICE: it is reasoned from the engine's code and from
   how phone browsers size the window, and it cannot be exercised in the
   cloud browser. Opening Home with ?cinematic=engine switches it off, so the
   accepted runtime can be seen on a phone exactly as it is.
   ========================================================================== */
@media (max-width: 719px), (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @media (prefers-reduced-motion: no-preference) {
    html[data-cinematic]:not([data-cinematic="engine"]) .page-home .cinematic {
      height: 660vh !important;
    }
  }
}

/* ==========================================================================
   6. Larger text on a phone
   The ruling: "support for portrait zoom/text resizing without catastrophic
   overlap". The film's display lines are sized in rem, and four of them are
   single words or single lines that cannot wrap. With the phone's text size
   raised (or the page zoomed, which narrows the window) they ran off the
   right edge and were cut: SHIRIN ATAIE and the line beneath it, WELCOME,
   EXPERIENCE, PRODUCER. So did the sign, whose one size is in rem.

   Each size is therefore held to the room between the two margins, divided
   by the measured width of its longest unbreakable piece in its own sizes
   (docs/MOBILE-HOME.md has the measurements). At the text size the pass was
   approved at, every one of these is larger than the size already in force
   on every window from 320 px wide, so nothing moves and nothing changes
   size: the cap only acts when text is enlarged or the window is narrower
   than 320 px.
   ========================================================================== */
@media (max-width: 719px) {
  /* SHIRIN ATAIE at this tracking is 8.64 of its own sizes wide */
  .film-id {
    --film-id-size: min(clamp(1.75rem, 3.1vw, 3.5rem), calc((100vw - 2 * var(--gutter)) / 8.7));
  }

  /* the second line is as wide as the name by design; it keeps that
     proportion (0.75rem to 1.75rem) when the name is held */
  .film-id__line {
    font-size: min(0.75rem, calc(var(--film-id-size) * 0.42858));
  }

  /* WELCOME is 5.27 of its own sizes wide */
  .film__beat--welcome {
    --film-welcome: min(clamp(3.25rem, 6vw, 7.25rem), calc((100vw - 2 * var(--gutter)) / 5.3));
  }

  /* EXPERIENCE is 6.66 of its own sizes wide (PRODUCER 5.77) */
  .film {
    --film-size: min(clamp(2.25rem, 10.4vw, 3.25rem), calc((100vw - 2 * var(--gutter)) / 6.7));
  }

  /* "experience." in the tagline is 4.95 of its own sizes wide */
  .film__beat--tagline {
    --film-tag: min(clamp(1.75rem, 8vw, 2.5rem), calc((100vw - 2 * var(--gutter)) / 5));
  }

  /* the sign's box is 20.5 of its own sizes wide (its arm, the widest part
     of the drawing, is 19.9). The locked drawing is not altered: one size
     still scales the whole of it. */
  .page-home .sign {
    font-size: min(clamp(0.8125rem, 3.6vw, 1rem), calc((100vw - 2 * var(--gutter)) / 20.5));
  }

  /* its rider's words have a floor in rem; they are 15.9 of their own sizes
     wide and the rider is 14.5 of the sign's, so they stay inside it */
  .page-home .sign__label {
    font-size: min(clamp(0.625rem, 0.7em, 0.75rem), 0.86em);
  }
}

/* ==========================================================================
   7. A small phone on its side
   A phone on its side shows the whole picture, Shirin included: she stands
   in its left third at the opening and in the finale. A larger phone on its
   side (720 px wide or more) is laid out by the tablet rules of film.css,
   which keep the name and the tagline on the right, clear of her. A smaller
   one (an iPhone SE on its side is 667 px wide) took the upright phone's
   rules instead, which stand everything on the left margin: the name was
   printed across her face at the opening, and the tagline across her in the
   finale. The ruling, on the finale: "avoid covering Shirin's face or body
   awkwardly".

   Here those two pieces stand on the right. The tagline starts 52 percent
   across, where the tablet rules have it, at the size they give it (28 px
   on these windows, where the upright phone's rule gave 40). The name ends
   88 percent across, short of the lit wall lamp at the right of the first
   frame (the lamp stands about 90 percent across), and never starts further
   right than 52 percent: 51.5 percent on a 667 px window, 45 on a 568 px
   one, where Shirin's hair ends about 40. Each is held to the room it has,
   so neither can run off the window. WELCOME HOME. and the three proof
   moments stay on the left: she is not in the picture behind them.

   The test is a touch screen 568 to 719 px wide and at least 3/2 as wide as
   tall: every phone of that width held on its side, and not a narrow window
   that is merely a little wider than tall (a phone's split screen), where
   the room on the right would be too small for the name.
   ========================================================================== */
@media (min-width: 568px) and (max-width: 719px) and (min-aspect-ratio: 3/2) and (pointer: coarse) {
  /* the engine's slot starts 58 percent across. The block starts 52 percent
     across, or further left where its end would otherwise pass 88 percent:
     the name is 8.7 of its own sizes wide */
  .film-id {
    --film-id-size: min(clamp(1.75rem, 3.1vw, 3.5rem), calc((48vw - var(--gutter)) / 8.7));
    margin-left: min(-6vw, calc(30vw - var(--film-id-size) * 8.7));
  }

  .film-id::before {
    inset: -30vh -34vw -34vh -20vw;
  }

  /* the tagline's longer line is 9.52 of its own sizes wide */
  .film__tagline {
    left: 52%;
  }

  .film__beat--tagline {
    --pool-x: 72vw;
    --pool-w: 104vw;
    --film-tag: min(clamp(1.75rem, 3.3vw, 3.75rem), calc((48vw - var(--gutter)) / 9.6));
  }
}

/* ==========================================================================
   8. A phone on its side, with reduced motion
   With reduced motion the first frame stays on screen behind the plates
   (section 3), and on a phone on its side that frame shows Shirin, standing
   in its left third with the keys. The plates' copy stands on the left, so
   it passed across her face as the page was scrolled. Here every plate
   stands in the right half instead, over the doors, where the name and the
   tagline already are; she is left clear. The shade behind the copy falls
   away to the left, as the second proof moment's does on a tablet, so it
   does not dim her.

   WELCOME and the first two proof moments are held to the half window:
   their size is the room divided by their longest line (OF EXPERIENCE, 8.3
   of its own sizes). The third proof moment is the locked panel and is not
   restyled: its slot is moved, whole, and the panel keeps its own size, so
   on a window narrower than about 800 px its headline takes two lines
   (BEST OF / 2026).

   A plate is as tall as its copy needs, and never less than the window, so
   no line can be cut at a plate's foot; the copy hangs from the foot of its
   plate as it does everywhere else.
   ========================================================================== */
@media (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @media (prefers-reduced-motion: reduce) {
    .film,
    .film__moment--two {
      --film-feather: linear-gradient(
        to left,
        rgb(37 37 38) 0%,
        rgb(37 37 38) 52%,
        rgb(37 37 38 / 0.8) 61%,
        rgb(37 37 38 / 0.48) 70%,
        rgb(37 37 38 / 0.18) 79%,
        transparent 88%
      );
    }

    /* On a window this short the copy fills more of its plate's height than
       on a phone held upright, so the shade of section 3 had faded before
       the top line of a headline, and the right of the first frame is lit by
       a wall lamp. The same shade, the same strength, reaching higher. */
    .film__veil {
      background: linear-gradient(
        to top,
        rgb(37 37 38 / 0) 0%,
        rgb(37 37 38 / calc(var(--v) * 0.55)) 6%,
        rgb(37 37 38 / var(--v)) 14%,
        rgb(37 37 38 / var(--v)) 66%,
        rgb(37 37 38 / calc(var(--v) * 0.6)) 78%,
        rgb(37 37 38 / calc(var(--v) * 0.2)) 88%,
        rgb(37 37 38 / 0) 96%
      );
    }

    .film {
      --film-size: min(clamp(3.25rem, 6.4vw, 7.25rem), calc((50vw - var(--gutter)) / 8.4));
    }

    .film__welcome {
      left: 50%;
    }

    .film__beat--welcome {
      --pool-x: 68vw;
      --pool-w: 124vw;
      --film-pool: 0.76;
      --film-welcome: min(clamp(3.25rem, 6vw, 7.25rem), calc((50vw - var(--gutter)) / 5.3));
    }

    .film__moment {
      height: auto;
      min-height: 100vh;
      min-height: 100svh;
    }

    /* the slot was laid over the plate from under the navigation; it now
       stands in the plate, under the same height, and gives the plate its
       own */
    .film__moment .film__slot {
      position: relative;
      inset: auto;
      padding-top: var(--nav-h);
    }

    .film__frame {
      padding-inline: 50% var(--gutter);
    }

    /* the panel brings its own margin, so its slot starts one margin left of
       the half */
    .film__moment--three .film__slot {
      margin-left: calc(50% - var(--gutter));
    }
  }
}

/* ==========================================================================
   9. The footer's links under a thumb, on Home
   The ruling: "usable tap targets". Every link and button on Home is 44 px
   tall on a phone. Seven of the footer's links are short words and so are
   narrower than that (Sell is 23 px wide). Their touch area is widened to
   44 px without moving or redrawing anything: an empty box behind the word.
   The footer's design is not touched, and the other pages are not touched.
   ========================================================================== */
@media (max-width: 719px) {
  .page-home .site-footer__group a::after,
  .page-home .site-footer__legal a::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: max(100%, 44px);
  }
}

/* ==========================================================================
   MOBILE V2 (sections 10 to 13)
   Owner ruling 2026-10-04, 5:44 PM, and his rulings of 6:47 PM, 7:03 PM and
   9:35 PM the same day
   (docs/rulings/2026-10-04_ruling-mobile-v2-refinement.txt):
   "surgical mobile-only refinement pass"; "improve only: 1. Shirin's portrait
   framing/choreography on mobile 2. the mobile position of What's next?
   3. mobile text stability/jitter 4. mobile perceived scroll smoothness.
   Everything else stays locked."; "Proceed with the small phone-only progress
   bridge."; "use the engine's existing progress as the single source of
   truth"; "keep ?cinematic=engine as the exact V1 comparison path"; and, at
   9:35 PM, "REBASE": "only the section height and current window height may
   be used to rebase it to the film's fixed travel".
   Record: docs/MOBILE-V2.md.

   EVERY RULE IN THESE FOUR SECTIONS begins html[data-film="bridge"]. Only
   assets/js/film-bridge.js sets that mark, and only on the phone tier (the
   tier capability.js reports when the page loads: a window under 600 px
   wide, or a touch screen whose shorter side is under 600 px), with motion
   wanted, where CSS scroll timelines exist, and never with
   ?cinematic=engine. Without the mark none of these rules applies and Home
   on a phone is exactly as sections 1 to 9 leave it: V1, less V1's own
   section 10 (an opt-in variant that followed Shirin, reached only with
   ?cinematic=mobile-cinematic), which V2 withdraws.

   --film-p is the engine's own progress through the film, put back on the
   film's fixed travel (the engine divides by a travel that changes as a
   phone's bars come and go; the script undoes that, and only that:
   docs/MOBILE-V2.md, section 8), and put onto <main> by that script each
   time the engine writes a new value. Inside the film it is the distance
   scrolled over that fixed travel. With the bars away that is the engine's
   own number, 0 to 1, to within a few hundred-thousandths (the section's
   height is a whole number of pixels). With them showing the engine's number
   is a little smaller and this one is not; past the film's end it can then
   stand a little over 1, which is why everything below clamps what it takes
   from it.

   THE TRAVEL IS FIXED ONLY BECAUSE SECTION 5 ABOVE HOLDS THE SECTION'S
   HEIGHT (660vh, where the engine would make it 6.6 of the window as it is
   at that moment). Every rule below stands inside the media tests section 5
   stands in. Section 5 is itself not verified on a device. Where it did not
   hold, or on a browser whose "vh" moved with its bars, --film-p would be
   the engine's own number again and would step with the bars.

   Everything below that moves is a plain function of that one number.
   Nothing here is an animation, nothing runs on a clock, and nothing
   remembers an earlier value: stop scrolling and everything stops.

   WHAT V2 MAKES UNTRUE ABOVE. Sections 1 to 9, and this file's heading, are
   V1's, byte for byte, and are kept so. The heading says that this file is
   the whole of the pass and that no script was edited, and that nothing here
   changes the film on phones. Read that as V1's. With V2 there is one script
   (the bridge), and on a phone held upright the engine draws into a wider
   frame (section 11). The engine itself is still not edited.
   ========================================================================== */

/* ==========================================================================
   10. The film's copy rides the engine's progress, not the browser's scroll
   timeline
   WHY. On the owner's iPhone (his screen recording, analysed frame by frame:
   docs/MOBILE-V2.md, section 2) the copy flashed for four or five frames at
   the start of a swipe: the name stepped sideways, the tagline stepped up,
   BEST OF 2026 lost its shade. In those frames the browser drew its
   scroll-driven animations as if the page were some tens of points further
   along, while the picture, which the engine draws, did not move. No
   way was found to stop the browser doing that from a stylesheet while the
   copy stays on its scroll timeline. So on such
   a phone the animations are switched off, and each piece's ink and position
   are computed from the engine's progress instead: the copy then takes its
   place from the number the engine has just written, on the same refresh.
   (The picture's own frame is drawn when the decoder returns it, as always;
   and with a phone's bars showing, the engine's own number, which picks the
   frame, runs behind the fixed travel the copy is on: by about 2.5 percent
   of its value on the owner's phone, as computed from the height of the
   bars in his recording; more on a shorter window.)

   NOTHING ABOUT THE CHOREOGRAPHY CHANGES while the bars are away (with them
   showing, the parenthesis above). --ia, --ib, --oa and --ob are the
   bounds film.css and next.css give each piece (--in-a, --in-b, --out-a,
   --out-b), as fractions where those are percentages. The gate "mobile"
   compares every one of them with those files and fails on any difference.
   The two formulas are what the two keyframe pairs in film.css do:
     ink        arrives 0 to 1 over ia..ib, leaves 1 to 0 over oa..ob
     position   22 px below its place on arrival, 12 px above it on leaving
   and the identity's drift (5vw to the right over 0 to 0.19) and the
   question's rise (9vh, over 0.925 to 0.965) likewise.
   ========================================================================== */
@media (max-width: 719px), (min-width: 568px) and (max-width: 959px) and (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  @supports (animation-timeline: view()) and (timeline-scope: --film) {
    @media (prefers-reduced-motion: no-preference) {
      html[data-film="bridge"] .film__beat--welcome .film__pool {
        --ia: 0.17;
        --ib: 0.195;
        --oa: 0.234;
        --ob: 0.259;
      }

      html[data-film="bridge"] .film__welcome {
        --ia: 0.175;
        --ib: 0.2;
        --oa: 0.226;
        --ob: 0.251;
      }

      html[data-film="bridge"] .film__moment--one .film__veil {
        --ia: 0.266;
        --ib: 0.291;
        --oa: 0.387;
        --ob: 0.412;
      }

      html[data-film="bridge"] .film__moment--one .film__headline {
        --ia: 0.272;
        --ib: 0.297;
        --oa: 0.379;
        --ob: 0.404;
      }

      html[data-film="bridge"] .film__moment--one .film__support {
        --ia: 0.292;
        --ib: 0.317;
        --oa: 0.379;
        --ob: 0.404;
      }

      html[data-film="bridge"] .film__moment--one .film__swell {
        --ia: 0.3;
        --ib: 0.323;
        --oa: 0.382;
        --ob: 0.412;
      }

      html[data-film="bridge"] .film__moment--two .film__veil {
        --ia: 0.412;
        --ib: 0.437;
        --oa: 0.533;
        --ob: 0.558;
      }

      html[data-film="bridge"] .film__moment--two .film__headline {
        --ia: 0.418;
        --ib: 0.443;
        --oa: 0.525;
        --ob: 0.55;
      }

      html[data-film="bridge"] .film__moment--two .film__support {
        --ia: 0.438;
        --ib: 0.463;
        --oa: 0.525;
        --ob: 0.55;
      }

      html[data-film="bridge"] .film__moment--three .film__veil {
        --ia: 0.558;
        --ib: 0.583;
        --oa: 0.679;
        --ob: 0.704;
      }

      html[data-film="bridge"] .film__moment--three p:nth-child(1) {
        --ia: 0.564;
        --ib: 0.589;
        --oa: 0.671;
        --ob: 0.696;
      }

      html[data-film="bridge"] .film__moment--three p:nth-child(2) {
        --ia: 0.584;
        --ib: 0.609;
        --oa: 0.671;
        --ob: 0.696;
      }

      html[data-film="bridge"] .film__moment--three .film__swell {
        --ia: 0.546;
        --ib: 0.566;
        --oa: 0.617;
        --ob: 0.642;
      }

      html[data-film="bridge"] .film__beat--tagline .film__pool {
        --ia: 0.79;
        --ib: 0.82;
        --oa: 0.905;
        --ob: 0.93;
      }

      html[data-film="bridge"] .film__tagline {
        --ia: 0.795;
        --ib: 0.83;
        --oa: 0.9;
        --ob: 0.925;
      }

      /* these three arrive and do not leave */
      html[data-film="bridge"] .film__bridge .film__pool {
        --ia: 0.915;
        --ib: 0.955;
      }

      html[data-film="bridge"] .page-home .next__question,
      html[data-film="bridge"] .film__question {
        --ia: 0.925;
        --ib: 0.965;
      }

      html[data-film="bridge"] .film-id {
        --ia: 0;
        --ib: 0.19;
      }

      /* how far in, and how far out, each piece is: 0 to 1, straight from the
         engine's progress */
      html[data-film="bridge"] .film__veil,
      html[data-film="bridge"] .film__swell,
      html[data-film="bridge"] .film__pool,
      html[data-film="bridge"] .film__welcome,
      html[data-film="bridge"] .film__headline,
      html[data-film="bridge"] .film__support,
      html[data-film="bridge"] .film__moment--three p,
      html[data-film="bridge"] .film__tagline,
      html[data-film="bridge"] .page-home .next__question,
      html[data-film="bridge"] .film__question,
      html[data-film="bridge"] .film-id {
        --film-i: clamp(0, calc((var(--film-p, 0) - var(--ia)) / (var(--ib) - var(--ia))), 1);
        animation-name: none;
      }

      html[data-film="bridge"] .film__veil,
      html[data-film="bridge"] .film__swell,
      html[data-film="bridge"] .film__beat .film__pool,
      html[data-film="bridge"] .film__welcome,
      html[data-film="bridge"] .film__headline,
      html[data-film="bridge"] .film__support,
      html[data-film="bridge"] .film__moment--three p,
      html[data-film="bridge"] .film__tagline {
        --film-o: clamp(0, calc((var(--film-p, 0) - var(--oa)) / (var(--ob) - var(--oa))), 1);
        opacity: calc(var(--film-i) * (1 - var(--film-o)));
        will-change: opacity;
      }

      html[data-film="bridge"] .film__welcome,
      html[data-film="bridge"] .film__headline,
      html[data-film="bridge"] .film__support,
      html[data-film="bridge"] .film__moment--three p,
      html[data-film="bridge"] .film__tagline {
        transform: translate3d(0, calc((1 - var(--film-i)) * 22px - var(--film-o) * 12px), 0);
        will-change: opacity, transform;
      }

      html[data-film="bridge"] .film__bridge .film__pool {
        opacity: var(--film-i);
        will-change: opacity;
      }

      html[data-film="bridge"] .page-home .next__question,
      html[data-film="bridge"] .film__question {
        opacity: var(--film-i);
        transform: translate3d(0, calc((1 - var(--film-i)) * 9vh), 0);
        will-change: opacity, transform;
      }

      html[data-film="bridge"] .film-id {
        transform: translate3d(calc(var(--film-i) * 5vw), 0, 0);
        will-change: transform;
      }
    }
  }
}

/* ==========================================================================
   11. Shirin in the picture on a phone held upright
   The ruling: "bring Shirin substantially closer to the center of the mobile
   viewport"; "Shirin welcomes you at the door"; "As the doors open: shift
   Shirin left"; through the house "prioritize architecture"; at the finale
   "bring her back toward a strong portrait position ... ensure her face is
   fully visible; preserve the champagne flute"; "Target story: Shirin, house,
   expertise, Shirin"; the movement "restrained", "smooth and monotonic",
   no "back-and-forth hunting".

   Held upright, a phone shows a little over a quarter of the picture's width
   (the middle of it, in V1). She stands in its left third at the opening and
   in the finale, so V1 never showed her face.

   HOW, WITHOUT TOUCHING THE ENGINE. The frame is given the picture's full
   width instead of the window's, centred, so the engine draws the whole
   picture into it; the pin shows the part behind the window; and the frame
   is slid sideways. The engine is not edited. It measures the frame when it
   sizes its canvas, as it always has, so on such a phone its canvas is the
   whole picture, up to the engine's own pixel budget, where in V1 it was the
   window (docs/MOBILE-V2.md, section 4, has the figures and the cost).

   THE PATH. One slide in each direction and never back:
     0            the window stands on her (its middle 24 percent of the way
                  across the picture; her face is at 22)
     0 to 0.13    the window travels right to the picture's middle: she
                  moves left and out as the camera passes her (she has left
                  the picture itself by 0.14; the doors begin to open at
                  0.156)
     0.13 to 0.9  the middle of the picture: V1's framing of the house, the
                  three proof moments and the sunset behind the tagline
                  (the framing; the engine's grade over the picture, its
                  "sheen", now runs across the whole picture, not the window)
     0.9 to 0.975 the window travels left to her (its middle 22.5 percent of
                  the way across; her face is at 22.8), as the tagline
                  leaves and the question arrives beneath her
     0.975 on     held on her, and she leaves with the film
   Each slide is one fixed curve of the film's progress, --film-p (it starts
   and ends gently: 3t² - 2t³, a curve of position, not of time). Position
   is a function of that number alone: nothing lags, and nothing moves
   unless the engine's progress does.

   Never further than the picture's own edge (--film-room): on a window
   nearly as wide as it is tall there is less picture to either side.

   AT THE OPENING THE PICTURE STANDS A LITTLE LOWER. Owner ruling 2026-10-05,
   9:09 AM (docs/rulings/2026-10-05_ruling-mobile-v2-opening-composition.txt):
   "In the opening mobile composition only, lower Shirin's portrait/crop
   enough to create visibly better breathing room above her"; "a small
   downward adjustment of the opening crop / subject placement, not ...
   pushing the text around"; "Do not let the text cover her face or hair."
   The picture is as tall as the window and the top of her hair is 16.5
   percent down its first frame; the identity stands a fixed distance under
   the navigation; so the shorter the window, the nearer her hair is to it.
   The picture is set down (--film-head) by what it takes to bring the part
   of it that is 11 percent down to 3rem below the navigation, which is
   where the identity's second line stands. On every upright phone the two
   lines then stand over the same band of the picture, with her hair the
   same share of the picture beneath them. On the owner's phone (771 px
   tall with its bars away) that is 23 px, and it leaves 32 px of clear
   ground between the identity and her hair, where moving the second line
   alone had left 9.
   NOT FURTHER, and the reason is in the picture: the lit edge where the
   wall meets the ceiling ends in a bright point at the corner of the
   door's frame, a little above that band. Set down further, that point
   stands in the second line, and the line no longer reads against it
   (measured over seventy window sizes: docs/MOBILE-V2.md, section 19).
   On a window so tall that the band is there already the amount is
   nothing. It is never more than the navigation's own height, so the strip
   the picture leaves above itself is behind the navigation and is not seen.
   It is part of the opening slide and of nothing else: the picture comes
   back up on the same curve as it travels right, and by 0.13 it stands
   exactly where it stood. The house, the proof moments, the tagline, her
   return and the question are framed as they were.
   ========================================================================== */
@media (max-width: 719px) and (orientation: portrait) {
  @supports (animation-timeline: view()) and (timeline-scope: --film) {
    @media (prefers-reduced-motion: no-preference) {
      html[data-film="bridge"] .page-home .cinematic__frame {
        --film-picture: max(100vw, 177.7778vh);
        --film-room: calc((var(--film-picture) - 100vw) / 2);
        --film-open: min(calc(var(--film-picture) * 0.26), var(--film-room));
        --film-close: min(calc(var(--film-picture) * 0.275), var(--film-room));
        --film-a: clamp(0, calc(var(--film-p, 0) / 0.13), 1);
        --film-b: clamp(0, calc((var(--film-p, 0) - 0.9) / 0.075), 1);
        --film-head: clamp(0px, calc(var(--nav-h) + 3rem - 11vh), var(--nav-h));
        left: calc(50% - var(--film-picture) / 2) !important;
        width: var(--film-picture) !important;
        translate: calc(
            var(--film-open) * (1 - var(--film-a) * var(--film-a) * (3 - 2 * var(--film-a)))
            + var(--film-close) * var(--film-b) * var(--film-b) * (3 - 2 * var(--film-b))
          )
          calc(var(--film-head) * (1 - var(--film-a) * var(--film-a) * (3 - 2 * var(--film-a))));
      }
    }
  }
}

/* ==========================================================================
   12. The opening identity, with her in the picture
   The ruling: "Do not allow the mobile crop change to create collisions
   between: Shirin's face, her body, the identity, door handles, nav. Do not
   add a card or solid panel. Use the minimum local readability treatment
   already established."

   In V1 the two lines stood on the left margin, 28.5 percent down, over the
   doors. With her in the picture that is across her face. They stand upper
   right instead, just under the navigation and above her head, the only
   clear part of the picture at that moment; their right edge is one margin
   in from the window's once the drift (5vw) has ended. As the scroll begins
   she moves left and out from under them, and the doors arrive beneath them
   as the engine fades them. Same type, same size, same drift, same fade.

   ONE THING IS DIFFERENT IN ITS LEAVING. As the engine fades its opening
   slot it also lifts it 18 px (app.js: 0 to -18 px over the fade, from 0.055
   to 0.19, on the curve 3t² - 2t³). Over the doors that is a small rise.
   Just under the navigation it carried the name's capitals up under the bar
   while they were still half inked. Here the block is set down by exactly
   as much as the slot is lifted, so the two lines fade and drift where they
   stand (exactly with the bars away. With them showing the engine lifts by
   its own number and the block is set down by the fixed travel's, so the
   two differ for a moment in mid-fade: by about two thirds of a pixel at
   most on the owner's phone, about 0.8 px on a short one, by arithmetic).
   The gate "mobile" holds the three numbers to the engine's own.

   The engine's slot starts 28.5 percent down and 58 percent across; both
   margins are in its terms. The name is 8.7 of its own sizes wide. On a
   window too narrow for that the block stays on the left margin, as in V1.

   Its pool (the readability treatment it has always had) is kept, drawn in
   from below and moved to the left, so that it shades the lit wall behind
   the two lines and not her face.
   ========================================================================== */
@media (max-width: 719px) and (orientation: portrait) {
  @supports (animation-timeline: view()) and (timeline-scope: --film) {
    @media (prefers-reduced-motion: no-preference) {
      html[data-film="bridge"] .film-id {
        --film-e: clamp(0, calc((var(--film-p, 0) - 0.055) / 0.135), 1);
        margin-top: calc(var(--nav-h) + 0.25rem - 28.5vh);
        margin-left: max(calc(var(--gutter) - 58vw), calc(37vw - var(--gutter) - var(--film-id-size) * 8.7));
        transform: translate3d(
          calc(var(--film-i) * 5vw),
          calc(var(--film-e) * var(--film-e) * (3 - 2 * var(--film-e)) * 18px),
          0
        );
      }

      /* The second line, closer to the name. Owner ruling 2026-10-05, 8:49 AM
         (docs/rulings/2026-10-05_ruling-mobile-v2-typography.txt): "reduce
         the opening identity subtitle gap to: margin-top: 0.35rem". The
         desktop's rule (film.css: clamp(0.9rem, 1.3vw, 1.4rem)) gives 0.9rem
         on a phone, so the second line stands 0.55rem (8.8 px) higher. The
         block is measured from its top, so the name does not move. */
      html[data-film="bridge"] .film-id__line {
        margin-top: 0.35rem;
      }

      /* The same pool, the same strength. It reached 34vh below the lines
         and now ends 3.25rem below where they ended before the ruling
         above, above her face. And it lay to the right of the lines, where
         it ran off the picture over the dark doors; here the lit stone is on
         the left, behind SHIRIN and LOS ANGELES, so it lies to the left
         (measured: docs/MOBILE-V2.md, 5).
         Its lower edge reads 3.8rem and not 3.25rem for one reason. The pool
         is measured from the block's box, and the ruling above makes the
         block 0.55rem shorter; 3.25rem plus that 0.55rem is 3.8rem, so the
         pool stands exactly where it stood and shades exactly what it
         shaded (the ruling: "no-op alignment"; "I expect no shading
         change"). */
      html[data-film="bridge"] .film-id::before {
        inset: -4.5rem -30vw -3.8rem -60vw;
      }
    }
  }
}

/* ==========================================================================
   13. "What's next?" low over the film
   The ruling: "What's next? must move to the bottom of the mobile cinematic
   viewport": "bottom third; comfortably above browser UI / safe area; not
   hugging the bottom edge; away from Shirin's face"; "Preserve What's next?
   parallax"; "Once on ivory, preserve the existing approved CTA composition."

   WHERE. Its top stands 6.25rem above the foot of the SMALL window (the
   window as it is with the browser's bars showing: the "svh" unit, which
   does not change as the bars come and go). So it is always above the
   browser's bar, and on the phones measured it is still in the lower third
   when the bars are away (docs/MOBILE-V2.md, section 6).
   Measured from the top of the window, as in V1, for both copies, by the
   same expression: the hand-over along the film's edge is V1's own
   mechanism, unchanged, at a new height.

   THE HAND-OVER. As in V1 the question holds while the film's edge travels
   up through it and turns it from ivory to graphite. In V1 it then held on
   for a full window while the sentence and the sign came up to it. Low on
   the window there is no room beneath it for that: a long hold would leave
   it alone at the foot of an empty ivory page. So it holds until the film's
   edge is 2rem above it, and then travels up with the page, the sentence
   directly beneath it: the composition V1 arrives at (the question, the
   sentence, Call Shirin, the sign, at the same distances), reached sooner.
   The hold is the distance from the window's foot to the question's top,
   plus those 2rem.

   Its pool goes with it: same size and strength, centred on the word.
   ========================================================================== */
@media (max-width: 719px) and (orientation: portrait) {
  @supports (animation-timeline: view()) and (timeline-scope: --film) {
    @media (prefers-reduced-motion: no-preference) {
      html[data-film="bridge"] .page-home .next,
      html[data-film="bridge"] .film__bridge {
        --next-top: calc(100svh - 6.25rem);
      }

      html[data-film="bridge"] .page-home .next {
        --next-hold: calc(100vh - 100svh + 8.25rem);
      }

      html[data-film="bridge"] .film__bridge {
        --pool-y: calc(var(--next-top) + var(--next-size) * 0.5);
      }
    }
  }
}


/* October 26: review-only phone refinement. Desktop declarations, About,
   cinematic engine, and approved copy are unchanged. */
@media (max-width: 719px) and (orientation: portrait) {
  /* Keep SHIRIN ATAIE at its existing exact font size and on one line.
     Centre its measured 8.7-em width inside the viewport rather than
     allowing the historic 37vw landing coordinate to bias it right. */
  .page-home .film-id {
    margin-left: calc(50vw - 58vw - 4.35 * var(--film-id-size));
  }
  html[data-film="bridge"] .page-home .film-id {
    margin-left: calc(50vw - 58vw - 4.35 * var(--film-id-size));
  }

  /* Phone/email remain in the same order; phone placement/number and the
     minimum 44px individual hit targets are preserved. */
  .site-footer__stack > .site-footer__group--plain[aria-label="Direct"] li + li {
    margin-top: -0.8rem;
  }

  /* A consistent mobile editorial opening for the five visual page heroes.
     About is expressly excluded. Do not force long headlines into two lines. */
  html body.page-buy .buy-focus,
  html body.page-sell .sell-opening,
  html body.page-sold .props-open,
  html body.page-areas .areas-open,
  html body.page-videos .videos-hero .videos-intro {
    display: flex;
    align-items: center;
    min-height: clamp(16.5rem, 31svh, 18.5rem);
    height: auto;
    padding-block: clamp(2.25rem, 4.7svh, 2.75rem);
  }
  body.page-buy .buy-focus__grid,
  body.page-sell .sell-opening__inner,
  body.page-sold .props-open__grid,
  body.page-areas .areas-open__grid {
    width: 100%;
  }
  body.page-buy .buy-focus__title,
  body.page-sell .sell-opening__title,
  body.page-sold .props-open__title,
  body.page-areas .areas-open__title,
  body.page-videos .videos-hero .videos-intro__title {
    font-family: var(--font-display);
    font-size: clamp(3rem, 10vw, 4.5rem);
    font-weight: 500;
    line-height: 1.03;
    letter-spacing: -.015em;
    max-width: 100%;
    text-wrap: balance;
  }
}

/* Phone-only icon drawing replaces iOS's default colored emoji presentation.
   In desktop rendering the original text glyph remains byte-for-byte. */
@media (max-width: 719px) {
  .mobile-link-glyph {
    position: relative;
    display: inline-block;
    width: .8rem;
    height: .8rem;
    margin-left: .08rem;
    vertical-align: -.05rem;
    font-size: 0;
    line-height: 0;
  }
  .mobile-link-glyph::before {
    content: "";
    position: absolute;
    top: .05rem;
    right: .02rem;
    width: .53rem;
    height: .53rem;
    border-top: 1px solid currentColor;
    border-right: 1px solid currentColor;
  }
  .mobile-link-glyph::after {
    content: "";
    position: absolute;
    top: .38rem;
    left: -.05rem;
    width: .86rem;
    height: 1px;
    background: currentColor;
    transform: rotate(-45deg);
  }
  /* Preserve the desktop circular button styling; replace only its content. */
  body.page-videos .videos-screen__play,
  body.page-videos .videos-short__play {
    font-size: 0;
  }
  body.page-videos .videos-screen__play::after,
  body.page-videos .videos-short__play::after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-top: .53rem solid transparent;
    border-bottom: .53rem solid transparent;
    border-left: .82rem solid var(--gold);
    transform: translateX(.11rem);
  }
  body.page-videos .videos-short__play::after {
    border-top-width: .42rem;
    border-bottom-width: .42rem;
    border-left-width: .66rem;
  }
}


/* Oct 26 mobile R2: review citations and optically centered play triangles.
   Never touch Home, About, the approved footer, or desktop styles. */
@media (max-width: 719px) {
  body.page-sell .sell-testimonial__context .mobile-link-glyph,
  body.page-sell .sell-testimonial__context .review-mobile-separator {
    display: none;
  }
  body.page-sell .sell-testimonial__context a {
    white-space: nowrap;
  }
  body.page-sell .sell-testimonial--lead .sell-testimonial__context a,
  body.page-sell .sell-testimonial__context a[href*="agentpronto.com"] {
    display: block;
    width: fit-content;
    margin-top: .22rem;
  }

  html body.page-videos .videos-screen__play,
  html body.page-videos .videos-short__play {
    position: relative;
  }
  html body.page-videos .videos-screen__play::after,
  html body.page-videos .videos-short__play::after {
    position: absolute;
    top: calc(50% - .53rem);
    left: calc(50% - .273rem);
    transform: none;
  }
  html body.page-videos .videos-short__play::after {
    top: calc(50% - .42rem);
    left: calc(50% - .22rem);
  }
}

/* Home on a tablet held upright.
   Owner rulings 2026-10-05, 1:46 PM and 2:40 PM
   (docs/rulings/2026-10-05_ruling-tablet-responsive-pass.txt and
   docs/rulings/2026-10-05_ruling-tablet-portrait-implementation.txt):
   "Landscape frozen. Portrait gets Shirin back at opening and finale. House
   stays centered in the middle. Upper-right desktop-style What's next?.
   Two-column portrait CTA. Nothing else."
   And, after his review of that build on his own tablet, his rulings of
   2026-10-06 (docs/rulings/2026-10-06_ruling-tablet-finale-crop.txt, 7:35 AM;
   ...-finale-revised-one-line.txt, 8:18 AM; ...-finale-approved.txt, 8:34 AM):
   the glass comes back into the picture at the end, and the end of the film
   follows the phone's choreography: the tagline in its two lines in the
   upper-right sky, then "What's next?" in one line, low over the film, the
   film's edge passing up through it. That is the end of the path in section
   2, and section 3.
   Record: docs/TABLET.md.

   HOW EVERYTHING ELSE IS KEPT AS IT WAS. This file is the whole of the pass.
   No other stylesheet, no page and no script was edited, and this file is
   appended to the end of the built stylesheet, after the desktop's thirteen
   and the phone's one, so everything before it is byte for byte what it was.
   Every rule here stands inside one media test and begins with one mark:

     (min-width: 720px) and (orientation: portrait) and (pointer: coarse)
         a TOUCH screen, taller than it is wide, 720 px wide or more. A
         tablet on its side is wider than tall and is left alone. A phone
         held upright is narrower than 720 px, and on its side is wider than
         tall. A browser window on a desk has a fine pointer, whatever its
         shape, and keeps the desktop master's presentation.
     html[data-device-tier="tablet"]
         set by the site's own script (capability.js) before the first
         paint. With scripts off there is no engine and no mark, and Home is
         left as the desktop master has it. The rules that touch the film
         (sections 2 and 3) add :not([data-cinematic="tableau"]) to it: where the
         same script finds no decoder for the film, the picture is a still
         and is left exactly as it was.

   Nothing here changes how the film loads, decodes or schedules, and nothing
   here is moved by a script: the one thing that moves (section 2) is moved
   by the film's own CSS scroll timeline, the one that moves the film's copy
   on a desk. The phone's bridge is not used and is not touched. The gate
   "tablet" holds this file byte for byte and rule by rule. */

@media (min-width: 720px) and (orientation: portrait) and (pointer: coarse) {
  /* ========================================================================
     1. "What's next?" and the call to action
     ======================================================================== */

  /* THE QUESTION stands upper right, as on a desk, over the film and then on
     ivory, in one place: both copies use the same two values. Upper: its
     middle is 22 percent of the way down the window, in the sky to the right
     of her head. Right: the ink of the question mark stands on the page's
     right margin, under the navigation's menu mark where there is one (0.045
     of the question's size is the mark's side bearing, the figure the desk's
     rule uses). On a desk the question ends on the sign's board instead,
     further in; here that would run it into her hair. */
  html[data-device-tier="tablet"] .page-home .next,
  html[data-device-tier="tablet"] .film__bridge {
    --next-top: max(calc(22vh - var(--next-size) * 0.5), var(--nav-h));
    --next-right: calc(var(--gutter) - var(--next-size) * 0.045);
  }

  html[data-device-tier="tablet"] .page-home .next__question {
    padding-right: var(--next-right);
    text-align: right;
  }

  html[data-device-tier="tablet"] .film__question {
    right: var(--next-right);
    text-align: right;
  }

  /* its pool goes with it: same size and strength, centred on the word
     (which is 5.98 of its own sizes wide), as in the desk's rule */
  html[data-device-tier="tablet"] .film__bridge {
    --pool-x: calc(100% - var(--next-right) - var(--next-size) * 2.99);
    --pool-y: 22vh;
  }

  /* THE CALL TO ACTION IN TWO COLUMNS, as on a desk: the sentence and Call
     Shirin on the left, the sign on the right margin. Under 900 px the
     desktop's stylesheet folds this into the phone's single column, which on
     a tablet left the right half of the page empty; the three declarations
     it changes for that are set back to their desk values here, and the sign
     to its desk size.

     The left column is as wide as the sentence's own measure (17 of its
     sizes), so the sentence keeps the three lines it has on a desk at every
     tablet width; a column of 7 parts in 12 is narrower than that under
     about 790 px and broke it into four. The sign keeps its own width and
     its place on the right margin: on the narrowest tablets (under about
     775 px) its box reaches a little way back over the left column's. Its
     ink does not: the sign's arm hangs 35 to 40 px below the sentence's last
     line and starts well to the right of the Call Shirin line. Without
     flex-shrink the sign would be squeezed to its column there, and its
     post would stand behind its board. */
  html[data-device-tier="tablet"] .page-home .next__grid {
    grid-template-columns: minmax(0, calc(17 * clamp(1.5rem, 2.35vw, 2.5rem))) minmax(0, 1fr);
  }

  html[data-device-tier="tablet"] .page-home .next__copy {
    padding-bottom: clamp(9rem, 30vh, 18rem);
  }

  html[data-device-tier="tablet"] .page-home .next__action {
    justify-content: flex-end;
  }

  html[data-device-tier="tablet"] .page-home .sign {
    flex-shrink: 0;
    font-size: clamp(0.875rem, 1.3vw, 1.25rem);
  }

  /* ========================================================================
     2. The film: Shirin, the house, Shirin
     3. The end of the film: the tagline, then the question low
     Both only where the film's copy is moved by scroll timelines and motion
     is wanted, which is where the film plays with its copy on a tablet.
     Anywhere else (no scroll timelines, reduced motion, or no decoder for
     the film) the picture, the identity and the tagline stay exactly as the
     desktop master has them, and the question as section 1 has it.
     ======================================================================== */
  @supports (animation-timeline: view()) and (timeline-scope: --film) {
    @media (prefers-reduced-motion: no-preference) {
      /* THE PICTURE. An upright tablet shows about two fifths of the film's
         width (37 to 42 percent), and the film opens and ends with Shirin at
         its left side: seen through the middle, as the desktop's stylesheet
         leaves it, she was a sliver at the left edge at the opening and half
         a face at the end.

         The frame is made as wide as the whole picture (the canvas covers the
         window by its height: the picture is as wide as the window, or 16/9
         of its height, whichever is the greater) and is slid sideways behind
         the window. The engine draws into it exactly as before. --tab-room is
         how far the frame can slide either way before its own edge would
         show.

           the opening   the window's left edge is 12.5 percent of the way
                         across the picture: Shirin with the keys at the left,
                         the door to her right. It is the left edge a 4 to 3
                         tablet on its side already has.
           the house     the window is on the middle of the picture, where it
                         has always been: the doors, WELCOME HOME. and the
                         three proof moments are composed for it.
           the end       the window's left edge is 11 percent of the way
                         across: Shirin with her glass, whole, at the left
                         (once she has returned the glass is never further
                         left than 11.0 percent of the way across the
                         picture: it is there at about 80 percent of the
                         film, with nothing to spare; from 84 percent, the
                         film's last frame, it stands 12 to 18.7 percent
                         across), the sunset and the sky to her right. It was
                         19.5 until the owner saw it on his tablet: the
                         glass and about a quarter of her were then outside
                         the window (rulings of 2026-10-06, which set aside
                         the earlier "the flute is expendable").

         AT REST THE WINDOW STANDS ON THE OPENING. Until the engine has drawn
         its first frame the picture is the film's first frame (the poster),
         wherever the page is scrolled to, and the film's timeline has no
         length yet: an animation on it would sit at its last keyframe, which
         is the end of the path. So the opening is the frame's own place, and
         the path below is put on only once the engine draws. */
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .page-home .cinematic__frame {
        --tab-picture: max(100vw, 177.7778vh);
        --tab-room: calc((var(--tab-picture) - 100vw) / 2);
        --tab-open: max(0px, calc(var(--tab-room) - var(--tab-picture) * 0.125));
        --tab-close: max(0px, calc(var(--tab-room) - var(--tab-picture) * 0.11));
        left: calc(50% - var(--tab-picture) / 2) !important;
        width: var(--tab-picture) !important;
        translate: var(--tab-open) 0;
      }

      /* THE PATH is a fixed curve of the film's progress and nothing else:
         the frame's place at any moment depends only on where the scroll is,
         forwards or backwards. It is one animation on the film's own
         timeline (film.css: --film), with the same range the film's copy is
         timed on, so its percentages are the engine's progress. It applies
         while the engine's status carries is-ready, which the engine sets
         when it has drawn a frame and which is also what takes the poster
         away (cinematic.css).

           0 to 13        off Shirin onto the doors. The doors begin to open
                          at 15.6, by which time the window has stopped.
           13 to 70.4     held on the middle.
           70.4 to 78.5   back to Shirin, from the frame in which the first
                          sliver of her shows (70.4, and the last proof
                          moment has just gone) to the frame in which she has
                          settled (78.5; the tagline arrives at 79).
           78.5 to 100    held on her.

         Each slide starts and stops gently (ease-in-out, set on the keyframe
         it starts from): that is the shape of the curve, a place for every
         point of progress, not a smoothing over time. With a straight line
         the picture would stop dead at 13 and at 78.5 while the scroll went
         on. */
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .page-home .cinematic__frame:has(> .video-status.is-ready) {
        animation-name: tablet-crop;
        animation-timing-function: linear;
        animation-fill-mode: both;
        animation-timeline: --film;
        animation-range: contain 0% contain 100%;
      }

      @keyframes tablet-crop {
        0% {
          translate: var(--tab-open) 0;
          animation-timing-function: ease-in-out;
        }

        13% {
          translate: 0 0;
          animation-timing-function: linear;
        }

        70.4% {
          translate: 0 0;
          animation-timing-function: ease-in-out;
        }

        78.5%,
        100% {
          translate: var(--tab-close) 0;
        }
      }

      /* THE IDENTITY stands to her right, against the door, as on a desk.
         Its setting is not touched: the same size, spacing and two lines it
         has always had on a tablet. Only its place changes.

         It is taken out of the flow of the engine's opening slot, as the
         desk's rule takes it, so that it can be placed by its right edge; the
         slot itself (the engine's, 58 percent across and 28.5 percent down)
         is not touched, and the engine still fades and lifts it.

         ACROSS. The ink of the name's last letter stands on the page's right
         margin, under the menu mark where there is one. The slot starts at
         58 percent, so that line is 58vw less its distance from the left
         edge; 0.14 of the name's size is the spacing that follows the last
         letter. On a window nearer square than about 4 to 5 the margin would
         carry the name across the seam between the doors (which is 43.2
         percent of the picture's width from the window's left edge), so
         there it stops at 42 percent, on the left-hand door, short of the
         seam.
         The name is 8.5 of its sizes wide. The whole of it is on the door
         where the window is about 0.69 as wide as it is tall, or wider (a
         4 to 3 tablet, and 820 x 1180). On a narrower tablet the door has not
         the room: its first letters stand on the door's black post (744 x
         1133; on a 16 to 10 tablet the first of them reaches the stone
         beside it). The keys are why: a window opened far enough across to
         give the name the door would cut them off.

         DOWN. The top of the second line stands 1.8rem above 40 percent of
         the way down the window, which is where the tops of the door handles
         are when the picture's travel first brings them under the name: both
         lines clear the handles while the name is still to be read, as they
         do on a desk. (11.5vh is 40 less the slot's 28.5; the name's box is
         1.05 of its size high, and the gap under it is the one film.css
         gives the second line.)

         IT DOES NOT DRIFT. On a desk the name drifts 5vw to the right as it
         fades, against the picture's travel. Here it stands on the right
         margin, which is 5vw wide: the drift carried it to the very edge of
         the screen. The picture's own slide moves under it instead. */
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .film-id {
        position: absolute;
        top: calc(11.5vh - var(--film-id-size) * 1.05 - clamp(0.9rem, 1.3vw, 1.4rem) - 1.8rem);
        right: calc(58vw - min(100vw - var(--gutter), 0.42 * max(100vw, 177.7778vh)) - var(--film-id-size) * 0.14);
        width: max-content;
        margin-top: 0;
        animation-name: none;
      }

      /* ====================================================================
         3. The end of the film: the tagline, then the question low
         (rulings of 2026-10-06, 8:18 AM and 8:34 AM: "adapt the choreography
         already approved on mobile"; "Build the proposal exactly as shown")

         With the glass in the picture her head stands further into the
         window: where the tagline and the question stood in the sky, upper
         right, there is now her hair. The sky that is left beside her is
         about a third of the window wide, and the question in one line is
         half the window. So, as on the phone: the tagline stands above her
         hair, and the question stands low, over her jacket, and is handed
         to the ivory page there. Not a word, a size or a line break of
         either is changed.
         ==================================================================== */

      /* THE TAGLINE, in its two lines and at its own size, stands in the
         upper-right sky above her hair: flush right on the page's right
         margin, its top 2.25rem under the navigation. There her hair is
         still rounding in toward the crown (it ends about 31 percent of the
         way across the picture at the foot of the second line, and 35
         percent further down, where the tagline stood), and at rest the
         tagline clears it at each of the five sizes the owner named: by
         28 px at 744 x 1133, the tightest, and by 94 at 820 x 1180. It
         arrives from 22 px lower (film.css) and is nearer her hair while it
         does, within a few pixels at 744 x 1133. On an upright screen
         narrower in shape than the five (about 720 x 1100 and taller) it
         touches her hair as it arrives (independent review, 2026-10-06;
         docs/TABLET.md, 13.9): not one of the sizes built for, and the
         tagline's place is the owner's ruling. Its pool (film.css) is
         measured from the same top and comes up with it. */
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .film__beat--tagline {
        --film-tag-top: calc(var(--nav-h) + 2.25rem);
      }

      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .film__tagline {
        right: var(--gutter);
        left: auto;
      }

      /* THE QUESTION, in one line and at its own size, stands low over the
         film: flush right on the line it has always ended on (section 1),
         its box 2.6rem above the foot of the SMALL window (the window as it
         is with a browser's bars showing: the "svh" unit), so its ink ends
         about 50 px above the foot at every size. That is over the hem of
         her jacket, under her glass, her hair and her face, between the
         jacket's two rows of buttons.

         Both copies stand there, by the same expression, as in section 1 and
         as on the phone: the hand-over along the film's edge is the mechanism
         it has always been, at a new height.

         THE HAND-OVER is the phone's (mobile.css, section 13). Upper right,
         the question held for a full window while the sentence and the sign
         came up to it. Low on the window there is no room beneath it for
         that: a long hold would leave it alone at the foot of an empty ivory
         page. So it holds until the film's edge is 2rem above it and then
         travels up with the page, the sentence and the sign directly beneath
         it: the call to action tablet V1 arrives at, at the same distances,
         reached sooner. The hold is the distance from the window's foot to
         the question's top, plus those 2rem.

         Its pool goes with it, centred on the word. */
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .page-home .next,
      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .film__bridge {
        --next-top: calc(100svh - var(--next-size) - 2.6rem);
      }

      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .page-home .next {
        --next-hold: calc(100vh - 100svh + var(--next-size) + 4.6rem);
      }

      html[data-device-tier="tablet"]:not([data-cinematic="tableau"]) .film__bridge {
        --pool-y: calc(var(--next-top) + var(--next-size) * 0.5);
      }
    }
  }
}

/* Oct26 mobile link clarity: identify textual hyperlinks across content.
   Do not restyle navigation, icon-only video controls, interactive buttons,
   CTA art, images, or the already approved desktop/footer composition. */
@media (max-width: 719px) {
  body main a[href]:not(.sign):not(.home-call):not([class*="__call"]):not([class*="__watch"]):not(.areas-card__directions):not(.skip-link) {
    text-decoration-line: underline !important;
    text-decoration-style: solid;
    text-decoration-thickness: 1px;
    text-underline-offset: .22em;
  }
}

/* Essential-only privacy notice + settings dialog (2026-10-27). */
.site-footer__legal { flex-wrap: wrap; }
.site-footer__cookie-btn {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0;
  border: 0; background: none; font: inherit; color: var(--ivory); cursor: pointer;
  transition: color var(--dur-ui) var(--ease-silk);
}
.site-footer__cookie-btn:hover { color: var(--gold); }
.site-footer__cookie-btn[hidden] { display: none; }
@media (max-width: 959px) { .site-footer__cookie-btn { min-height: 44px; } }

.privacy-notice {
  position: fixed; z-index: 90;
  left: max(1rem, env(safe-area-inset-left)); right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  margin-inline: auto; max-width: 34rem;
  background: #533340; color: #F3EFE9;
  border: 1px solid rgba(200, 169, 107, .45);
  box-shadow: 0 24px 60px -24px rgba(37, 37, 38, .6);
  animation: privacy-in .5s cubic-bezier(.22,.61,.36,1) both;
}
.privacy-notice[hidden] { display: none; }
@media (min-width: 960px) { .privacy-notice { left: auto; right: 2rem; bottom: 2rem; margin: 0; } }
.privacy-notice__inner { padding: 1.5rem 1.5rem 1.25rem; }
.privacy-notice__title, .privacy-dialog__title {
  margin: 0; font-family: "Bodoni Moda", Georgia, serif; font-weight: 500;
  font-size: clamp(1.3rem, 1.6vw, 1.55rem); line-height: 1.2; color: #F3EFE9;
}
.privacy-notice__copy { margin: .75rem 0 0; font-family: "Manrope", system-ui, sans-serif; font-size: 1rem; line-height: 1.55; color: rgba(243,239,233,.88); }
.privacy-notice__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; margin-top: 1.1rem; }
.privacy-notice__btn, .privacy-notice__link {
  min-height: 44px; display: inline-flex; align-items: center;
  font-family: "Manrope", system-ui, sans-serif; font-size: .875rem; letter-spacing: .08em; text-transform: uppercase;
  color: #F3EFE9; cursor: pointer;
}
.privacy-notice__btn { border: 0; background: none; padding: 0; font-weight: 500; }
.privacy-notice__btn--primary { padding: 0 1.4rem; background: #C8A96B; color: #252526; font-weight: 600; }
.privacy-notice__btn--primary:hover { background: #F3EFE9; }
.privacy-notice__btn--quiet, .privacy-notice__link { text-decoration: underline; text-decoration-color: rgba(200,169,107,.7); text-underline-offset: .3em; }
.privacy-notice__btn--quiet:hover, .privacy-notice__link:hover { color: #C8A96B; }
.privacy-notice :focus-visible, .privacy-dialog :focus-visible, .site-footer__cookie-btn:focus-visible { outline: 2px solid #C8A96B; outline-offset: 3px; }

.privacy-dialog {
  width: min(36rem, calc(100vw - 2rem)); max-height: calc(100svh - 2rem); overflow: auto;
  padding: 0; border: 1px solid rgba(200,169,107,.5); background: #252526; color: #F3EFE9;
}
.privacy-dialog::backdrop { background: rgba(37,37,38,.6); }
.privacy-dialog__inner { padding: 2rem; }
.privacy-dialog__inner p { margin: 1rem 0 0; font-family: "Manrope", system-ui, sans-serif; font-size: 1rem; line-height: 1.6; color: rgba(243,239,233,.88); }
.privacy-dialog__inner strong { color: #C8A96B; font-weight: 600; }
.privacy-dialog__inner code { font-size: .875em; word-break: break-all; }
.privacy-dialog__status:empty { display: none; }
@media (max-width: 559px) {
  .privacy-notice__inner { padding: 1.15rem 1.15rem 1rem; }
  .privacy-notice__copy { font-size: 1rem; line-height: 1.5; margin-top: .5rem; }
  .privacy-notice__actions { gap: .25rem 1rem; margin-top: .75rem; }
  .privacy-dialog__inner { padding: 1.5rem; }
}
@keyframes privacy-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .privacy-notice { animation: none; } }
html[data-motion="reduce"] .privacy-notice { animation: none; }

/* Cookie notice mobile action balance, 2026-10-27.
   Only the floating banner's actions are touched; settings dialog and all
   desktop/footer/page layouts remain exactly as approved. */
@media (max-width: 559px) {
  .privacy-notice > .privacy-notice__inner > .privacy-notice__actions {
    display: grid;
    grid-template-columns: max-content max-content;
    justify-content: start;
    align-items: center;
    column-gap: clamp(.5rem, 2.3vw, .95rem);
    row-gap: .55rem;
  }
  .privacy-notice > .privacy-notice__inner > .privacy-notice__actions > .privacy-notice__btn--primary {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: start;
  }
  .privacy-notice > .privacy-notice__inner > .privacy-notice__actions > .privacy-notice__link {
    grid-column: 1;
    grid-row: 2;
    white-space: nowrap;
  }
  .privacy-notice > .privacy-notice__inner > .privacy-notice__actions > .privacy-notice__btn--quiet {
    grid-column: 2;
    grid-row: 2;
    white-space: nowrap;
  }
  .privacy-notice > .privacy-notice__inner > .privacy-notice__actions > :is(.privacy-notice__link, .privacy-notice__btn--quiet) {
    font-size: clamp(.71rem, 3.4vw, .875rem);
    letter-spacing: .04em;
  }
}
