/* ==========================================================================
   Project pages (/work/<slug>/) and the standalone pages (/work, /film,
   /motiongraphics, /decks).

   ONE content column - the width of the project card - holds everything on a
   page; nothing reaches past its edges. tools/build_pages.py re-flows each
   Squarespace section into row groups and columns (see the note at the top of its
   rendering code); this sheet gives them one consistent, tight rhythm.
   ========================================================================== */

:root{
  --pc1:262 50% 60%; --pc2:292 44% 70%;      /* overridden per project on <html> */
  --ink:#f4f3f1; --ink-2:#c6c4c0; --muted:#9d9a95; --line:#2b2930;
  --radius:12px;
  --shadow:0 18px 42px rgba(0,0,0,.45);
  /* fonts: --ff-display / --ff-ui / --ff-body are set once for the whole site in site.css */

  --content:1100px;                        /* the project card's width - the page's width */
  --side:max(20px,5vw);                    /* the least margin either side */
  --sec-gap:clamp(44px,5.2vw,72px);          /* between sections */
  --grp-gap:clamp(24px,2.6vw,36px);        /* between rows inside a section */
  --col-gap:clamp(24px,3.2vw,44px);        /* between side-by-side columns */
  --stack-gap:clamp(14px,1.6vw,20px);      /* between blocks stacked in a column */
}

.pp{display:block; color:var(--ink); font-family:var(--ff-body)}
.wrap{width:min(var(--content), 100% - 2 * var(--side)); margin-inline:auto}

/* ---- glass wash (project pages only) ------------------------------------ */
body.project::before{
  content:""; position:fixed; inset:-14%; z-index:0; pointer-events:none;
  background:
    radial-gradient(62% 55% at 18% 12%, hsl(var(--pc1)) 0%, hsl(var(--pc1) / 0) 70%),
    radial-gradient(58% 52% at 84% 26%, hsl(var(--pc2)) 0%, hsl(var(--pc2) / 0) 72%),
    radial-gradient(78% 62% at 48% 88%, hsl(var(--pc1)) 0%, hsl(var(--pc1) / 0) 74%);
  filter:blur(22px) saturate(1.35); opacity:.85;
}
/* the Design page's wash (AJ 09-10: "soft colors of the images all blurred together with
   glass overlay like front page"): its own pictures blurred into one field of colour
   (build_pages.recap_wash), under the same glass */
body.recap-page::before{
  content:""; position:fixed; inset:-8%; z-index:0; pointer-events:none;
  background:url(/assets/img/work/_index/recap-wash.jpg) center/cover no-repeat;
  filter:blur(24px) saturate(1.1); opacity:.8;
}
@media (max-width:767px){                  /* the tall one, made from the phone layout */
  body.recap-page::before{background-image:url(/assets/img/work/_index/recap-wash-m.jpg)}
}
body.project::after, body.recap-page::after{
  content:""; position:fixed; inset:0; z-index:1; pointer-events:none;
  background:rgba(10,10,12,.52);
  -webkit-backdrop-filter:blur(58px) saturate(1.35);
          backdrop-filter:blur(58px) saturate(1.35);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  body.project::after, body.recap-page::after{background:rgba(10,10,12,.72)}
}
body.recap-page::after{background:rgba(10,10,12,.7)}            /* AJ: "a darker glass" on Design */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  body.recap-page::after{background:rgba(10,10,12,.84)}
}
body.project > *, body.recap-page > :not(dialog){position:relative; z-index:2}
body.project > .site-header, body.recap-page > .site-header{position:sticky; z-index:60}   /* the glass header stays put over the wash */

/* ---- 404: a missing page says so (build_pages.build_404) ---- */
.nf{padding:clamp(72px,16vh,180px) 0 clamp(48px,10vh,120px)}
.nf h1{margin:.12em 0 .3em; font-family:var(--ff-display); font-weight:400; font-size:clamp(44px,8vw,96px);
  line-height:.95; text-transform:uppercase; color:var(--ink)}
.nf > p:not(.eyebrow){margin:0 0 22px; color:var(--ink-2)}

/* ---- page rhythm ------------------------------------------------------------ */
.pp > .sec, .pp > .strips-sec, .pp > .cs-sec, .pp > .cs-quote, .pp > .cs-cta{margin-top:var(--sec-gap)}
body.standalone .pp > .sec:first-child, .pp > .recap:first-child{margin-top:clamp(16px,2.4vw,32px)}
body.standalone .pp{padding-bottom:var(--sec-gap)}
.pp [id]{scroll-margin-top:92px}             /* clears the sticky header */
@media (prefers-reduced-motion:no-preference){ html{scroll-behavior:smooth} }

/* ==== case study (project pages) ================================================
   hero (summary + project card) / chapter strip / overview / highlights / chapters
   (centred title over a panel) / named parts as an accordion / pull quote / next
   project. tools/build_pages.py decides which piece each Squarespace section becomes.
   Type: display face for titles (always weight 400 - it has no bold, and a faked one
   smears), the UI face for labels, buttons and part names, the body face for copy. */
:root{--panel:hsl(0 0% 100% / .045); --panel-line:hsl(0 0% 100% / .1)}
.eyebrow{margin:0; font-family:var(--ff-ui); font-weight:600; font-size:11px; letter-spacing:.22em;
  text-transform:uppercase; color:var(--muted)}
