@font-face { font-family: 'Cormorant Garamond'; src: url('assets/cormorant-regular.woff2') format('woff2'); font-style: normal; font-weight: 400 600; font-display: swap; }
@font-face { font-family: 'Cormorant Garamond'; src: url('assets/cormorant-italic.woff2') format('woff2'); font-style: italic; font-weight: 400 600; font-display: swap; }
/* Ena's face, for the heading of its page only. menu-navigation.js fetches it once the card is ready and
   holds the turn for it, so it swaps in from a fallback only on a very slow connection, and never shows blank. */
@font-face { font-family: 'Archivo'; src: url('assets/archivo-variable.woff2') format('woff2'); font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; }

:root { color-scheme: light; --ink: #750d11; --paper: #faf3e2; --line: #903e37; --font-menu: 'Cormorant Garamond'; }
* { box-sizing: border-box; }
html { min-width: 320px; background: #f1eee7; }
body { margin: 0; color: var(--ink); font-family: var(--font-menu), Georgia, serif; -webkit-font-smoothing: antialiased; }
::selection { background: #750d1126; }
h1,h2,h3,p { margin: 0; }
a:focus-visible,button:focus-visible { outline: 2px solid var(--ink); outline-offset: 5px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* The serve: the film lays the live menu on the table. */
.experience { position: relative; min-height: 100svh; overflow: clip; background: #eeeae2; }
/* Clip the extended cloth without making the stage a focus-scroll container.
   Its size is the table's, which can be taller than the window (player.js). */
.table-stage { position: absolute; inset: 0; overflow: clip; container-type: size; }
.scene { position: absolute; top: 50%; left: 50%; transform-origin: center; width: 1536px; height: 864px; }
.table-video { display: none; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.olive-scene { display: none; position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; overflow: hidden; }
#olive-film { display: block; width: 100%; height: 100%; position: relative; z-index: 1; }
/* ...so the bowl's drawn shadow stays under the bowl: a positioned element
   otherwise paints over the canvas, however early it sits in the markup. */
body[data-sequence] .table-video { display: block; }
body[data-sequence] .scene { left: 0; top: 0; transform-origin: 0 0; background: transparent; }
body[data-sequence] .olive-scene { display: block; visibility: hidden; }
body[data-service="card"] .olive-scene { display: none; }
.table { position: absolute; width: 100%; height: 100%; object-fit: cover; }
.table:not([src]) { display: none; }
/* Continue the native table beyond the film with matching reflected edges. */
.table-continuation {
  position:absolute;width:calc(100% + 2*var(--table-bleed,0px));height:calc(100% + 2*var(--table-bleed,0px));
  margin:calc(-1*var(--table-bleed,0px));max-width:none;object-fit:fill;
  transform-origin:50% 50%;pointer-events:none;z-index:-1;
}
.menu-placement { position: absolute; left: 0; top: 0; transform-origin: 0 0; visibility: hidden; }
#film,.tracking-overlay { pointer-events: none; position: absolute; width: 100%; height: 100%; inset: 0; }
.tracking-overlay { visibility: hidden; overflow: visible; }
/* The loading line is due 1.2 s after first paint, out of sight (and out of the
   accessibility tree) until then. The deadline lives here so that it holds while
   player.js is still arriving on a slow link; the player hides the line before it
   when the table is set in time, brings it forward when its download forecast says
   the wait will be long, and times its stay and its exit. A table taller than
   the window still has it in view. */
.loading { position: absolute; z-index: 4; left: 50%; top: min(47%, 47svh); transform: translate(-50%,-50%); font-style: italic; font-size: 24px; white-space: nowrap; animation: loading-in .25s ease-out 1.2s both; }
@keyframes loading-in { from { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) { .loading { animation-duration: 0s; } }
.loading[hidden] { display: none; }
/* An error is shown at once. */
.loading.error { max-width: min(420px,calc(100vw - 60px)); text-align: center; white-space: normal; font-size: 21px; animation: none; }

/* The film keeps its own paper and shadows; only the card area is keyed. */
#opaque-film,#paper-continuation { display:none; pointer-events:none; position:absolute; inset:0; width:100%; height:100%; }
body[data-scene-mode="opaque"] #opaque-film,body[data-scene-mode="opaque"] #paper-continuation { display:block; }
body[data-scene-mode="opaque"] .table-stage,body[data-scene-mode="baked"] .table-stage { isolation:isolate; }
body[data-scene-mode="opaque"] .scene,body[data-scene-mode="baked"] .scene { z-index:1; }
/* The light falls *through* the scene, so it multiplies over it. Without this it is
   a flat grey veil laid on top, which is what made the whole picture look weak. */
body[data-scene-mode="opaque"] .table-video,body[data-scene-mode="baked"] .table-video { z-index:2; mix-blend-mode:multiply; pointer-events:none; }
body[data-scene-mode="opaque"] .menu-card,body[data-scene-mode="baked"] .menu-card { box-shadow:none; }
body[data-screen-projection] .menu-placement { z-index:2; will-change:transform; }
/* Supersample thin rules before the perspective warp, including on 1× screens. */
body[data-screen-projection] .menu-card { zoom:2; }
body[data-screen-projection] #film { z-index:3; transform-origin:0 0; }
body[data-screen-projection] .table-video { z-index:5; }
#card-surface,#card-surface-shadow { position:absolute;inset:0;width:100%;height:100%;pointer-events:none; }
#card-surface { z-index:2; }
#card-surface-shadow { z-index:1; }
body[data-card-surface="mesh"] .menu-placement { opacity:0; }
body[data-card-surface="mesh"] .menu-placement:focus-within { opacity:1; }
/* The bowl is on the same table as the card, so the olive tree's light has to
   fall across it too: above the film, below the light that multiplies over both. */
body[data-screen-projection] .olive-scene { z-index:4; }
/* The menu reaches past the filmed card and covers its shadow, so it brings its own. */
body[data-scene-mode="opaque"][data-menu-shadow] .menu-card,body[data-scene-mode="baked"][data-menu-shadow] .menu-card { box-shadow: 0 1px 3px #3f2e2033, 2px 6px 14px #4a3a2a26; }


/* Studio card navigation and typography. */
:root{--card-top-space:76px;--card-bottom-space:76px;--card-min-width:290px}
html,body{height:100%;overflow:hidden}
.experience{height:100svh;min-height:0}
button,a{-webkit-tap-highlight-color:transparent}
button{font-family:inherit;color:inherit}
.site-nav{position:fixed;inset:0 0 auto;z-index:12;height:70px;display:flex;align-items:center;justify-content:space-between;padding:0 clamp(18px,4vw,60px);gap:20px;pointer-events:none}
/* The header is set in a classic sans (the user, 24 Sep): the menu's serif stays on the card. */
.site-nav button{pointer-events:auto;background:none;border:0;padding:10px 0;cursor:pointer;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.1;font-weight:500;letter-spacing:.02em}
.site-nav .site-home{border-bottom:1px solid transparent}.site-nav .site-home[aria-current],.site-nav .site-home:hover{border-color:currentColor}
.site-nav nav{display:flex;gap:30px}
.site-nav nav button{border-bottom:1px solid transparent}
.site-nav nav button[aria-current],.site-nav nav button:hover{border-color:currentColor}
/* Ordinary legal links remain available while the card loads, scrolls or turns. */
.studio-footer{position:fixed;left:clamp(18px,4vw,60px);right:18px;bottom:14px;z-index:12;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:12px;line-height:1.25;pointer-events:none}
.studio-footer nav{display:flex;gap:22px;align-items:center;min-height:32px}
.studio-footer a{display:inline-flex;align-items:center;min-height:32px;color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;pointer-events:auto}
.studio-footer a:hover{opacity:.72}
.studio-footer p{max-width:430px;text-wrap:pretty}
@media(max-width:600px){.studio-footer{left:17px;right:17px;bottom:8px}}
@media(max-width:370px){.studio-footer{left:12px;right:12px}}
/* The card is never drawn narrower than --card-min-width (about 14px body type): a window too short
   to show all of it scrolls instead, down to a table that player.js keeps tall enough for the card
   and its gaps. The header then scrolls with the table, so it never lies over the card. The query's
   640px clears the tallest such table (590px) with room for a phone's toolbars. */
@media(max-height:640px),(max-width:319px){
  html,body{height:auto;overflow:visible}
  body{position:relative;padding-bottom:max(12px,env(safe-area-inset-bottom))}
  .site-nav{position:absolute}
  /* Keep disclosure visible from first paint. The extra page space lets the
     whole card scroll clear without changing its filmed size or placement. */
  .studio-footer{position:fixed;left:0;right:0;bottom:0;padding:4px clamp(12px,4vw,60px) max(8px,env(safe-area-inset-bottom));background:#f1eee7f5}
}
.menu-card{position:relative;width:790px;height:1264px;padding:0;background:transparent;color:var(--ink);font-family:var(--font-menu),Georgia,serif;box-shadow:none!important;outline:none}
.card-rotator{position:relative;width:100%;height:100%;padding:54px 64px 52px;background:var(--paper);transform-origin:50% 50%;box-shadow:0 1px 3px #3f2e2033,2px 6px 14px #4a3a2a26}
/* Keep the resting scroll container in a flat paint layer. A permanently hidden
   back face inside the tracked, supersampled plane can cull its scroll contents
   when the filmed card hands over to HTML. Perspective is needed only in a turn. */
.menu-card[aria-busy="true"]{perspective:2200px}
.menu-card[aria-busy="true"] .card-rotator{backface-visibility:hidden}
.card-rotator::before{content:'';position:absolute;pointer-events:none;inset:0;opacity:.4;background:url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Cpath fill='%23926d31' opacity='.12' d='M0 0h160v160H0z' filter='url(%23n)'/%3E%3C/svg%3E");mix-blend-mode:multiply}
.menu-border{position:absolute;inset:18px;border:1.6px solid var(--line);opacity:.8;border-radius:21px 3px 21px 3px;pointer-events:none}
.menu-border::after{content:'';position:absolute;inset:5px;border:1.6px solid var(--line);border-radius:16px 1px 16px 1px}
.menu-content{position:relative;height:100%;display:flex;flex-direction:column;outline:none}
.menu-content[data-page="home"]{display:block;overflow-x:hidden;overflow-y:auto;overscroll-behavior-y:contain;scrollbar-width:none;touch-action:pan-y pinch-zoom}
.menu-content[data-page="home"]::-webkit-scrollbar{display:none}
/* While a list link shows keyboard focus, the scroller reaches 12px past the text column, so the ring at the
   column's edge is not clipped. Only then: at rest, a wider scroller shifts the first page's 4x raster,
   which the film prints. */
.menu-content[data-page="home"]:has(.project-links>:focus-visible){margin:0 -12px;padding:0 12px}
.menu-home{height:1158px;min-height:1158px;display:flex;flex-direction:column}
.menu-scroll-section{padding:56px 0 70px}
.menu-scroll-section+.menu-scroll-section{border-top:1.6px solid var(--line)}
.menu-scroll-section:last-child{min-height:100%}
.studio-name:focus{outline:none}
.masthead{text-align:center}
.studio-name{margin:0 -5px;line-height:0}.studio-lettering{display:block;width:100%;height:210px;background:currentColor;-webkit-mask:url("assets/salt-to-taste.svg") center/contain no-repeat;mask:url("assets/salt-to-taste.svg") center/contain no-repeat}
.menu-rule{display:flex;align-items:center;gap:15px;margin:24px 0 22px}
.menu-rule::before,.menu-rule::after{content:'';flex:1;height:1.6px;opacity:.8;background:var(--line)}.menu-rule span{font-family:Georgia,serif;font-size:36px;line-height:1}
h2{text-align:center;font-weight:600;font-size:47px;line-height:1.08;letter-spacing:-.03em}
.studio-intro{text-align:center;font-size:41px;line-height:1.22;margin:10px 8px 0;text-wrap:pretty}
.studio-intro p+p{margin-top:26px}
/* 100px below: the space the separate arrow used to take, so the rule stays where it is printed. */
.kitchen-rule{position:relative;margin-top:auto;margin-bottom:100px}
.studio-contact{margin:24px 0 0;text-align:center;font-size:38px;line-height:1.18}
.studio-contact a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
/* The scroll cue is a chevron centred where the lower rule's star stands. The first scroll of the card
   fades the star back in for good; the state sits on #menu, so card turns keep it. The chevron is
   outlined geometry so CSS zoom and the tracked projection preserve the weight of its printing. */
.scroll-cue{position:absolute;left:50%;top:50%;width:52px;height:52px;margin:-26px 0 0 -26px;display:flex;align-items:center;justify-content:center;color:inherit;cursor:pointer;transition:opacity .2s,visibility .2s}
.scroll-cue::after{content:'';position:absolute;inset:-29px}
.scroll-cue svg{width:48px;height:48px;fill:currentColor;stroke:none}
.scroll-cue:hover svg{transform:translateY(4px)}
.scroll-cue:focus-visible{outline-offset:-2px}
.kitchen-rule span{opacity:0;transition:opacity .2s}
#menu[data-scrolled] .kitchen-rule span{opacity:1}
#menu[data-scrolled] .scroll-cue{opacity:0;visibility:hidden}
.project-list{list-style:none;margin:53px 0 0;padding:0;display:grid;gap:40px}
.project-list>li{padding-bottom:34px;border-bottom:1px solid #903e3740}.project-list>li:last-child{padding-bottom:0;border:0}
.project-title{font-size:47px;line-height:1.15;font-weight:600;letter-spacing:-.015em}
.project-description{font-size:34px;line-height:1.25;margin-top:14px;text-wrap:pretty}
/* Text links with room to tap and for the focus ring; negative margins take the padding back, so the
   text stays on the column edge. */
.project-links{display:flex;flex-wrap:wrap;gap:0 48px;margin:0 0 -20px}
.project-links>*{position:relative;margin:0 -10px;padding:20px 10px;background:none;border:0;color:inherit;font-size:32px;line-height:1.2;font-weight:600;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:6px;cursor:pointer}
.project-links>:hover{opacity:.72}.project-links>:focus-visible{outline-offset:-2px}
.card-back{position:relative;align-self:flex-start;display:block;background:none;border:0;padding:2px 0 8px;margin:0 0 38px;font-size:30px;line-height:1.2;cursor:pointer;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px}
.card-back:hover{opacity:.72}
/* A 390px phone shows the card at .4, so each control is hit 110 card px tall (44 CSS px) without
   moving its text or its focus ring. Links reach only downwards, into the space before the next rule,
   so the description above them stays text. */
.project-links>::after,.card-back::after{content:'';position:absolute;inset:0 0 -32px}
.card-back::after{inset:-32px -12px}
.face-title{font-size:72px;line-height:1.02;font-weight:500;letter-spacing:-.035em;text-align:left;outline:none}
/* Ena's page sets its name as Ena does; -.07em takes back the E's side bearing, so its stem stands on
   the text edge. */
.face-title.ena{font-family:Archivo,sans-serif;font-weight:650;font-stretch:112%;font-size:132px;line-height:1;letter-spacing:-.034em;text-transform:uppercase;margin:18px 0 52px -.07em}
.service-details{display:grid;gap:27px;margin:47px 0 0}
.service-details>div{padding-bottom:25px;border-bottom:1px solid #903e3740}.service-details>div:last-child{border:0}
.service-details dt{font-size:40px;line-height:1.1;font-weight:600;letter-spacing:-.02em}.service-details dd{font-size:33px;line-height:1.24;margin:9px 0 0}
.project-about{font-size:38px;line-height:1.26;text-wrap:pretty}.project-about p+p{margin-top:26px}
.open-project{align-self:center;margin-top:38px}
.menu-content.is-turning{pointer-events:none}
.olive-notes{position:absolute;left:0;top:0;transform-origin:0 0;pointer-events:none;z-index:4}
.menu-only .olive-notes{display:none}
.bowl-shadow{position:absolute;border-radius:50%;pointer-events:none;background:radial-gradient(closest-side,rgba(52,34,22,.34),rgba(52,34,22,.20) 54%,rgba(52,34,22,0) 82%)}
.bowl-still{position:absolute;pointer-events:none}
.menu-only .site-nav,.menu-only .studio-footer{display:none}
.menu-only .experience{width:790px;min-height:0;height:1264px;background:transparent;overflow:visible}
.menu-only .table,.menu-only .table-video,.menu-only .olive-scene,.menu-only #film,.menu-only .tracking-overlay,.menu-only .loading{display:none}
.menu-only .table-stage,.menu-only .scene,.menu-only .menu-placement{position:relative;inset:auto;width:790px;height:1264px;transform:none;visibility:visible;overflow:visible}
.menu-only .card-rotator{box-shadow:none}.menu-only #opaque-film,.menu-only #paper-continuation{display:none!important}
.no-script{max-width:640px;margin:60px auto;padding:24px}.no-script h1{font-size:48px}.no-script h2{font-size:32px;text-align:left;margin-top:35px}.no-script p,.no-script a{display:block;font-size:24px;line-height:1.5;margin-top:16px;color:inherit}
@media(max-width:600px){:root{--card-top-space:72px;--card-bottom-space:72px}.site-nav{height:64px;padding:0 17px;gap:15px}.site-nav .site-home{font-size:14px}.site-nav nav{gap:18px}.site-nav nav button{font-size:14px}}
@media(max-width:370px){.site-nav{padding:0 12px;gap:10px}.site-nav .site-home{font-size:13px}.site-nav nav{gap:12px}.site-nav nav button{font-size:13px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important}.scroll-cue,.kitchen-rule span{transition:none}}

/* A baked serve: the film carries the printing, the hand and the shadow, and the
   live HTML card takes over only once the printed one has come to rest. */
.serve-film { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
body[data-scene-mode="baked"] .menu-placement { transition: opacity .28s ease; }

/* Neutral leaf shadows; the separate highlight wash supplies the warmth. */
body[data-scene-mode="baked"] .table-video {
  filter: grayscale(1) contrast(1.18) brightness(1.10);
}
/* A second, much slower pass of the same film, offset and scaled, so the canopy does
   not read as one repeating loop. */
body[data-scene-mode="baked"] .table-stage::after {
  content: ""; position: absolute; inset: -10%; z-index: 3; pointer-events: none;
  background: radial-gradient(60% 45% at 22% 18%, rgba(255,243,216,.23), rgba(255,243,216,0) 70%),
              radial-gradient(45% 38% at 82% 72%, rgba(255,246,224,.16), rgba(255,246,224,0) 72%),
              radial-gradient(70% 60% at 50% 110%, rgba(65,68,60,.12), rgba(65,68,60,0) 70%);
  mix-blend-mode: soft-light;
}

/* Wind in the branches. The light film already loops, but it is a slow soft dapple
   and on its own it reads as a still afternoon. Drifting and turning it very slightly
   moves the leaf shadows across the cloth; the wash below runs on a different period
   so the two never come back into step and the loop cannot be counted. Scaled up
   enough that the drift never walks an edge into frame. */
@keyframes canopy-sway {
  0%   { transform: scale(1.44) translate3d(-6.8%, -3.6%, 0) rotate(-1.5deg); }
  37%  { transform: scale(1.48) translate3d(5.1%,  3.3%, 0) rotate(1.35deg); }
  68%  { transform: scale(1.46) translate3d(7.2%, -2.7%, 0) rotate(1.8deg); }
  100% { transform: scale(1.44) translate3d(-6.8%, -3.6%, 0) rotate(-1.5deg); }
}
@keyframes canopy-breath {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: .85; }
  50%  { transform: translate3d(4%, -2.5%, 0) scale(1.09); opacity: 1; }
  100% { transform: translate3d(0, 0, 0) scale(1); opacity: .85; }
}
body[data-scene-mode="baked"] .table-video {
  animation: canopy-sway 11s ease-in-out infinite;
  transform-origin: 52% 46%; will-change: transform;
}
body[data-scene-mode="baked"] .table-stage::after {
  animation: canopy-breath 19.5s ease-in-out infinite;
  transform-origin: 40% 30%; will-change: transform, opacity;
}
/* A landscape light film cropped into a tall viewport loses most of its leaf
   pattern. Turn its viewport-sized box so the dapple retains a natural scale. */
@keyframes canopy-sway-portrait {
  0%, 100% { transform: translate(-50%, -50%) rotate(88.5deg) scale(1.26) translate3d(-4.5%, -3%, 0); }
  37% { transform: translate(-50%, -50%) rotate(91.2deg) scale(1.29) translate3d(3.3%, 3%, 0); }
  68% { transform: translate(-50%, -50%) rotate(91.5deg) scale(1.27) translate3d(4.5%, -2.25%, 0); }
}
@media (max-aspect-ratio: 3/4) {
  body[data-scene-mode="baked"] .table-video {
    inset: auto; left: 50%; top: 50%; width: 100svh; height: 100vw; width: 100cqh; height: max(100cqw, 56.206cqh);
    transform-origin: 50% 50%;
    transform: translate(-50%, -50%) rotate(90deg) scale(1.20);
    animation-name: canopy-sway-portrait;
  }
}
/* The light film is 3.56:1, v20's 16:9 in the middle. Up to 16:9 a window sees what
   it did; a wider one sees more leaves, and its box grows taller (40 % of the way with
   the width, at most 1.35×, centred), so the leaves grow a little too, and the drift
   with them. A phone's box is tall enough to keep v20's leaf size. */
@supports (width: 1cqh) {
  body[data-scene-mode="baked"] .table-video { --light-h: clamp(100cqh, 60cqh + 22.482cqw, 135cqh); }
  @media (min-aspect-ratio: 16/9) {
    body[data-scene-mode="baked"] .table-video { top: calc(50cqh - var(--light-h) / 2); height: var(--light-h); }
  }
  @keyframes canopy-sway {
    0%   { transform: scale(1.44) translate3d(max(-6.8cqw, -.12098 * var(--light-h)), -3.6%, 0) rotate(-1.5deg); }
    37%  { transform: scale(1.48) translate3d(min(5.1cqw, .09074 * var(--light-h)), 3.3%, 0) rotate(1.35deg); }
    68%  { transform: scale(1.46) translate3d(min(7.2cqw, .1281 * var(--light-h)), -2.7%, 0) rotate(1.8deg); }
    100% { transform: scale(1.44) translate3d(max(-6.8cqw, -.12098 * var(--light-h)), -3.6%, 0) rotate(-1.5deg); }
  }
  @keyframes canopy-sway-portrait {
    0%, 100% { transform: translate(-50%, -50%) rotate(88.5deg) scale(1.26) translate3d(-4.5%, -3cqw, 0); }
    37% { transform: translate(-50%, -50%) rotate(91.2deg) scale(1.29) translate3d(3.3%, 3cqw, 0); }
    68% { transform: translate(-50%, -50%) rotate(91.5deg) scale(1.27) translate3d(4.5%, -2.25cqw, 0); }
  }
}
@media (prefers-reduced-motion: reduce) {
  body[data-scene-mode="baked"] .table-video,
  body[data-scene-mode="baked"] .table-stage::after { animation: none; }
  /* Held at the sway's middle pose, so the leaves keep their size. */
  body[data-scene-mode="baked"] .table-video { transform: scale(1.46) rotate(.5deg); }
}
@media (prefers-reduced-motion: reduce) and (max-aspect-ratio: 3/4) {
  body[data-scene-mode="baked"] .table-video { transform: translate(-50%, -50%) rotate(90.4deg) scale(1.27); }
}

/* The live card takes over from a photographed one, and the two papers are not the
   same cream: measured at the swap, the HTML card was [243 226 197] against the
   film's [237 218 184] — brighter, and most of it in blue, so the card jumped cooler
   the moment it was handed over. A multiply of exactly that ratio (237/243, 218/226,
   184/197 of white) puts the live paper on the filmed paper's tone. The olive-tree
   light multiplies over both equally, so correcting the base is enough. */
body[data-scene-mode="baked"] .card-rotator::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: rgb(249, 246, 238); mix-blend-mode: multiply;
}

/* The tracked live rectangle is the printed artwork, inset inside the filmed
   sheet. Keep that registration for the type, and extend only the paper to the
   physical edges. Derived from printInset [.025,.018] + printShift [0,-.0045].
   The paper also keeps the shadow the film leaves under it at rest, or the shadow
   lifts off the table as the film fades out: a contact line along the lower and
   right edges, and, where the sheet's lower left lifts a little, a band that runs
   from the corner to 270 card px at 31 px deep and on to 352 px at 23 px, darkest
   in its first 8 px. Each band is the sheet shrunk by its spread and pushed down
   and left by its offset, so only that strip shows below the edge. Matched to the
   film at the handoff. */
body[data-scene-mode="baked"] .card-rotator{box-shadow:none}
body[data-scene-mode="baked"] .card-rotator::before{
  inset:-1.4% -2.632% -2.334%;opacity:1;background-color:var(--paper);mix-blend-mode:normal;
  box-shadow:3px 5px 3px -1px #3f2e2033,2px 6px 14px #4a3a2a26,
             -271px 322px 7px -291px #3f2e201a,-230px 273px 7px -250px #3f2e201a,
             -255px 285px 3px -277px #3f2e2038;
  transition:box-shadow .25s ease;
}
/* Until the handoff the film's own shadow lies under the paper, and player.js fades
   the film out over .25 s: the live shadow comes in over the same .25 s, so the two
   never stack into a darker band for a moment. */
body[data-scene-mode="baked"]:not([data-card-ready="true"]) .card-rotator::before{
  box-shadow:3px 5px 3px -1px #3f2e2000,2px 6px 14px #4a3a2a00,
             -271px 322px 7px -291px #3f2e2000,-230px 273px 7px -250px #3f2e2000,
             -255px 285px 3px -277px #3f2e2000;
}
@media(prefers-reduced-motion:reduce){body[data-scene-mode="baked"] .card-rotator::before{transition:none}}
body[data-scene-mode="baked"] .card-rotator::after{inset:-1.4% -2.632% -2.334%}
body[data-card-fallback] .card-rotator::before,body[data-card-fallback] .card-rotator::after{inset:0}
