/* Step Inside. A living painting fills the screen behind the career; each job's facts sit on a solid notebook page over
   the left of the painting (never text on paint), then the page scrolls away and the whole world shows with only its
   title tag. After the career comes the Workbench, a cloth-bound book of Robert's projects. */
:root{--cloth:#34503a;--foil:#d9b46a;--graphite:#5f5a54;--tape:rgba(240,225,180,.78)}

/* Header: name, links, and the one control that stops all motion. */
.live .site-header{background:rgba(251,246,234,.9)}
.live .brand em{color:var(--terracotta)}
.motion-toggle{display:inline-flex;align-items:center;justify-content:center;min-width:9.4em;gap:8px;min-height:44px;padding:8px 14px;background:var(--paper);border:1.5px solid var(--ink);border-radius:var(--radius);cursor:pointer;font:500 15px/1 var(--body)}
.motion-toggle:hover{background:var(--paper-2)}
.motion-icon{width:12px;height:12px;background:linear-gradient(90deg,var(--ink) 0 35%,transparent 35% 65%,var(--ink) 65%)}
[data-motion=reduced] .motion-toggle{background:var(--paper-2)}
[data-motion=reduced] .motion-toggle .motion-icon{background:var(--ink);clip-path:polygon(0 0,100% 50%,0 100%)}
.live .header-cta{background:var(--ink);color:var(--paper);border-color:var(--ink)}
@media (max-width:860px){.live .site-header{gap:10px}.motion-word{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.motion-toggle{padding:8px 12px;min-width:5.2em}}
/* Hover feedback on the controls that had none (mouse only). */
/* Phones and tablets keep a way to write on screen: the Email button stays in the header (the Menu has it too). Below 520 px
   it says just "Email" and Pause shows only its icon (both keep their full names for screen readers); below 370 px the
   brand needs the room, so Email lives in the Menu alone. */
@media (max-width:860px){.live .site-header .header-cta{display:inline-flex;padding:8px 12px}}
@media (max-width:520px){.live .site-header{gap:6px}.live .motion-toggle{min-width:44px;width:44px;padding:0}.live .motion-label,.cta-word{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.mobile-nav summary{padding-inline:10px}}
@media (max-width:400px){.live .site-header{padding-inline:10px}.mobile-nav summary{padding-inline:8px}}
@media (max-width:359px){.live .site-header .header-cta{display:none}}
@media (hover:hover) and (pointer:fine){.live .header-cta:hover{background:var(--ink-2);color:var(--paper)}.mag-controls button:not([aria-disabled=true]):hover{background:var(--paper-2)}.mag-corner:hover{box-shadow:-5px -5px 8px rgba(59,47,37,.24);filter:brightness(1.05)}}
.mag-corner{transition:box-shadow var(--d-touch) var(--ease-settle),filter var(--d-touch) var(--ease-settle)}
/* The phone menu shows when it is open, and unfolds a touch. */
.mobile-nav summary{background:var(--paper)}
.mobile-nav[open] summary{background:var(--ink);color:var(--paper)}
.mobile-nav nav{transform-origin:top right}


/* The stage: sticky behind the pages, full screen. Two canvases trade places as the reader moves between jobs. */
.inside{position:relative;overflow:clip} /* the stage may hang 100svh below its section (negative margin); clip it there */
.stage{position:sticky;top:0;height:100svh;margin-bottom:-100svh;overflow:hidden;background:var(--paper-3);z-index:0}
.stage canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transform-origin:68% 42%;background:var(--paper-3) center/cover no-repeat}
/* Changing worlds (films/window.js). The new world opens out from Robert on top (.blooming), through a watercolour edge
   (.ink, Codex's bloom) or, until that has loaded, a soft round one, and settles a touch, centred on him; on phones too, in
   the painting band. Motion off: a 0.3 s fade (.leaving), which fades back (.returning) if the reader turns back.
   Gentle on purpose: it happens eight times a read. */
@property --r{syntax:'<length>';inherits:false;initial-value:0px}
@property --s{syntax:'<length>';inherits:false;initial-value:0px}
.stage canvas.front{opacity:1;animation:settle 900ms var(--ease-paper)}
@keyframes settle{from{transform:scale(1.02)}}
.stage canvas.leaving{z-index:1;opacity:0;transform:scale(1.04);animation:none;transition:opacity 600ms cubic-bezier(.33,1,.68,1),transform 600ms cubic-bezier(.33,1,.68,1)}
[data-motion=reduced] .stage canvas.leaving{transition:opacity .3s linear!important;transform:none}
/* turning back mid-fade: the old world fades back in rather than cutting */
.stage canvas.returning{transition:opacity 600ms cubic-bezier(.33,1,.68,1)}
[data-motion=reduced] .stage canvas.returning{transition:opacity .3s linear!important}
.stage canvas.blooming{z-index:2;mask-image:radial-gradient(circle at var(--ox) var(--oy),#000 var(--r),transparent calc(var(--r) + 14vmax));-webkit-mask-image:radial-gradient(circle at var(--ox) var(--oy),#000 var(--r),transparent calc(var(--r) + 14vmax))}
.stage canvas.blooming.ink{mask-image:url(assets/films/site/bloom.webp);-webkit-mask-image:url(assets/films/site/bloom.webp);mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;
 mask-size:var(--s) var(--s);-webkit-mask-size:var(--s) var(--s);mask-position:calc(var(--ox) - var(--s)/2) calc(var(--oy) - var(--s)/2);-webkit-mask-position:calc(var(--ox) - var(--s)/2) calc(var(--oy) - var(--s)/2)}
/* A pause's title tag stands down once its world has left the stage (desktop, where the tags are sticky). */
@media (min-width:900px),(orientation:landscape){.ma .tag{transition:opacity var(--d-step) var(--ease-settle)}.ma.stale .tag{opacity:0}}
.pages{position:relative;z-index:1;padding-top:1px}

/* The title page: the opening painting with nothing over it but a paper title card in its quiet lower left, like the
   first page of a picture book. The little forest spirits sit on the card; a gentle cue leads into the notebook. */
.title-page{min-height:calc(100svh - 61px);display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-start;padding:0 0 8vh}
.title-card{position:relative;margin-left:clamp(16px,3vw,48px);max-width:min(600px,calc(100vw - 32px));padding:clamp(22px,2.4vw,34px) clamp(26px,3vw,44px) clamp(18px,2vw,26px);background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-paper);rotate:-1deg}
.title-card::before,.title-card::after{content:'';position:absolute;top:-11px;width:84px;height:24px;background:var(--tape-img) 0 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}
.title-card::before{left:-18px;rotate:-38deg}.title-card::after{right:-18px;rotate:36deg;background-position:50% 0}
.title-kicker{font:500 12px/1.3 var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.title-card h1{font-size:clamp(58px,7.2vw,108px);font-variation-settings:"SOFT" 100,"WONK" 1;font-weight:400;line-height:.92;margin:.14em 0 .12em}
.title-role{font:500 clamp(18px,1.6vw,22px)/1.35 var(--display)}
.title-film{margin-top:16px;padding-top:12px;border-top:1px dotted var(--line);font-size:14px;color:var(--ink-2)}
/* On arrival the card is laid on the painting like a sheet of paper, its tape pressed down, then the cue rises. Once per
   visit: live.js marks the page .arrived when the cue has risen, so Pause then Play doesn't replay it. The new motion keys
   off the header switch ([data-motion=full], set before first paint by the inline script in index.html), so Pause stops
   it and Play starts it whatever the device's own setting. */
@media screen{
 [data-motion=full]:not(.arrived) .title-card{animation:card-land var(--d-paper) var(--ease-settle) .15s both}
 [data-motion=full]:not(.arrived) .title-card::before,[data-motion=full]:not(.arrived) .title-card::after{animation:tape-press var(--d-step) var(--ease-settle) .75s both}
 [data-motion=full]:not(.arrived) .title-scroll{animation:cue-rise var(--d-paper) var(--ease-settle) 1.05s both}}
@keyframes card-land{from{opacity:0;translate:0 -16px;rotate:-2.6deg}}
@keyframes tape-press{from{opacity:0;scale:1.25}}
@keyframes cue-rise{from{opacity:0;translate:0 8px}}
/* Stepping inside: on wide screens the opening painting pushes gently in (to 1.04, about 30 px at its edges) as the reader
   scrolls off the title card, holds through the fact page and eases back before the first job's world arrives. Tied to the
   scroll, so it's the reader's own movement; motion off, it doesn't happen. */
@supports (animation-timeline:scroll()){@media screen and (min-width:900px){
 [data-motion=full] .stage{transform-origin:66% 59%;animation:step-in linear both;animation-timeline:scroll(root);animation-range:0 220vh}}}
@keyframes step-in{40%,75%{scale:1.04}}
/* Each job page and the letter settle into place as they come up the screen (the opening facts and the career list,
   read first, never fade), tied to the scroll itself (not a timer), so a jump
   straight to a job finds its page already down. Where scroll-driven animation isn't supported, sheets simply sit.
   The job page's whole leaf moves, timed by its sheet: animating the sheet itself would make it a stacking context and
   lift the soot sprites that hide behind job 2's page in front of it. The fade is done by 45%, so no page rests ghosted. */
@supports (animation-timeline:view()){@media screen{
 .leaf.job .sheet{view-timeline-name:--page}
 [data-motion=full] .leaf.job{timeline-scope:--page;animation:sheet-in linear both;animation-timeline:--page;animation-range:entry 0% entry 55%}
 [data-motion=full] .letter{animation:sheet-in linear both;animation-timeline:view();animation-range:entry 0% entry 55%}}}
@keyframes sheet-in{from{opacity:0;translate:0 36px}45%{opacity:1}}
.title-film b{margin:0 4px;font:italic 500 clamp(19px,1.6vw,22px)/1.2 var(--display);font-variation-settings:var(--soft);color:var(--terracotta)}
.title-scroll{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin:22px 0 0 clamp(16px,3vw,48px);padding:10px 18px;background:var(--paper-tex),var(--sheet);border:1px solid var(--line);border-radius:0;box-shadow:var(--shadow-tag);font:500 15px/1 var(--body);color:var(--ink);text-decoration:none}
.title-scroll:hover{background:var(--paper-2)}
.title-scroll i{font-style:normal;animation:nudge 2.6s var(--ease-paper) 2.4s 2}
@keyframes nudge{0%,55%,100%{transform:none}25%{transform:translateY(4px)}}
.title-card .cameo{transition:opacity var(--d-step) var(--ease-settle),translate var(--d-paper) var(--ease-creature)}
@starting-style{.title-card .cameo{opacity:0;translate:0 12px}}
@media (max-width:899px) and (orientation:portrait){.title-page{min-height:0;padding:22px 0 6px}.title-card{margin:0 16px;rotate:0deg}.title-scroll{margin-left:16px}}

/* Notebook pages: solid paper with a strip of washi tape, over the quiet left third of each painting. */
.leaf{padding:14vh 0 10vh}
.leaf.opening{min-height:calc(100svh - 61px);display:flex;align-items:center;padding:6vh 0}
.sheet{position:relative;width:clamp(340px,32vw,480px);margin-left:clamp(16px,3vw,48px);padding:clamp(24px,2.6vw,36px);background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-paper)}
.sheet p{text-wrap:pretty}
.sheet::before{content:'';position:absolute;top:-12px;left:28%;width:98px;height:28px;transform:translateX(-50%) rotate(-3deg);background:var(--tape-img) 0 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}

.opening-role{font:500 clamp(19px,1.7vw,23px)/1.35 var(--display);margin-bottom:1em}
.ledger{list-style:none;padding:0;margin:0 0 22px;border-top:1px solid var(--line)}
.ledger li{display:grid;grid-template-columns:minmax(6.2em,auto) 1fr;align-items:baseline;gap:0 14px;padding:10px 0;border-bottom:1px dotted var(--line)}
.ledger b{grid-row:span 2;font:500 clamp(24px,2.3vw,32px)/1 var(--display);color:var(--terracotta);font-variant-numeric:lining-nums tabular-nums;white-space:nowrap}
.ledger span{font-size:15px;line-height:1.3}
.ledger small{font-size:13px;color:var(--muted)}
.opening-links{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 10px}
.plain-link{font-size:14px;margin:0}
.work-head h2{font-size:clamp(34px,3.4vw,52px)}
.work-head p{color:var(--ink-2);margin:0}
.job h3{font-size:clamp(30px,2.8vw,42px);margin-bottom:.15em}
.job-role{font-weight:600;margin-bottom:.4em}
.job-context{font-size:15px;color:var(--ink-2)}
.job-proof{font:italic 400 19px/1.45 var(--display);border-left:3px solid var(--terracotta);padding-left:14px}
.job-summary{color:var(--ink-2)}
.day-line{font:italic 400 15px/1.4 var(--display);color:var(--muted);margin:14px 0 0}
.day-line span{font:500 12px/1 var(--body);font-style:normal;letter-spacing:.12em;text-transform:uppercase;margin-right:6px}
/* The career index on the "help desk" page: one row per job, newest first. */
.career-index{list-style:none;padding:0;margin:18px 0 0;border-top:1px solid var(--line)}
.career-index a{display:grid;grid-template-columns:72px 8.4em 1fr auto;gap:0 14px;align-items:start;padding:4px 0;border-bottom:1px dotted var(--line);text-decoration:none;color:var(--ink)}
.career-index em{grid-column:4;grid-row:1;font:500 13px/1.5 var(--body);font-style:normal;color:var(--muted);text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums;padding-top:.15em}
.career-index small{font-size:12px;color:var(--muted)}
@media (min-width:900px){.work-head .sheet{width:clamp(420px,48vw,700px)}} /* the career summary is read, not glanced: wide enough that roles don't wrap */
.career-index span{grid-column:2;grid-row:1/3;font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums;padding-top:.2em}
.career-index b{grid-column:3;font:500 17px/1.25 var(--display)}
/* each job's painting, small, as on a contact sheet: the eight worlds seen together */
.career-index img{grid-column:1;grid-row:1/3;width:72px;height:41px;object-fit:cover;padding:2px;background:var(--sheet);border:1px solid var(--line);box-shadow:0 1px 2px rgb(42 34 27/.15);rotate:-1deg}
.career-index li:nth-child(even) img{rotate:1deg}
.career-index i{grid-column:3;font-size:14px;font-style:normal;color:var(--ink-2)}
@media (hover:hover){.career-index a:hover b{color:var(--terracotta)}}
/* Hovers ease in at the site's touch speed rather than snapping (mouse only; Pause turns transitions off). */
@media (hover:hover) and (pointer:fine){.career-index b,.site-header nav a,.wb-toc button span,.letter-links a,.live .header-cta{transition:color var(--d-touch) var(--ease-settle),background-color var(--d-touch) var(--ease-settle)}
 .systems-map a,.cert-grid a{transition:color var(--d-touch) var(--ease-settle),transform .2s}}
.career-tools{margin:6px 0 0;font-size:14px;line-height:1.5;color:var(--ink-2)}
/* A job's result line: its numbers stand out in the ledger's terracotta. */
.job-proof .num{font-weight:600;font-style:normal;color:var(--terracotta);font-variant-numeric:lining-nums}
/* The career timeline: in the header's empty middle (it never covers a painting), wide screens only, while the career is
   on screen. Dots on a thread, the job on stage filled and named beneath. */
.site-header .career-rail{display:none}
@media (min-width:1200px){
  .site-header .career-rail{display:flex;flex-direction:column;align-items:center;gap:1px;flex:none;margin-right:auto;opacity:0;visibility:hidden;transition:opacity var(--d-step) var(--ease-settle),visibility 0s linear var(--d-step)}
  .site-header .career-rail.on{opacity:1;visibility:visible;transition:opacity var(--d-step) var(--ease-settle)}
  .site-header .career-rail ol{list-style:none;margin:0;padding:0;display:flex;position:relative}
  .site-header .career-rail ol::before{content:'';position:absolute;left:11px;right:11px;top:50%;border-top:1px solid var(--line)}
  .site-header .career-rail a{position:relative;display:grid;place-items:center;width:24px;height:22px}
  .site-header .career-rail a::before{content:'';width:9px;height:9px;border-radius:50%;background:var(--sheet);border:1.5px solid var(--graphite);transition:background-color var(--d-touch) var(--ease-settle),scale var(--d-touch) var(--ease-settle)}
  .site-header .career-rail a:hover::before, .site-header .career-rail a:focus-visible::before{background:var(--paper-2);border-color:var(--ink);scale:1.15}
  .site-header .career-rail a.here::before{background:var(--terracotta);border-color:var(--terracotta);scale:1.3}
  .site-header .career-rail-label{margin:0;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:500 13px/1.2 var(--display);color:var(--ink)}
  .site-header .career-rail-label span{font:400 12px/1 var(--body);color:var(--muted);font-variant-numeric:tabular-nums lining-nums}}
@media print{.career-rail{display:none!important}.bring{background:none;padding:8mm 0}.bring-sheet{rotate:none;box-shadow:none;border:0;padding:0;background:none}.bring-sheet::before{display:none}}
@media (max-width:600px),(orientation:landscape) and (max-height:500px){.career-index a{grid-template-columns:56px 1fr auto}.career-index img{width:56px;height:32px;grid-row:1/4}.career-index span{grid-column:2;grid-row:1;padding:0}.career-index em{grid-column:3;grid-row:1}.career-index b,.career-index i{grid-column:2/-1}} /* phones (and phones held sideways, where the sheet is 340 px): the painting beside, dates over the job */
.job-evidence{border-top:1px solid var(--line);padding:10px 0 0;margin-top:16px}
.job-evidence summary{cursor:pointer;list-style:none;font-weight:600;min-height:32px;text-decoration:underline;text-underline-offset:.25em;text-decoration-color:var(--line)}
.job-evidence summary::-webkit-details-marker{display:none}
.job-evidence summary::before{content:'▸'/'';display:inline-block;margin-right:8px;color:var(--terracotta);transition:transform var(--d-step) var(--ease-settle)} /* turns with the fold's own 0.4 s unfold */
.job-evidence[open] summary::before{transform:rotate(90deg)}
/* The fold unfolds rather than snapping open, where the browser can animate <details>. */
@supports selector(::details-content){@media screen{
 .job-evidence{interpolate-size:allow-keywords}
 [data-motion=full] .job-evidence::details-content{block-size:0;overflow:clip;transition:block-size var(--d-step) var(--ease-settle),content-visibility var(--d-step) allow-discrete}
 .job-evidence[open]::details-content{block-size:auto}}}
.job-evidence ul{padding-left:20px;margin:8px 0 12px;font-size:15px}
.job-evidence li{margin-bottom:6px}
.job-sources{display:flex;flex-wrap:wrap;gap:12px;font-size:15px}
.scene-note{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap} /* names the scene for screen readers; the tag shows it */

/* "Ma": a pause where the whole painting shows, with only its title tag pinned bottom-left on paper. */
.ma{height:72svh;position:relative}
/* Tape on each job's sheet in the drawn tape's own shape (98x28 keeps its 280x80 proportions), stuck down by a different hand
   job to job: left and sage on jobs 1, 3, 5, 7, right and rose on 2, 4, 6, 8. The opening page keeps its centred cream strip. */
.leaf.job:is(#job-1,#job-3,#job-5,#job-7) .sheet::before{left:72%;transform:translateX(-50%) rotate(2deg);background-position:50% 0}
.leaf.opening .sheet::before{left:50%;transform:translateX(-50%) rotate(-2deg);background-position:100% 0}
/* The title tags are pinned by a corner of tape at the left (clear of the pets, who sit further along), and sit a hair off
   square. The forest's tag needs none: its kodama hold it down. */
.tag::before{content:'';position:absolute;top:-9px;left:-14px;width:70px;height:20px;rotate:-34deg;background:var(--tape-img) 0 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}
.ma[data-scene=f6] .tag::before{display:none}
.tag{rotate:-.6deg;position:sticky;top:calc(100svh - 128px);display:inline-flex;flex-direction:column;gap:2px;margin:0 0 0 clamp(16px,3vw,48px);padding:12px 18px;background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-tag)}
.tag b{font:italic 500 clamp(22px,2.4vw,34px)/1.1 var(--display);font-variation-settings:var(--soft)}
.tag span{font-size:14px;color:var(--ink-2)}
.tag .nw{white-space:nowrap;font-style:normal}

/* Phones held upright: the painting becomes a sticky band under the header (at most a third of the screen) and the pages
   scroll beneath it at full width. The band frames the scene a little closer, past the quiet left third that only the
   desktop's notebook page needs. Phones on their side keep the desktop layout, so the text is never hidden. */
@media (max-width:899px) and (orientation:portrait){
 :root{--band:min(56.25vw,36svh)}
 /* only the career sits under the painting band; later sections land just under the header */
 html{scroll-padding-top:65px}
 .pages *{scroll-margin-top:calc(var(--band) + 8px)}
 .site-header{padding-block:6px}
 .stage{top:57px;height:var(--band);margin-bottom:calc(-1 * var(--band));z-index:2;box-shadow:0 8px 20px -12px rgba(42,34,27,.6)}
 .stage canvas{inset:auto;max-width:none;width:120%;height:120%;left:-16%;top:-10%;transform-origin:50% 50%}
 .stage canvas.front{animation:none}.stage canvas.leaving{transform:none}
 .pages{padding-top:var(--band)}
 .leaf,.leaf.opening{padding:28px 0;min-height:0}
 .sheet{width:auto;margin:0 16px}
 .leaf.opening .sheet{flex:1}  /* the opening sheet fills the width like the job pages (it sat at 505 of 736 px on tablets) */
 .ma{height:auto;padding:4px 0 8px}
 .tag{position:relative;top:auto;margin:0 16px}
 /* the sheets lie on a darker page than themselves, so they read as paper laid down rather than cards */
 .inside{background:var(--paper-3)}
}
/* Touch: the small text links get a full 44 px target. */
@media (pointer:coarse){.job-evidence summary,.job-sources a,.job-steps a,.letter-links a,.plain-link a,.wb-more,.wb-links a,.lost-links a{min-height:44px;display:inline-flex;align-items:center}}
/* Previous and next job at the foot of each page, named, so a reader can step through the career without the list. */
.job-steps{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;margin-top:14px;font-size:14px}
.job-steps a{color:var(--ink-2);text-underline-offset:.2em}
.site-header nav a[aria-current]{color:var(--terracotta);text-decoration:underline 2px;text-underline-offset:.35em}
.mobile-nav nav a[aria-current]{font-weight:600;box-shadow:inset 3px 0 var(--terracotta)}

/* The Workbench: a cloth-bound art book on a lamp-lit table. */
/* As a list (and in print), the pages lie flat in order: the book's spread slots, corners and creatures step aside. */
.mag:not(.mag-on) :is(.mag-slot,.mag-corner,.mag-sheet,.fox-strip,.playground,.flip){display:none}
.workbench{position:relative;isolation:isolate;background:var(--paper-2);border-top:1px solid var(--line)}
.workbench::before{content:'';position:absolute;inset:0;z-index:-1;background:radial-gradient(ellipse at 50% 20%,rgba(233,178,92,.2),transparent 60%);animation:breath var(--d-breath) var(--ease-paper) infinite alternate;pointer-events:none}
@keyframes breath{from{opacity:.65}}
/* The last painting fades into the colour of the desk below it (its average, #a2683c), not into a band of cream. */
@media (min-width:900px),(orientation:landscape){.inside::after{content:'';position:absolute;left:0;right:0;bottom:0;height:24svh;background:linear-gradient(rgb(162 104 60/0),#a2683c);pointer-events:none}}
/* What I bring lies on the same desk as the Workbench book, on one taped sheet, so the evening carries on from the book to
   the letter with no stretch of bare page. The desk is pinned to the screen in both sections, so it reads as one desk the
   book and the sheet slide over (where fixed backgrounds aren't supported, each section simply shows its own). */
.bring{padding:clamp(64px,8vw,120px) var(--gutter);background:linear-gradient(rgb(239 228 207/0),var(--paper-2)) bottom/100% 180px no-repeat,var(--paper-2)}
.bring-sheet{position:relative;max-width:1120px;margin:0 auto;padding:clamp(26px,4vw,56px);background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-paper);rotate:.25deg}
.bring-sheet::before{content:'';position:absolute;top:-12px;left:50%;width:98px;height:28px;translate:-50% 0;rotate:-2deg;background:var(--tape-img) 0 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}
.systems-footnote{max-width:var(--measure)}
.bring :is(.systems-map,.cert-grid) a{align-content:start}
/* The end of the day: the closing letter lies over one last living painting (the farmhouse at blue hour), full width,
   fading in from the paper above. */
.contact-section{position:relative;isolation:isolate;padding-block:clamp(96px,14vw,200px)}
.dusk-frame{position:absolute;z-index:-1;top:0;left:calc(50% - 50vw);width:100vw;height:100%;overflow:hidden;-webkit-mask-image:linear-gradient(transparent,#000 180px);mask-image:linear-gradient(transparent,#000 180px)}
.dusk-living{position:absolute;inset:0;width:100%;max-width:none;height:100%;object-fit:cover;background:#2b3346 center/cover no-repeat}
/* Night falls between the desk and the letter instead of a band of cream: What I bring fades to the dark of the film
   strip and the footer carries the night on below the painting (text 8.8:1, links 11:1 on #2f3432), on every screen.
   Where the dusk runs full width it fades in out of that dark; on portrait screens the letter lies on it below the band. */
@media screen{
 .bring{background:linear-gradient(rgb(42 34 27/0),#2a221b) bottom/100% 180px no-repeat,var(--paper-2)}
 /* the desk painting loads with the Workbench's (once the reader is within a screen and a half), not with the opening */
 .workbench.near~.bring{background:linear-gradient(rgb(42 34 27/0),#2a221b) bottom/100% 180px no-repeat,url(assets/films/workbench/desk-top.webp) center/cover fixed,var(--paper-2)}
 .site-footer{background:#2f3432;color:#e3d6c1;border-top:0}
 .site-footer a,.site-footer .footer-link{color:#f6efe2}
 .site-footer a:hover,.site-footer .footer-link:hover{color:#d9b46a}
 .site-footer :focus-visible{outline-color:#f6efe2}}
@media screen and (min-width:900px),screen and (orientation:landscape){
 .dusk-frame{background:#2a221b;-webkit-mask-image:none;mask-image:none}
 .dusk-living{-webkit-mask-image:linear-gradient(transparent,#000 180px);mask-image:linear-gradient(transparent,#000 180px)}}
/* The ending answers the opening. The dusk painting pulls back from the lit study window as the letter arrives (wide screens,
   1.12 at most), the letter is taped at its corners like the title card, and 'Now showing' closes the programme. */
@supports (animation-timeline:view()){@media screen and (min-width:900px){
 .contact-section{view-timeline-name:--dusk}
 [data-motion=full] .dusk-living{transform-origin:14% 50%;animation:pull-out linear both;animation-timeline:--dusk;animation-range:entry 0% cover 50%}}}
@keyframes pull-out{from{scale:1.12}}
.contact-section .letter::before{display:none}
.letter-tapes::before,.letter-tapes::after{content:'';position:absolute;top:-11px;width:84px;height:24px;background:var(--tape-img) 0 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}
.letter-tapes::before{left:-18px;rotate:-38deg}.letter-tapes::after{right:-18px;rotate:36deg;background-position:50% 0}
.letter-film{text-align:right;margin:14px 0 0;padding-left:64px} /* clear of Calcifer in the letter's corner */
/* Portrait phones: the letter would cover nearly all of the dusk, so the painting becomes a band across the top of the closing
   section, like the opening's, with the lit window in view and the letter below; the section clips its own overhangs (the
   corner tapes reached past the screen's edge). */
@media (max-width:899px) and (orientation:portrait){
 .contact-section{overflow-x:clip;padding-top:calc(var(--band) + 40px)}
 @media screen{.contact-section{background:#2a221b}}  /* night carries on below the band: the letter lies on the dark like the desktop's */
 .dusk-frame{height:calc(var(--band) + 160px);-webkit-mask-image:linear-gradient(transparent,#000 50px,#000 calc(100% - 140px),transparent);mask-image:linear-gradient(transparent,#000 50px,#000 calc(100% - 140px),transparent)}
 .dusk-living{object-position:8% 50%}} /* Robert on the veranda and the lit window both in the band */
.letter::after{content:'';position:absolute;inset:0;z-index:-1;background:radial-gradient(60% 45% at 8% 100%,rgb(255 160 70/.14),transparent);animation:breath var(--d-breath) var(--ease-paper) infinite alternate;pointer-events:none}
.workbench{--wpw:min(clamp(300px,40vw,600px),calc((100svh - 330px)*.8))} /* label ~110 px, controls ~72 px: the whole book fits below the header */
#workbench{scroll-margin-top:calc(16px - clamp(56px,9vw,120px))} /* a jump here lands on the heading, so the whole book and its controls fit below it */
.workbench-head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:12px 40px;max-width:max(calc(var(--wpw)*2),940px);margin:0 auto 32px}
.workbench-head p{max-width:46ch;margin:0}
/* Robert's desk (Codex, assets/films/workbench/desk-top.webp): once the reader nears the Workbench, the book lies on the job 8
   desk seen from above, the paper above fading into it. The heading becomes a taped paper label and the page count sits on a
   paper slip, so neither is ever text on wood. */
.workbench.near{background:linear-gradient(#a2683c,rgb(162 104 60/0) 120px) top/100% 120px no-repeat,url(assets/films/workbench/desk-top.webp) center/cover fixed,var(--paper-2);border-top:0}
/* Previous and Next are paper slips like the page count between them, not web buttons on the wood. */
.workbench.near .mag-controls button{background:var(--paper-tex),var(--sheet);border:1px solid var(--line);border-radius:0;box-shadow:var(--shadow-tag)}
.workbench.near .mag-controls button[aria-disabled=true]{opacity:1;color:var(--muted);border-color:var(--line)}
.workbench.near .workbench-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 32px;position:relative;width:fit-content;max-width:min(100%,960px);padding:18px 26px;background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-tag);rotate:-.4deg}
.workbench.near .workbench-head h2{margin:0;font-size:clamp(40px,3.6vw,60px)}
.workbench.near .workbench-head p{max-width:34ch;font-size:15px;line-height:1.45}
.workbench.near .workbench-head::before{content:'';position:absolute;top:-11px;left:30px;width:84px;height:24px;rotate:-6deg;background:var(--tape-img) 50% 0/300% 100% no-repeat;filter:drop-shadow(var(--shadow-tape))}
.workbench.near .mag-count{padding:6px 12px;background:var(--paper-tex),var(--sheet);border:1px solid var(--line);box-shadow:var(--shadow-tag)}
.link-button{background:none;border:0;padding:0;font:inherit;color:inherit;text-decoration:underline;text-underline-offset:.2em;cursor:pointer}
.workbench .mag{--pw:var(--wpw)}
.workbench .mag-slot{aspect-ratio:.8;background:url(assets/films/workbench/paper.webp) 0 0/384px,var(--sheet)}
.workbench .mag-slot:empty{background:none;box-shadow:none}
.workbench .mag-single .mag-slot{aspect-ratio:.74}  /* one page at a time on phones: taller, so the two-project pages keep their links */
.workbench .mag-page{aspect-ratio:.8;background:url(assets/films/workbench/paper.webp) 0 0/384px,var(--sheet);padding:28px 30px 18px}
.workbench .mag-page::before{display:none}
.workbench .mag-face{background:url(assets/films/workbench/paper.webp) 0 0/384px,var(--sheet)}
.workbench .mag-book{filter:drop-shadow(0 30px 40px rgba(42,34,27,.35))}
.workbench .mag-foot{font:italic 400 13px/1 var(--display);color:var(--muted);border-top:1px solid var(--line)}
.wb-cover{justify-content:center;align-items:center;gap:14px;text-align:center;color:#f3ead7;border-radius:3px 6px 6px 3px;
 background:linear-gradient(90deg,rgba(0,0,0,.25),transparent 8%),var(--cloth)!important}
.workbench.near .wb-cover{background:linear-gradient(90deg,rgba(0,0,0,.25),transparent 8%),url(assets/films/workbench/cloth.webp) 0 0/256px,var(--cloth)!important}
.workbench.near .wb-back{background-image:linear-gradient(270deg,rgba(0,0,0,.25),transparent 8%)!important}
.wb-plate{width:62%;aspect-ratio:16/10;border:6px solid #f3ead7;background:var(--paper-3);box-shadow:0 6px 14px rgba(0,0,0,.3)}
.workbench.near .wb-plate{background:url(assets/films/workbench/cover.webp) center/cover}
.wb-title{margin:6px 0 0;font:italic 600 clamp(34px,10cqw,52px)/1 var(--display);color:var(--foil);text-shadow:0 -1px 0 rgba(0,0,0,.35),0 1px 0 rgba(255,255,255,.12)}
.wb-sub{margin:0;font-size:14px;color:#e7dcc6}
.wb-back{background-image:linear-gradient(270deg,rgba(0,0,0,.25),transparent 8%)!important}
.wb-h{font:500 clamp(24px,8cqw,32px)/1.1 var(--display)}
.wb-toc{list-style:none;padding:0;margin:8px 0 18px}
.wb-toc button{display:flex;gap:8px;width:100%;padding:7px 0;background:none;border:0;font:500 clamp(13px,3.4cqw,15px)/1.3 var(--body);color:var(--ink);cursor:pointer;text-align:left}
.wb-toc button span{flex:1;background:radial-gradient(circle,var(--line) 1px,transparent 1.5px) 0 85%/6px 6px repeat-x;padding-right:6px}
.wb-toc button b{font:italic 500 15px var(--display);color:var(--terracotta)}
.wb-toc button:hover span{color:var(--terracotta)}
.wb-intro{font-size:14px;color:var(--ink-2)}
.wb-kicker{margin:0;font:500 12px/1.3 var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.wb-num{margin:10px 0 4px;font:italic 500 clamp(44px,14cqw,84px)/1 var(--display);color:var(--terracotta)}
.wb-num i{font-style:normal}
.wb-result h3{font-size:clamp(22px,7cqw,30px);margin:6px 0}
.wb-result p{margin:0 0 8px}
.margin-note{display:inline-block;margin-top:6px;font:italic 400 15px var(--display);color:var(--graphite);transform:rotate(-1.5deg)}
/* Gate D art: a painted spot in a page corner (after the film of the job the result came from), washi tape on the
   screenshots, a pressed leaf here and there, and a pencil flipbook in every page's corner: one drawing per page, so
   turning the pages makes the little forest spirits walk. */
.spot{position:absolute;right:10px;bottom:62px;width:clamp(104px,36cqw,180px);aspect-ratio:4/3;pointer-events:none}
/* the book's painted dressing loads once the reader nears it (.near), never with the opening */
.workbench.near .spot{background:var(--spot) center/contain no-repeat}
.wb-shot::before{background:url(assets/films/workbench/tape.webp) 0 0/300% 100% no-repeat!important;width:84px!important;height:24px!important}
.wb-notes .wb-shot::before{background-position:50% 0!important}
.wb-pair section+section .wb-shot::before{background-position:100% 0!important}
.wb-contents::after,.wb-endpaper::after{content:'';position:absolute;width:74px;aspect-ratio:1;background:0 0/300% 100% no-repeat;pointer-events:none}
.workbench.near :is(.wb-contents,.wb-endpaper)::after{background-image:url(assets/films/workbench/leaves.webp)}
.wb-contents::after{top:14px;right:14px;rotate:24deg}
.wb-endpaper::after{top:18px;left:16px;rotate:-18deg;background-position:50% 0}
.workbench .mag-foot{padding-right:46px}
@media (max-width:899px){.workbench .mag-controls{display:grid;grid-template-columns:auto 1fr auto;gap:8px}.workbench .mag-count{min-width:0}}
.flip{position:absolute;right:6px;bottom:24px;width:44px;aspect-ratio:1;background:calc(var(--i) * -44px) 0/528px 44px no-repeat;opacity:.7;pointer-events:none}
.workbench.near .flip{background-image:url(assets/films/workbench/flipbook.webp)}
.wb-more{margin-top:auto;align-self:flex-start;font-size:15px}
.wb-shot{position:relative;display:block;padding:6px;border:1px dashed var(--graphite);background:#fff}
.wb-shot::before{content:'';position:absolute;top:-9px;left:16px;width:56px;height:18px;background:rgba(143,195,223,.55);transform:rotate(-4deg)}
.wb-shot img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top}
.wb-fig{font:italic 400 14px var(--display);color:var(--graphite);margin:10px 0 0}
.wb-notes h3,.wb-notes h4{font-size:clamp(20px,6.4cqw,28px);margin:6px 0}
.wb-notes p:not(.wb-kicker){margin:0 0 8px;font-size:clamp(13px,3.4cqw,15px)}
.wb-links{display:flex;flex-wrap:wrap;gap:4px 14px}
.wb-pair{gap:12px}.wb-pair section{display:grid;grid-template-columns:38% 1fr;gap:2px 14px;align-content:start}.wb-pair .wb-shot{grid-row:span 4;align-self:start}.wb-pair .wb-shot img{aspect-ratio:4/3}
/* short and narrow book pages: the contents list tightens and screenshots crop shorter, so nothing clips */
@container mag (max-height:560px){.wb-toc{margin:4px 0 8px}.wb-toc button{padding:3px 0}}
@container mag (max-width:420px){.wb-pair section{display:grid;grid-template-columns:1fr 34%;gap:2px 12px;align-content:start}.wb-pair .wb-shot{display:block;grid-column:2;grid-row:1/span 2;align-self:start;padding:3px}.wb-pair .wb-shot::before{width:52px!important;height:15px!important;left:8px}.wb-pair section>:not(.wb-shot){grid-column:1}.wb-pair section>p:not(.wb-kicker){grid-column:1/-1}.wb-shot img{aspect-ratio:2/1}.wb-toc button{line-height:1.2}.wb-intro{font-size:12.5px;line-height:1.4;margin:0}}
.mag:not(.mag-on) .mag-page{aspect-ratio:auto;container-type:inline-size}
.wb-divider{justify-content:center}
.wb-endpaper{justify-content:center;align-items:center;background:#e9e1cc!important}
.wb-postcard{position:relative;z-index:1;display:flex;flex-direction:column;gap:6px;padding:28px 32px;background:var(--sheet);border:1px solid var(--line);transform:rotate(4deg);box-shadow:0 10px 24px -10px rgba(42,34,27,.5);text-decoration:none}
.wb-postcard span{font:500 12px var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.wb-postcard b{font:italic 500 26px var(--display);color:var(--ink)}
.wb-every{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:22px;font:italic 400 16px var(--display)}
.workbench .mag-page a{color:inherit;font-weight:500}
.workbench .mag-page a.margin-note{color:var(--graphite)}
.workbench .mag-controls button{min-height:44px}

/* What I bring: a ruled list on paper, not more cards. */
.bring h2{margin-bottom:.4em}
.bring-intro{color:var(--ink-2);max-width:56ch}
.bring :is(.systems-map,.cert-grid){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 40px;margin-top:20px}
.bring :is(.systems-map,.cert-grid) a{display:grid;grid-template-columns:44px 1fr auto;gap:2px 12px;padding:14px 0;border:0;border-bottom:1px solid var(--line);background:none;box-shadow:none;text-decoration:none}
.bring :is(.systems-map,.cert-grid) a:hover{transform:none;background:var(--paper-2)}
.bring :is(.systems-map,.cert-grid) span{grid-row:span 2;font:italic 400 20px/1 var(--display);color:var(--terracotta)}
.bring :is(.systems-map,.cert-grid) strong{font:500 19px/1.2 var(--display)}
.bring :is(.systems-map,.cert-grid) small{grid-column:2;font-size:14px;color:var(--ink-2)}
.bring :is(.systems-map,.cert-grid) b{grid-column:3;grid-row:1;font-size:14px;padding:0;margin:0}
.list-head{font:italic 500 24px/1.2 var(--display);color:var(--terracotta);margin:36px 0 14px}
@media (max-width:760px){.bring :is(.systems-map,.cert-grid){grid-template-columns:1fr}}
/* Below 1000 px the link drops under its description instead of taking a column (titles were squeezed to four lines). */
@media (max-width:1000px){.bring :is(.systems-map,.cert-grid) a{grid-template-columns:36px 1fr}.bring :is(.systems-map,.cert-grid) b{grid-column:2;grid-row:auto;padding-top:4px}}

@media print{.stage,.motion-toggle,.ma,.mobile-nav{display:none!important}.sheet{width:auto;margin:0;box-shadow:none}.sheet::before{display:none}.pages{padding:0}.leaf{padding:8mm 0}.scene-note{position:static;width:auto;height:auto;clip:auto;font-style:italic}}

/* Page creatures (films/critters.js). Decoration only, kept to edges, still when motion is off. Every motion here is a CSS
   animation or transition, so the Pause button's kill switch (styles.css) freezes it; JS only toggles classes.
   Shy creatures creep out slowly with a little overshoot and bolt back fast. */
.critter{display:inline-block;width:var(--s);line-height:0;pointer-events:none}
.critter svg{display:block;width:100%;height:auto;overflow:visible}
.soot .pupils{animation:glance var(--glance,3.6s) steps(1) infinite}
@keyframes glance{0%{transform:none}35%{transform:translate(-2.5px,.5px)}62%{transform:translate(2.5px,-1px)}85%{transform:translate(0,1.5px)}}
/* Behind the Spirited Away page: z-index -1 puts them behind the sheet's paper, so they peek out from its right edge. */
.peeker{position:absolute;right:0;z-index:-1;pointer-events:auto;transform:translate(0,-50%);transition:transform .16s cubic-bezier(.55,0,.85,.35)}
.peeker.out{transform:translate(70%,-50%) rotate(9deg);transition:transform .6s cubic-bezier(.25,1.35,.5,1)}
@media (max-width:899px){.peeker.out{transform:translate(40%,-50%) rotate(9deg)}}  /* the phone gutter is 16 px: lean out less */
/* Kodama perched on the forest film's title tag; the head rattles from its base, one after another. */
.perch{position:absolute;bottom:calc(100% - 4px)}
/* The IT pets sit at the right end of their tag. */
.kodama .head{transform-box:fill-box;transform-origin:50% 92%}
.kodama.rattle .head{animation:rattle .9s ease-in-out}
@keyframes rattle{0%,100%{transform:none}10%{transform:rotate(-14deg)}25%{transform:rotate(12deg)}40%{transform:rotate(-10deg)}55%{transform:rotate(8deg)}70%{transform:rotate(-4deg)}}
@media (max-width:899px){.ma .kodama.perch{width:28px}}
/* The header kodama sits hidden under the header bar and leans down into view, once. */
.from-header{position:fixed;top:var(--hdr,61px);right:clamp(140px,24vw,420px);z-index:49;transform:translateY(-100%);transition:transform .16s cubic-bezier(.55,0,.85,.35)}
.from-header.out{transform:translateY(-38%) rotate(-6deg);transition:transform .6s cubic-bezier(.25,1.35,.5,1)}
/* Catch on the Workbench table, in short rallies: the star flies across on one wrapper and arcs on another (rising
   slows, falling speeds up), spinning one way; each catcher squashes as it lands. Between rallies they rest. */
.playground{position:relative;height:72px;max-width:520px;margin:10px auto 0}
.catcher{position:absolute;bottom:4px;transform-origin:50% 100%;transition:translate .6s cubic-bezier(.3,1.4,.5,1),scale .6s cubic-bezier(.3,1.4,.5,1),opacity .4s ease-out;pointer-events:auto}
.catcher.left{left:0}.catcher.right{right:0;transition-delay:.12s}
.playground.rally .catcher.left{animation:hop 2.4s linear infinite}
.playground.rally .catcher.right{animation:hop 2.4s linear 1.2s infinite}
@keyframes hop{0%{transform:scale(1.12,.86)}5%{transform:translateY(-10px) scale(.94,1.08)}12%{transform:scale(1.1,.9)}18%,100%{transform:none}}
.star{position:absolute;left:30px;right:30px;bottom:26px;height:18px;container-type:inline-size;transition:opacity .3s}
.star-x{position:absolute;left:0}
.star-y{display:block;width:16px}
.playground.rally .star-x{animation:starx 1.2s linear infinite alternate}
.playground.rally .star-y{animation:stary 1.2s infinite}
.playground.rally .star-y svg{animation:spin 1.2s linear infinite}
@keyframes starx{to{translate:calc(100cqw - 16px) 0}}
@keyframes stary{0%{transform:none;animation-timing-function:cubic-bezier(.33,.67,.67,1)}50%{transform:translateY(-38px);animation-timing-function:cubic-bezier(.33,0,.67,.33)}100%{transform:none}}
@keyframes spin{to{rotate:360deg}}
.playground.scared .catcher{translate:0 14px;scale:.7;opacity:0;pointer-events:none;transition:translate .18s cubic-bezier(.23,1,.32,1),scale .18s cubic-bezier(.23,1,.32,1),opacity .18s}
.playground.scared .star{opacity:0}
/* The laptop crew crossing the bottom of the Spirited Away painting, behind the pages, clipped by the stage. width:auto
   overrides .critter's var(--s), which the crew would otherwise inherit as 0 from the stage and squash its soots to nothing. */
.crew{position:absolute;left:0;bottom:12px;width:auto;display:flex;align-items:flex-end;gap:1px;transform:translateX(var(--from))}
.crew.go{transform:translateX(var(--to));transition:transform var(--dur) linear}
.crew.gone{opacity:0;transition:transform var(--dur) linear,opacity .35s ease-in}
.crew .soot{animation:patter .28s ease-in-out infinite alternate}
.crew .soot:nth-child(2){animation-delay:-.14s}
@keyframes patter{to{transform:translateY(-4px)}}
.crew .laptop{position:absolute;left:2px;bottom:16px;width:72px;transform:rotate(-3deg);animation:patter .56s ease-in-out infinite alternate}
/* Codex's painted creatures: sprite sheets played from exposure sheets (films/critters.js writes one @keyframes per act,
   holding each drawing for its own number of frames). --cw is one cell's width on screen; --foot lifts the cell so the
   creature's feet sit on the line it stands on. */
.painted{width:var(--w);height:var(--h);background:var(--img) 0 var(--y,0)/var(--bw) var(--bh) no-repeat}
.painted.resting{animation:none;background-position-x:calc(var(--cw) * var(--f,0) * -1)}
.painted.away{animation-play-state:paused}
/* Each IT pet sits in a seat on its tag. */
.seat{line-height:0}
.seat .painted{display:block}
/* A soot sprite flung out from under the corner of the Workbench page that just landed: the trip across on the wrapper
   (linear), the arc, the landing squash, a shake and the hop back on the sprite (eased), like the star in the catch game. */
.flung{position:absolute;left:var(--x0);bottom:2px;z-index:3;width:30px;margin-left:-15px;visibility:hidden;pointer-events:none}
.flung.go{visibility:visible;animation:fling-x 2.6s linear both}
.flung.go .soot{transform-origin:50% 60%;animation:fling-y 2.6s both}
@keyframes fling-x{0%{translate:0 0}22%,78%{translate:var(--dx) 0}100%{translate:0 0}}
@keyframes fling-y{0%{transform:translateY(-4px) rotate(0deg) scale(.2);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
 11%{transform:translateY(-74px) rotate(calc(var(--sp) * .5)) scale(1);animation-timing-function:cubic-bezier(.6,0,.9,.5)}
 22%{transform:translateY(0) rotate(var(--sp)) scale(1.2,.75);animation-timing-function:ease-out}
 28%{transform:translateY(-14px) rotate(var(--sp)) scale(.95,1.05);animation-timing-function:ease-in}
 34%{transform:translateY(0) rotate(var(--sp)) scale(1.08,.9)}
 38%,50%{transform:translateY(0) rotate(var(--sp)) scale(1)}
 54%{transform:translateY(0) rotate(calc(var(--sp) + 12deg)) scale(1)}
 58%{transform:translateY(0) rotate(calc(var(--sp) - 12deg)) scale(1)}
 62%{transform:translateY(0) rotate(calc(var(--sp) + 7deg)) scale(1)}
 66%,78%{transform:translateY(0) rotate(var(--sp)) scale(1);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
 89%{transform:translateY(-48px) rotate(var(--sp)) scale(1);animation-timing-function:cubic-bezier(.6,0,.9,.5)}
 100%{transform:translateY(-4px) rotate(var(--sp)) scale(.2)}}
/* The soot sprite riding the header's job dots: --x is the dot it sits on, and it hops there one dot at a time. */
.career-rail .rider{position:absolute;left:0;bottom:calc(50% + 5px);width:13px;margin-left:-6.5px;translate:var(--x,0) 0;transition:translate calc(var(--n,1) * .17s) linear}
.career-rail .rider.hop svg{animation:rider-hop .17s var(--n,1)}
@keyframes rider-hop{0%{transform:none;animation-timing-function:cubic-bezier(.33,.67,.67,1)}50%{transform:translateY(-7px);animation-timing-function:cubic-bezier(.33,0,.67,.33)}100%{transform:none}}
.lane{position:absolute;left:0;right:0;bottom:0;height:120px;overflow:hidden;pointer-events:none}
.lane.on-top{bottom:100%}
.lane .painted{position:absolute;left:0;bottom:calc(-1 * var(--foot));transform:translateX(var(--x,0));transform-origin:50% calc(100% - var(--foot));transition:transform var(--t,0s) linear,scale .18s cubic-bezier(.3,1.6,.5,1)}
.lane .painted.squash{scale:1.06 .9;transition:transform var(--t,0s) linear,scale .07s ease-in}
.lane .painted::after{content:'';position:absolute;left:28%;right:28%;bottom:calc(var(--foot) - 1px);height:5px;border-radius:50%;background:rgba(42,34,27,.2);filter:blur(1px)}
.bring,.site-footer,.contact-section{position:relative}
/* The black cat strolls along the top of the night footer: a faint moonlit rim keeps him from vanishing into the dark. */
.site-footer .lane .painted{filter:drop-shadow(0 0 1.5px rgb(255 226 180/.6))}
/* The fire demon by the signature: a warm glow, and he brightens when a contact link is about to be used. */
.hearth{position:absolute;left:10px;bottom:6px;transform-origin:50% 90%;filter:drop-shadow(0 0 10px rgba(255,150,60,.35));transition:scale .22s cubic-bezier(.23,1,.32,1)}
[data-motion=full] .letter:has(.letter-links a:focus-visible) .hearth{scale:1.12}
@media (hover:hover) and (pointer:fine){[data-motion=full] .letter:has(.letter-links a:hover) .hearth{scale:1.12}}
/* The fox-squirrel behind the top edge of the Workbench book: it rises slowly and ducks fast. */
.fox-strip{position:absolute;left:0;right:0;bottom:100%;height:100px;overflow:hidden;pointer-events:none}
.fox-strip .painted{position:absolute;left:0;bottom:0;translate:var(--x,0) 0;transform:translateY(100%);transition:transform .16s cubic-bezier(.55,0,.85,.35),translate var(--t,0s) linear}
.fox-strip .painted.up{transform:translateY(20%);transition:transform .6s cubic-bezier(.25,1.35,.5,1),translate var(--t,0s) linear}
@media print{.critter,.crew,.playground,.job-steps{display:none!important}
 /* The book's pages print as a plain list: no size queries, clipping or page dressing, which paged printing mishandled
    (each page came out shifted off its left edge, its painted spot a blank shadowed box). */
 .workbench .mag-page{container-type:normal;overflow:visible;box-shadow:none}
 /* a closed book is slid half a page sideways on wide screens; that slide stayed on in print and pushed the list off the page */
 .mag-closed-front,.mag-closed-back{transform:none}
 .workbench .mag-book{filter:none}
 .wb-endpaper{background:none!important}.wb-postcard{transform:none;box-shadow:none}
 /* the career list's scene thumbnails load only as the list nears the screen, so on paper they were empty boxes */
 .career-index img{display:none}.career-index a{grid-template-columns:0 8.4em 1fr auto}.career-index span{margin-left:-14px}
 /* the closing letter sits under the phone dusk band's space on narrow pages; on paper it follows straight on */
 .contact-section{padding:8mm 0}
 .workbench :is(.spot,.flip),.workbench .mag-page::before,.wb-contents::after,.wb-endpaper::after{display:none!important}
 /* the printed address of each systems-map and credential link runs under its text, not down the number column */
 .bring :is(.systems-map,.cert-grid) a::after{grid-column:2/-1}}
/* Let the pointer reach a peeking sprite or a tag through the empty parts of each section; the pages stay clickable. */
.pages,.pages #jobs,.pages .leaf,.pages .ma{pointer-events:none}
.pages .sheet,.pages .tag,.pages .title-card,.pages .title-scroll,.peeker{pointer-events:auto}
/* Hand-ruled lines on the job pages, the career list and What I bring (tokens in styles.css); the result line's coloured
   bar becomes a dry-brush stroke. */
@media screen{
 .ledger,.career-index,.job-evidence,.workbench .mag-foot{border-top:0;background:var(--rule) 0 0/var(--rule-size)}
 .ledger li,.career-index a{border-bottom:0;background:var(--rule-dots) 0 100%/var(--rule-size)}
 .title-film{border-top:0;background:var(--rule-dots) 0 0/var(--rule-size)}
 .bring :is(.systems-map,.cert-grid) a{border-bottom:0;background:var(--rule) 0 100%/var(--rule-size)}
 .job-proof{border-left:0;padding-left:17px;background:url(assets/films/site/proof-stroke.webp) 0 2px/6px calc(100% - 4px) no-repeat}}