.panel{background:var(--panel); border:1px solid var(--panel-line); border-radius:18px;
  padding:clamp(18px,3vw,40px); display:flex; flex-direction:column; gap:var(--grp-gap)}

/* hero: the summary left, the project card right - every project the same shape */
.cs-hero{display:grid; grid-template-columns:minmax(0,5fr) minmax(0,7fr); gap:var(--col-gap);
  align-items:center; padding-top:clamp(12px,2.4vw,36px)}
.cs-hero-copy{display:flex; flex-direction:column; align-items:flex-start; gap:18px; min-width:0}
.badge{display:inline-flex; align-items:center; gap:9px; margin:0; padding:6px 13px 6px 11px;
  border:1px solid var(--panel-line); border-radius:999px; background:var(--panel);
  font-family:var(--ff-ui); font-weight:600; font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-2); line-height:1.3}
.badge::before{content:""; flex:none; width:6px; height:6px; border-radius:50%; background:hsl(var(--pc1))}
.cs-title{margin:0; font-family:var(--ff-display); font-weight:400; font-size:clamp(36px,4vw,58px);
  line-height:1.02; letter-spacing:.005em; text-transform:uppercase; text-wrap:balance}
.cs-lead{color:var(--ink-2); font-size:clamp(15.5px,1.15vw,17px); max-width:48ch}
.cs-actions{display:flex; flex-wrap:wrap; gap:10px}
.btn{display:inline-flex; align-items:center; gap:8px; padding:11px 18px; border-radius:10px;
  border:1px solid transparent; font-family:var(--ff-ui); font-weight:600; font-size:14.5px;
  letter-spacing:.03em; line-height:1.2; text-decoration:none; transition:background-color .2s, border-color .2s}
.btn-primary{background:var(--ink); color:#0d0d10}
.btn-primary:hover{background:#fff}
.btn-ghost{background:var(--panel); border-color:var(--panel-line); color:var(--ink)}
.btn-ghost:hover{border-color:hsl(0 0% 100% / .3)}
.btn:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}
.cs-meta{margin:6px 0 0; display:flex; flex-wrap:wrap; gap:14px 32px; font-family:var(--ff-ui)}
.cs-meta dt{font-weight:600; font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--muted); margin-bottom:4px}
.cs-meta dd{margin:0; font-size:14.5px; letter-spacing:.02em; line-height:1.4}
.cs-hero-card{margin:0; aspect-ratio:3/2}
.cs-hero-card img{width:100%; height:100%; object-fit:cover; display:block}
@media (max-width:860px){ .cs-hero{grid-template-columns:1fr; gap:26px} .cs-hero-card{order:-1} }

/* the chapters, listed where the wireframe keeps its logo row */
.cs-strip{margin-top:clamp(32px,4vw,56px); padding:20px 0; border-block:1px solid var(--panel-line);
  display:flex; flex-direction:column; align-items:center; gap:12px; text-align:center}
.cs-strip p{margin:0; font-family:var(--ff-ui); font-weight:600; font-size:11px; letter-spacing:.22em;
  text-transform:uppercase; color:var(--muted)}
.cs-strip ul{list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; justify-content:center; gap:0 26px}
.cs-strip a{display:inline-block; padding:10px 2px; font-family:var(--ff-ui); font-weight:700; font-size:clamp(14px,1.15vw,16px); letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-2); text-decoration:none; transition:color .2s}
.cs-strip a:hover{color:var(--ink)}
.cs-strip a:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:4px; border-radius:3px}

/* sections: a centred title, then the content */
.cs-sec{display:flex; flex-direction:column; gap:var(--grp-gap)}
.cs-sec-head{display:flex; flex-direction:column; align-items:center; gap:10px; text-align:center}
.cs-sec-head h2, .cs-split-head h2{margin:0; font-family:var(--ff-display); font-weight:400;
  font-size:clamp(28px,3vw,42px); line-height:1.04; letter-spacing:.01em; text-transform:uppercase; text-wrap:balance}

/* overview and named parts: title (and opening words) left, content right */
.cs-split{display:grid; grid-template-columns:minmax(0,4fr) minmax(0,7fr); gap:var(--col-gap); align-items:start}
.cs-split-head{display:flex; flex-direction:column; gap:16px; min-width:0}
.cs-split-head .rt{color:var(--ink-2)}
.cs-split-head .blk-img{margin:4px 0 0}
.cs-prose{max-width:70ch}
@media (max-width:860px){ .cs-split{grid-template-columns:1fr; gap:22px} }

/* accordion: one named part per item, the first open */
.acc{display:flex; flex-direction:column; gap:10px; min-width:0}
.acc-item{background:var(--panel); border:1px solid var(--panel-line); border-radius:12px}
.acc-item summary{list-style:none; cursor:pointer; display:flex; align-items:center; justify-content:space-between;
  gap:16px; padding:15px 18px; border-radius:12px; font-family:var(--ff-ui); font-weight:700;
  font-size:clamp(15.5px,1.25vw,17.5px); line-height:1.3}
.acc-item summary::-webkit-details-marker{display:none}
.acc-item summary:hover{background:hsl(0 0% 100% / .03)}
.acc-item summary:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:2px}
.acc-icon{flex:none; position:relative; width:24px; height:24px; border-radius:50%; border:1px solid var(--panel-line)}
.acc-icon::before, .acc-icon::after{content:""; position:absolute; left:50%; top:50%; width:10px; height:1.5px;
  background:var(--ink); transform:translate(-50%,-50%)}
.acc-icon::after{transform:translate(-50%,-50%) rotate(90deg); transition:transform .2s ease}
.acc-item[open] .acc-icon::after{transform:translate(-50%,-50%)}
.acc-body{padding:0 18px 18px; color:var(--ink-2)}

/* pull quote */
.cs-quote-card{margin:0 auto; max-width:860px; padding:clamp(26px,4vw,52px) clamp(20px,4vw,60px);
  text-align:center; background:var(--panel); border:1px solid var(--panel-line); border-radius:18px}
.cs-quote-card::before{content:"\201C"; display:block; height:.5em; font-family:var(--ff-display);
  font-size:84px; line-height:1; color:hsl(var(--pc1))}
.cs-quote-card blockquote{margin:0}
.cs-quote-card .rt :is(h1,h2,h3,h4,p){margin:0; font-family:var(--ff-ui); font-weight:600;
  font-size:clamp(20px,2.2vw,29px); line-height:1.32; text-transform:none}

/* ---- sections: row groups stacked, columns side by side --------------------- */
.sec{display:flex; flex-direction:column; gap:var(--grp-gap)}
.grp-1{display:flex; flex-direction:column; gap:var(--stack-gap)}
.grp-1.is-text > .rt{max-width:74ch}              /* a readable measure for text on its own */
.grp-1.is-text > .rt:has(> .ta-center){margin-inline:auto; max-width:min(100%,780px)}  /* pull quotes, intros */
/* long copy (wireframe notes, UI notes) runs in two columns, not one narrow strip */
.grp-1.is-long > .rt{max-width:none; columns:2; column-gap:var(--col-gap)}
.grp-1.is-long .rt > :is(h1,h2){column-span:all}
.grp-1.is-long .rt :is(li,p){break-inside:avoid}
.grp-1.is-long .rt :is(h3,h4){break-after:avoid}
@media (max-width:900px){ .grp-1.is-long > .rt{columns:1} }
.grp-n{display:grid; grid-template-columns:var(--tracks); column-gap:var(--col-gap); align-items:start}
.col{display:flex; flex-direction:column; gap:var(--stack-gap); min-width:0}
/* a column much shorter than its neighbour stays in view while the neighbour scrolls
   past, instead of leaving a tall empty gap (project.js sets .stick, only when the
   column fits on screen) */
.col.stick{position:sticky; top:24px}
@media (max-width:767px){
  .grp-n{display:flex; flex-direction:column; align-items:stretch; gap:var(--stack-gap)}  /* not start: pictures need the full width */
  .grp-n > .col{display:contents}
  .grp-n .blk{order:var(--mo,0)}
}

/* ---- pictures ------------------------------------------------------------ */
.blk{margin:0; min-width:0}
.blk-img{margin:0; display:block}
.blk-img.card img{width:100%; height:100%; object-fit:cover; display:block}
/* whole pictures: the column's width, or narrower when that would make them taller than
   the screen (860px at most); --ratio comes from the page, so the space is held before
   the picture loads */
.blk-img.fit img{
  display:block; width:min(100%, calc(min(80vh,860px) * var(--ratio,1))); height:auto;
  border-radius:var(--radius); box-shadow:var(--shadow);
}
.blk-link{display:block; border-radius:var(--radius)}
.blk-link:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:4px}
.card{border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow)}

/* ---- galleries --------------------------------------------------------------- */
.gal{display:grid; gap:clamp(10px,1.4vw,18px); grid-template-columns:repeat(var(--cols,1),minmax(0,1fr))}
@media (max-width:767px){ .gal{grid-template-columns:repeat(var(--cols-m,1),minmax(0,1fr))} }
.gal figure{margin:0}
.gal img{width:100%; height:auto; display:block}
.gal.has-ar img{aspect-ratio:var(--ar); object-fit:cover}

/* ---- video ------------------------------------------------------------------ */
.blk-vid{margin:0}
.vid-frame{width:100%; aspect-ratio:16/9; background:#000}
.vid-frame video{width:100%; height:100%; display:block; object-fit:contain}
.vcap{margin-top:10px; color:var(--ink-2); font-size:.92em}
.vcap p{margin:0}

/* ---- text: one tight scale ------------------------------------------------------ */
.rt{
  font-family:var(--ff-body); color:var(--ink);
  font-size:clamp(15px, calc(14.4px + .14vw), 16.5px); line-height:1.58;
  overflow-wrap:break-word;                /* a long word never pushes past the column */
}
.rt :is(h1,h2){font-family:var(--ff-display); font-weight:400; color:var(--ink); line-height:1.04; text-transform:uppercase}
.rt :is(h3,h4){font-family:var(--ff-ui); font-weight:700; color:var(--ink); line-height:1.22}
.rt :is(p,h1,h2,h3,h4){white-space:pre-wrap}
.rt h1{font-size:clamp(30px,3.4vw,46px); letter-spacing:-.01em; margin:0 0 .45em}
.rt h2{font-size:clamp(26px,2.7vw,38px); letter-spacing:-.008em; margin:0 0 .45em}
.rt h3{font-size:clamp(20px,1.9vw,27px); margin:0 0 .45em}
.rt h4{font-size:clamp(16.5px,1.35vw,19px); line-height:1.25; margin:1.1em 0 .4em}
.rt p{margin:0 0 .8em}
.rt :is(ul,ol){margin:.3em 0 .9em; padding-left:1.25em}
.rt li{margin:.25em 0}
.rt li > p{margin:0}
.rt li :is(ul,ol){margin:.2em 0}
.rt > :first-child{margin-top:0}
.rt > :last-child{margin-bottom:0}
.rt a{color:inherit; text-decoration:underline; text-underline-offset:.18em; text-decoration-thickness:1px}
.rt a:hover{opacity:.7}
.rt .sqsrte-large{font-size:1.2em}
.rt .sqsrte-small{font-size:.85em}
.ta-center{text-align:center} .ta-right{text-align:right} .ta-justify{text-align:justify}

/* ---- next project ----------------------------------------------------------- */
.cs-cta{padding-bottom:clamp(48px,6vw,88px)}
.cta-card{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); overflow:hidden;
  background:var(--panel); border:1px solid var(--panel-line); border-radius:18px}
.cta-copy{display:flex; flex-direction:column; justify-content:center; align-items:flex-start; gap:14px;
  padding:clamp(24px,4vw,52px)}
.cta-copy h2{margin:0; font-family:var(--ff-display); font-weight:400; font-size:clamp(30px,3.4vw,48px);
  line-height:1.02; letter-spacing:.01em; text-transform:uppercase; text-wrap:balance}
.cta-sub{margin:0; font-family:var(--ff-ui); font-weight:600; font-size:12px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-2)}
.cta-copy .cs-actions{margin-top:6px}
.cta-img{position:relative; display:block; min-height:280px; overflow:hidden}
.cta-img img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; transition:transform .6s ease}
.cta-img:hover img{transform:scale(1.035)}
@media (max-width:760px){ .cta-card{grid-template-columns:1fr} .cta-img{order:-1; min-height:0; aspect-ratio:16/9} }
@media (prefers-reduced-motion:reduce){ .cta-img img, .acc-icon::after, .btn, .cs-strip a{transition:none} }

/* ---- /work: MORE DESIGN justified gallery (rows set by project.js) ------------- */
.strips{--rh:clamp(110px, 24vw, var(--row)); display:flex; flex-wrap:wrap; gap:var(--gap)}
.strips::after{content:""; flex-grow:1e9}                /* no-script fallback only */
.strips.is-justified::after{display:none}                /* exact rows need no spacer */
.strip-item{
  flex:var(--r) 1 calc(var(--r) * var(--rh));
  aspect-ratio:var(--r); height:auto; display:block; overflow:hidden;
}
.strip-item img{width:100%; height:100%; object-fit:cover; transition:opacity .25s}
.strip-item:hover img{opacity:.82}
.strip-item:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}

/* ---- /work: the Design recap, a floating 3D field ------------------------------
   a hairline lane per category, its name - a button - turned up at the top; entries at
   the positions build_pages.recap_layout worked out (percent of the frame, so the whole
   composition scales as one), each at its own depth (--z) and bobbing gently; the field
   leans toward the pointer and drifts with the scroll (project.js). Picking a lane
   brings its entries forward and sends the rest back. */
.recap{margin-top:var(--sec-gap)}
.recap-field{--rule:hsl(0 0% 100% / .1); position:relative; aspect-ratio:var(--ar,1100/1520);
  perspective:1500px; perspective-origin:50% 42%}
/* the lane lines stay put. The words - title, hint, lane names - ride their own 3D layer,
   40px forward, that follows the pointer more slowly than the entries do and floats on
   one long shared breath (project.js sets --tx/--ty/--trx/--try on the field) */
.recap-space{position:absolute; inset:0; transform-style:preserve-3d;
  border-right:1px solid var(--rule);
  background-image:linear-gradient(to right, var(--rule) 1px, transparent 1px);
  background-size:calc(100% / var(--n)) 100%}
.recap-title{position:absolute; left:50%; top:50%; margin:0;
  transform:translate(-50%,-50%) translate3d(var(--tx,0px), var(--ty,0px), 40px)
    rotateX(var(--trx,0deg)) rotateY(var(--try,0deg));
  animation:type-float 11s ease-in-out infinite alternate;
  font-family:var(--ff-display); font-weight:400; font-size:clamp(44px,8.6vw,98px); line-height:.9;
  letter-spacing:.005em; text-transform:uppercase; white-space:nowrap; pointer-events:none; color:var(--ink);
  transition:opacity .4s ease}
.recap-count{margin-left:.12em; font-family:var(--ff-ui); font-weight:600; font-size:.2em;
  letter-spacing:.08em; vertical-align:top; position:relative; top:.35em; color:var(--ink-2)}
.recap-hint{position:absolute; left:50%; top:calc(50% + clamp(34px,4.6vw,56px)); margin:0;
  transform:translateX(-50%) translate3d(var(--tx,0px), var(--ty,0px), 40px)
    rotateX(var(--trx,0deg)) rotateY(var(--try,0deg));
  animation:type-float 11s ease-in-out infinite alternate;
  font-family:var(--ff-ui); font-weight:600; font-size:11px;
  letter-spacing:.2em; text-transform:uppercase; white-space:nowrap; color:var(--muted); pointer-events:none;
  transition:opacity .4s ease}
.recap-field.is-filtered .recap-title, .recap-field.is-filtered .recap-hint{opacity:.3}
.rc-lane{display:contents}
/* the lane names: turned up at the top of each lane, their feet on one line (--band),
   riding the words' layer with the title */
.rc-label{position:absolute; bottom:calc(100% - var(--band)); left:calc(var(--i) * 100% / var(--n) + 5px);
  margin:0; padding:6px 4px; border:0; border-radius:3px; background:none; cursor:pointer;
  writing-mode:vertical-rl; transform:translate3d(var(--tx,0px), var(--ty,0px), 40px) rotate(180deg);
  animation:type-float 11s ease-in-out infinite alternate;
  font-family:var(--ff-ui); font-weight:600; font-size:13px; letter-spacing:.2em;
  text-transform:uppercase; white-space:nowrap; color:var(--muted); transition:color .25s ease}
.rc-label:hover, .rc-lane.is-on .rc-label{color:var(--ink)}
.rc-label[aria-pressed="true"]{color:var(--ink); text-decoration:underline; text-underline-offset:5px}
.rc-label:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:2px}
a.rc-label{text-decoration:none}
a.rc-label:hover{text-decoration:underline; text-underline-offset:5px}
@keyframes type-float{from{translate:0 -5px} to{translate:0 5px}}
@media (prefers-reduced-motion:reduce){ .recap-title, .recap-hint, .rc-label{animation:none} }
/* an entry: placed and set at its depth (--z). Its picture and caption float together
   (.rc-float): a 3D sway of its own, plus a wander project.js runs - each entry drifts
   on its own slow path and nudges its neighbours aside when they meet (--px/--py/--dy) */
.rc-item{position:absolute; left:var(--x); top:var(--y); width:var(--w); display:block;
  color:var(--ink); text-decoration:none; transform-style:preserve-3d;
  transform:translate3d(0, var(--rise,0px), calc(var(--z,0px) + var(--lift,0px)));
  transition:transform .8s cubic-bezier(.22,.61,.36,1), opacity .55s ease, filter .55s ease}
/* hover is a class project.js sets with a short grace either side - no edge flicker */
.rc-item.is-hover, .rc-item:focus-visible{--lift:70px}
.recap-field.has-hover:not(.is-filtered) .rc-item:not(.is-hover){opacity:.55}
/* a category picked (hover or click on its name): its entries rise and come to the front
   of everything, so nothing covers them; the rest sink back and fade */
.recap-field.is-filtered .rc-item{--lift:-90px; opacity:.16; filter:grayscale(.7)}
.recap-field.is-filtered .rc-lane.is-on .rc-item{--lift:160px; --rise:-22px; opacity:1; filter:none}
.recap-field.is-filtered .rc-lane.is-on .rc-item.is-hover{--lift:200px}
.rc-float{display:block; translate:var(--px,0px) calc(var(--py,0px) + var(--dy,0px));
  animation:rc-float var(--fd,7s) ease-in-out var(--fdl,0s) infinite alternate}
@keyframes rc-float{
  from{transform:translate3d(0,-6px,0) rotateX(5deg) rotateY(-6deg) rotateZ(-.5deg)}
  to{transform:translate3d(0,6px,0) rotateX(-4deg) rotateY(6deg) rotateZ(.5deg)}}
.rc-img{position:relative; display:block; overflow:hidden; background:#16161a; border-radius:2px;
  box-shadow:0 18px 38px rgba(0,0,0,.5)}
/* the picture is pinned inside its frame, so the frame's shape alone sets the height */
.rc-img img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .8s cubic-bezier(.22,.61,.36,1)}
.rc-item.is-hover .rc-img img, .rc-item:focus-visible .rc-img img{transform:scale(1.05)}
/* the caption may run wider than a narrow entry, up to the width the layout reserved */
.rc-cap{display:flex; justify-content:space-between; align-items:flex-start; gap:12px; min-width:100%;
  width:max-content; max-width:var(--cw,100%); margin-top:7px; font-family:var(--ff-ui); font-size:11px;
  letter-spacing:.04em; line-height:1.25; color:var(--muted); transition:color .45s ease}
.rc-n{font-variant-numeric:tabular-nums}
.rc-t{text-align:right}
.rc-item.is-hover .rc-cap, .rc-item:focus-visible .rc-cap{color:var(--ink)}
.rc-item:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:4px}
/* case studies: drawn larger and nearer, badged, and they open their project page */
.rc-badge{position:absolute; top:8px; left:8px; z-index:1; padding:4px 9px; border-radius:999px;
  background:rgb(10 10 12 / .74); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  font-family:var(--ff-ui); font-weight:700; font-size:9.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink); pointer-events:none}
.rc-item.is-project .rc-cap{color:var(--ink-2)}
.rc-item.is-project .rc-t{font-weight:700}
/* phones: the same field, run long (AJ: "design mobile page to reflect the web version").
   The lane names turn up across the top as on the desktop, their feet on one line
   (--mband), the title under them, then the entries where recap_phone_layout put them:
   x and width in % of the field (--mx, --mw), top as a fraction of the scatter below the
   title (--my), the scatter --mh of the field's width tall. A field this tall has no one
   vantage point, so each entry sways in a perspective of its own; a picked category
   grows a touch and comes to the front while the rest fall back. */
@media (max-width:767px){
  .recap-field{aspect-ratio:auto; perspective:none; max-width:520px; margin-inline:auto}
  .recap-space{--mband:172px; --mtop:calc(var(--mband) + 128px); position:relative; inset:auto;
    transform-style:flat; padding-top:var(--mtop)}
  .recap-space::before{content:""; display:block; padding-top:var(--mh)}
  .recap-title{top:calc(var(--mband) + 22px); transform:translateX(-50%); font-size:clamp(40px,13vw,64px)}
  .recap-hint{top:calc(var(--mband) + 32px + clamp(36px,11.7vw,58px)); width:84%; transform:translateX(-50%);
    white-space:normal; text-align:center; line-height:1.5}
  .rc-label{bottom:calc(100% - var(--mband)); left:calc(var(--i) * 100% / var(--n)); padding:8px 9px;
    font-size:12px; letter-spacing:.16em}
  .rc-item{left:var(--mx); top:calc(var(--mtop) + (100% - var(--mtop)) * var(--my)); width:var(--mw);
    transform-style:flat; perspective:800px; transform:translateY(var(--rise,0px)) scale(var(--ms,1))}
  .recap-field.is-filtered .rc-item{--ms:.95}
  .recap-field.is-filtered .rc-lane.is-on .rc-item{--ms:1.04; --rise:0px; z-index:2}
  .rc-cap{max-width:100%}
}
@media (prefers-reduced-motion:reduce){
  .rc-float{animation:none}
  .rc-img img, .rc-item, .rc-cap, .rc-label, .recap-title, .recap-hint{transition:none}
}

/* ---- /film: the reel -----------------------------------------------------------
   the names stacked big over a full-screen background that plays the film in the middle
   of the screen (reel.js); names right-aligned to one axis, their details beside it */
.reel{position:relative}
/* the film runs up under the glass header, edge to edge */
body.reel-page .site-header{position:fixed; left:0; right:0; top:0}
.reel-stage{position:sticky; top:0; height:100vh; height:100svh; overflow:hidden; background:#060608}
/* darker than the film itself so the names stand out; --crop zooms past bars baked
   into a file; a slow cross-fade between films */
.reel-vid{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0;
  transform:scale(var(--crop,1)); filter:brightness(.6) saturate(.92); transition:opacity 1.2s ease}
.reel-vid.is-on{opacity:1}
.reel-shade{position:absolute; inset:0; background:
  linear-gradient(90deg, rgba(8,8,10,.84) 0%, rgba(8,8,10,.52) 52%, rgba(8,8,10,.3) 100%),
  linear-gradient(0deg, rgba(8,8,10,.75) 0%, rgba(8,8,10,0) 32%)}
.reel-body{position:relative; z-index:2; margin-top:-100vh; margin-top:-100svh; padding:0 0 42vh}
.reel-ui{position:sticky; top:calc(100vh - 76px); top:calc(100svh - 76px); height:0; z-index:3}
.reel-ui-row{display:flex; align-items:center; justify-content:space-between; gap:16px; height:48px}
.reel-count{margin:0; min-width:64px; font-family:var(--ff-ui); font-weight:600; font-size:12px;
  letter-spacing:.16em; color:var(--ink-2); font-variant-numeric:tabular-nums}
.reel-now{color:var(--ink)}
/* each dot is a 28px tap target around an 8px mark */
.reel-dots{display:flex; gap:0}
.reel-dot{position:relative; width:28px; height:28px; padding:0; border:0; background:none; cursor:pointer}
.reel-dot::before{content:""; position:absolute; inset:10px; border-radius:50%; background:hsl(0 0% 100% / .32);
  transition:background-color .25s, transform .25s}
.reel-dot[aria-current="true"]::before{background:var(--ink); transform:scale(1.25)}
.reel-dot:focus-visible, .reel-sound:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}
.reel-sound{width:44px; height:44px; display:grid; place-items:center; border-radius:50%; cursor:pointer;
  border:1px solid hsl(0 0% 100% / .22); background:hsl(0 0% 0% / .35); color:var(--ink);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px)}
.reel-sound[aria-pressed="false"] .snd-on, .reel-sound[aria-pressed="true"] .snd-off{display:none}
.reel-head{display:flex; justify-content:space-between; align-items:flex-end; gap:24px;
  padding-top:30vh; margin-bottom:26px; font-family:var(--ff-ui); font-weight:600; font-size:11px;
  letter-spacing:.22em; text-transform:uppercase; color:var(--ink-2)}
.reel-head h1{margin:0; font:inherit; color:var(--ink)}
.reel-head h1 span{color:var(--ink-2)}
.reel-head p{margin:0; text-align:right}
.reel-names{list-style:none; margin:0; padding:0}
/* only the words answer the pointer - the empty space beside a name does nothing */
.reel-item a{display:grid; grid-template-columns:minmax(0,1.9fr) minmax(0,1fr); align-items:center;
  column-gap:20px; padding:1px 0; text-decoration:none; color:hsl(0 0% 100% / .26); transition:color .6s ease;
  pointer-events:none}
.reel-name, .reel-meta{pointer-events:auto}
.reel-item.is-active a, .reel-item a:hover, .reel-item a:focus-visible{color:var(--ink)}
.reel-item a:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:4px}
.reel-name{justify-self:end; text-align:right; font-family:var(--ff-display); font-weight:400;
  font-size:clamp(34px,7vw,96px); line-height:.92; letter-spacing:.005em; text-transform:uppercase}
.reel-meta{justify-self:start; font-family:var(--ff-ui); font-weight:600; font-size:11px; letter-spacing:.14em;
  line-height:1.5; text-transform:uppercase}
.reel-role{opacity:.8}
@media (max-width:767px){
  .reel-item a{grid-template-columns:1fr; row-gap:6px; padding:14px 0}   /* AJ: "a bit more spaced" */
  .reel-name{justify-self:start; text-align:left; font-size:clamp(32px,11vw,56px)}
  .reel-head{padding-top:24vh}
}
@media (prefers-reduced-motion:reduce){ .reel-vid, .reel-item a, .reel-dot{transition:none} }

/* ---- a film's own page ------------------------------------------------------------ */
.fp-hero{display:flex; flex-direction:column; gap:22px; padding-top:clamp(12px,2.4vw,36px)}
.fp-head{display:flex; flex-direction:column; align-items:flex-start; gap:12px}
.fp-detail{margin:0; font-family:var(--ff-ui); font-weight:600; font-size:13px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-2)}
.fp-player{margin:0}
.fp-bar{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:18px}
.fp-bar .cs-meta{margin:0}

/* ---- /decks: the shelf and the book -----------------------------------------------
   spines side by side, each titled at the top; the one pointed at opens wide (decks.js).
   Chosen, a deck opens as a book whose pages turn about their left edge */
.decks-page{display:block; padding-bottom:var(--sec-gap)}
.decks-head{padding-top:clamp(20px,3vw,40px)}
.shelf{display:flex; gap:8px; height:clamp(360px,40vw,470px)}
.spine{position:relative; flex:1 1 0; min-width:0; overflow:hidden; padding:0; border:0; border-radius:10px;
  background:#111114; color:var(--ink); cursor:pointer; text-align:left;
  transition:flex-grow .6s cubic-bezier(.2,.7,.2,1)}
.spine.is-open{flex-grow:6}
.spine-cover{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:brightness(.42) saturate(.8); transition:filter .6s ease}
.spine.is-open .spine-cover{filter:none}
.spine::after{content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(8,8,10,.75) 0%, rgba(8,8,10,0) 34%, rgba(8,8,10,0) 58%, rgba(8,8,10,.82) 100%)}
.spine-top{position:absolute; left:12px; right:10px; top:12px; z-index:1; display:flex; flex-direction:column;
  gap:3px; font-family:var(--ff-ui)}
.spine-n{font-size:10.5px; font-weight:600; letter-spacing:.18em; color:var(--muted)}
.spine-name{font-size:12.5px; font-weight:700; line-height:1.25}
.spine-line{font-size:11px; line-height:1.3; color:var(--ink-2); overflow:hidden;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical}
.spine-foot{position:absolute; left:20px; right:20px; bottom:18px; z-index:1; display:flex; align-items:flex-end;
  justify-content:space-between; gap:16px; opacity:0; transform:translateY(8px);
  transition:opacity .4s ease .15s, transform .4s ease .15s}
.spine.is-open .spine-foot{opacity:1; transform:none}
.spine-title{font-family:var(--ff-display); font-weight:400; font-size:clamp(28px,3.2vw,46px); line-height:.95;
  text-transform:uppercase}
.spine-go{flex:none; padding:9px 14px; border-radius:999px; background:rgb(10 10 12 / .6);
  border:1px solid hsl(0 0% 100% / .2); font-family:var(--ff-ui); font-weight:600; font-size:12px;
  letter-spacing:.14em; text-transform:uppercase; white-space:nowrap}
.spine:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}
.shelf-hint{margin-top:14px; font-family:var(--ff-ui); font-weight:600; font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--muted)}
@media (max-width:767px){
  .shelf{flex-direction:column; height:auto}
  .spine{flex:none; height:72px; transition:height .5s cubic-bezier(.2,.7,.2,1)}
  .spine.is-open{height:min(60vw,260px)}
  .spine-title{font-size:clamp(24px,8vw,36px)}
}

/* the book: pages turn about their left edge; a turned page lifts away and is gone */
.book{width:100vw; height:100vh; max-width:none; max-height:none; margin:0; padding:0; border:0;
  background:#07070a; color:var(--ink); display:none; flex-direction:column}  /* solid: nothing shows through */
.book[open]{display:flex}
.book::backdrop{background:transparent}
.book-bar{display:flex; align-items:center; gap:16px; padding:16px clamp(16px,3vw,32px)}
.book-title{margin:0; flex:1; min-width:0; font-family:var(--ff-display); font-weight:400;
  font-size:clamp(22px,2.4vw,32px); text-transform:uppercase; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.book-count{margin:0; font-family:var(--ff-ui); font-weight:600; font-size:12px; letter-spacing:.16em;
  color:var(--ink-2); font-variant-numeric:tabular-nums}
.book-close{flex:none; width:44px; height:44px; border-radius:50%; border:0; background:rgba(255,255,255,.08);
  color:var(--ink); font-size:22px; cursor:pointer}
.book-stage{position:relative; flex:1; min-height:0; display:grid; place-items:center; perspective:2200px;
  padding:0 clamp(60px,7vw,100px) 8px}
.book-pages{position:relative; width:min(1100px, 100%, (100vh - 200px) * 16 / 9); aspect-ratio:16/9;
  transform-style:preserve-3d; cursor:pointer}
.leaf{position:absolute; inset:0; transform-origin:left center; transform-style:preserve-3d;
  backface-visibility:hidden; border-radius:4px; background:#0d0d10; box-shadow:0 30px 60px rgba(0,0,0,.55);
  transition:transform .9s cubic-bezier(.3,.6,.2,1)}
.leaf img{position:absolute; inset:0; width:100%; height:100%; object-fit:contain; border-radius:4px;
  backface-visibility:hidden}
.leaf.peek{transform:rotateY(-14deg)}
.leaf.is-turned{transform:rotateY(-178deg)}
.book-prev, .book-next{position:absolute; top:50%; transform:translateY(-50%); width:48px; height:48px;
  border-radius:50%; border:0; background:rgba(255,255,255,.08); color:var(--ink); font-size:20px; cursor:pointer}
.book-prev{left:clamp(8px,2vw,24px)}
.book-next{right:clamp(8px,2vw,24px)}
.book-prev:disabled, .book-next:disabled{opacity:.25; cursor:default}
.book-note{margin:0 auto 18px; max-width:60ch; min-height:1.3em; text-align:center; font-family:var(--ff-ui);
  font-size:13px; color:var(--ink-2)}
.book :focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}
@media (max-width:767px){ .bd-long{display:none} .book-drive{padding:9px 12px} .book-stage{padding:0 12px 8px}
  .book-prev, .book-next{top:auto; bottom:-4px} }
@media (prefers-reduced-motion:reduce){ .spine, .spine-cover, .spine-foot, .leaf{transition:none} }

/* private decks: the spine says so; opening one asks for the password */
.spine-go{display:inline-flex; align-items:center; gap:6px}
.book-drive[hidden]{display:none}
.book.is-locked .book-stage, .book.is-locked .book-count, .book.is-locked .book-drive,
.book.is-locked .book-note{display:none}
.book-lock{margin:auto; width:min(380px, 100% - 40px); display:flex; flex-direction:column; gap:12px;
  font-family:var(--ff-ui)}
.book-lock[hidden]{display:none}
.book-lock-title{margin:0 0 6px; font-family:var(--ff-display); font-weight:400; font-size:clamp(26px,3vw,36px);
  line-height:1; text-transform:uppercase}
.book-lock label{font-weight:600; font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--muted)}
.book-lock-row{display:flex; gap:8px}
.book-lock input{flex:1; min-width:0; height:46px; padding:0 14px; border-radius:10px; border:1px solid var(--panel-line);
  background:rgba(255,255,255,.06); color:var(--ink); font:inherit; font-size:16px}  /* 16px: no zoom on iOS */
.book-lock input:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:2px}
.book-lock-err{margin:0; min-height:1.3em; font-size:13px; color:hsl(8 80% 72%)}

/* phones: no label under 11px */
@media (max-width:767px){
  .rc-badge{top:6px; left:6px; padding:3px 7px; letter-spacing:.12em}   /* fits the smaller phone entries */
  .spine-n{font-size:11px}
}

/* a heading for screen readers and search, not shown */
.sr-only{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0}

/* ---- lightbox ------------------------------------------------------------------ */
.lightbox{
  width:100vw; height:100vh; max-width:none; max-height:none; margin:0; padding:0; border:0;
  background:rgba(6,6,8,.94); color:var(--ink);
  display:none; align-items:center; justify-content:center;
}
.lightbox[open]{display:flex}
.lightbox::backdrop{background:transparent}
.lb-img{max-width:min(92vw,1800px); max-height:86vh; object-fit:contain; border-radius:6px}
.lightbox button{
  position:absolute; background:rgba(255,255,255,.08); color:var(--ink); border:0;
  width:48px; height:48px; border-radius:50%; font-size:22px; cursor:pointer;
}
.lightbox button:hover{background:rgba(255,255,255,.16)}
.lightbox button:focus-visible{outline:2px solid hsl(38 96% 55%); outline-offset:3px}
.lb-close{top:18px; right:18px}
.lb-prev{left:18px; top:50%; transform:translateY(-50%)}
.lb-next{right:18px; top:50%; transform:translateY(-50%)}
.lb-count{position:absolute; bottom:18px; left:0; right:0; text-align:center; margin:0;
  font-size:12px; letter-spacing:.2em; color:var(--muted); font-variant-numeric:tabular-nums}

@media (prefers-reduced-motion:reduce){
  .strip-item img{transition:none}
}
