/* ======================================================================
   /work and /work/<entry>: the fast path.

   Minimal, in the Google manner: white page, grey for anything secondary,
   one blue for the things you can press, no boxes around content. Two
   faces: Instrument Serif for headlines and numbers, Instrument Sans for
   reading. The room survives in exactly one place, the link back to it,
   in its own pixel face. One file for every /portfolio page.
   ====================================================================== */
:root{
  --bg:#fff; --surface:#f1f3f4; --surface-2:#f8f9fa;
  --ink:#202124; --body:#3c4043; --quiet:#5f6368; --rule:#e8eaed;
  --blue:#1a73e8; --blue-ink:#fff; --hover:rgba(32,33,36,.04);
  --shadow:0 1px 2px rgba(60,64,67,.3), 0 2px 6px 2px rgba(60,64,67,.15);
  --radius:20px;
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#1f1f1f; --surface:#2a2a2a; --surface-2:#252525;
    --ink:#e3e3e3; --body:#c4c7c5; --quiet:#9aa0a6; --rule:#3c4043;
    --blue:#a8c7fa; --blue-ink:#062e6f; --hover:rgba(255,255,255,.05);
    --shadow:0 1px 3px rgba(0,0,0,.5), 0 4px 8px 3px rgba(0,0,0,.25);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#1f1f1f; --surface:#2a2a2a; --surface-2:#252525;
  --ink:#e3e3e3; --body:#c4c7c5; --quiet:#9aa0a6; --rule:#3c4043;
  --blue:#a8c7fa; --blue-ink:#062e6f; --hover:rgba(255,255,255,.05);
  --shadow:0 1px 3px rgba(0,0,0,.5), 0 4px 8px 3px rgba(0,0,0,.25);
  color-scheme:dark;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:16px; line-height:1.6; -webkit-font-smoothing:antialiased;
}
a{color:inherit; text-decoration:none}
img,video{max-width:100%; display:block}
.q{color:var(--quiet)}
:focus-visible{outline:2px solid var(--blue); outline-offset:3px; border-radius:6px}
.vh{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}

/* The display face: headlines, numbers, titles. It is drawn small for its
   size, so everything set in it runs larger than a sans would. */
h2, .ehead h1, .ctitle, .nums b, .write h3, .pn a{
  font-family:"Instrument Serif",Georgia,"Times New Roman",serif; font-weight:400; letter-spacing:-.01em;
}

/* ---------- bar ---------- */
.bar{
  position:sticky; top:0; z-index:5;
  display:flex; align-items:center; gap:16px;
  height:64px; padding:0 max(16px, calc((100% - 1080px) / 2));
  background:color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter:saturate(1.4) blur(12px); backdrop-filter:saturate(1.4) blur(12px);
}
.bar .home{font-weight:600; font-size:17px; letter-spacing:-.01em; margin-right:auto; display:inline-flex; align-items:center; gap:10px}
.bar .home .mark{width:26px; height:26px; border-radius:6px; flex:none}
.bar .links{display:flex; gap:4px}
.bar .links{align-items:center}
.bar .links a{font-size:14px; color:var(--quiet); padding:8px 12px; border-radius:999px}
.bar .links a:hover{color:var(--ink); background:var(--hover)}

/* ---------- page ---------- */
.page{max-width:1080px; margin:0 auto; padding:0 16px 96px}
section{margin-top:88px}
h2{font-size:40px; line-height:1.1; margin:0 0 28px}

/* ---------- hero ---------- */
.actions{display:flex; gap:12px; justify-content:center; flex-wrap:wrap; margin:36px 0 0}
.hero .meta{font-size:14px; color:var(--quiet); margin:24px 0 0}
.hero .meta a, .more a, .foot a, .write a, .brief a, .lede a{color:var(--blue)}
.hero .meta a:hover, .more a:hover, .foot a:hover, .write a:hover{text-decoration:underline}

.btn{
  display:inline-flex; align-items:center; height:44px; padding:0 22px;
  border-radius:999px; font-size:15px; font-weight:500;
  color:var(--blue); border:1px solid var(--rule); background:transparent;
  font-family:inherit; cursor:pointer; transition:background .15s, box-shadow .15s;
}
.btn:hover{background:color-mix(in srgb, var(--blue) 8%, transparent)}
.btn.primary{background:var(--blue); color:var(--blue-ink); border-color:transparent}
.btn.primary:hover{box-shadow:var(--shadow); background:var(--blue)}

/* ---------- numbers ---------- */
.nums{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:48px 32px;
}
.nums li > a, .nums li{display:block}
.nums li > a{margin:-12px; padding:12px; border-radius:16px}
.nums li > a:hover{background:var(--hover)}
.nums b{display:block; font-size:clamp(44px, 5.4vw, 60px); line-height:1}
.nums .nl{display:block; font-size:15px; color:var(--body); margin-top:8px}
.nums .ns{display:block; font-size:13px; color:var(--quiet); margin-top:2px}

/* ---------- work ---------- */
.cards{list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:56px 32px}
.card{display:block}
.cover{
  display:flex; align-items:center; justify-content:center; gap:16px;
  aspect-ratio:4 / 3; overflow:hidden; border-radius:var(--radius);
  background:var(--surface);
  outline:1px solid var(--rule); outline-offset:-1px;   /* white screenshots keep an edge */
}
.cover > img{width:100%; height:100%; object-fit:cover; object-position:top center; transition:transform .5s cubic-bezier(.2,0,0,1)}
.cover > img[src$=".png"]{object-fit:contain; padding:28px}
.cover > img.fromvideo{object-position:center}
.card:hover .cover > img{transform:scale(1.025)}
.cover.phones{align-items:flex-start; padding-top:36px; gap:20px}
.cover .hand{
  height:112%; width:auto; flex:0 0 auto; overflow:hidden; border-radius:22px;
  box-shadow:var(--shadow); transition:transform .5s cubic-bezier(.2,0,0,1);
}
.cover .hand img{width:100%; height:100%; object-fit:cover}
.cover .hand + .hand{margin-top:36px}
.card:hover .cover .hand{transform:translateY(-6px)}
@media (prefers-reduced-motion: reduce){ .card:hover .cover > img, .card:hover .cover .hand{transform:none} }

.ctext{display:block; padding:18px 4px 0}
.ctitle{display:block; font-size:28px; line-height:1.15}
.card:hover .ctitle{color:var(--blue)}
.cline{display:block; font-size:15px; color:var(--body); margin-top:4px;
       display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.cmeta{display:block; font-size:13px; color:var(--quiet); margin-top:8px}

/* ---------- experience ---------- */
.roles{list-style:none; margin:0; padding:0; border-top:1px solid var(--rule)}
.roles li{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.4fr) auto; gap:4px 24px; padding:18px 0; border-bottom:1px solid var(--rule); align-items:baseline}
.roles .co{font-weight:500}
.roles .rr{color:var(--body)}
.roles .when{color:var(--quiet); font-size:14px; font-variant-numeric:tabular-nums}
.more{margin:20px 0 0; font-size:15px}
.foot{margin-top:96px; text-align:center; font-size:14px; color:var(--quiet)}

/* ---------- a case study ---------- */
.entry{max-width:1080px}
.crumb{margin:24px 0 0; font-size:14px}
.crumb a{color:var(--quiet)}
.crumb a:hover{color:var(--ink)}
.ehead{max-width:720px; margin:56px auto 0; text-align:center}
.ehead h1{font-size:clamp(52px, 8vw, 88px); letter-spacing:-.02em; line-height:1; margin:0}
.ehead h1 > span{display:inline-block}
.ehead .note{display:block; font-family:"Instrument Sans",sans-serif; font-size:16px; letter-spacing:0; margin-top:8px}
.ehead .lede{font-size:clamp(18px, 2.2vw, 21px); color:var(--quiet); line-height:1.5; margin:18px 0 0}
.ehead .meta{font-size:14px; color:var(--quiet); margin:18px 0 0}
.ehead .links{display:flex; flex-wrap:wrap; gap:12px; justify-content:center; margin:28px 0 0}

.col{max-width:720px; margin:0 auto}
.brief{margin:64px 0 0; display:grid; gap:28px}
.brief div{display:grid; grid-template-columns:120px 1fr; gap:24px}
.brief dt{font-size:14px; color:var(--quiet); padding-top:2px}
.brief dd{margin:0; font-size:17px; line-height:1.6; color:var(--body)}
.brief .res dd{color:var(--ink); font-weight:500}
.out{margin:64px 0 0; font-size:17px}
.kv{
  margin:40px 0 0; padding:24px 0 0; border-top:1px solid var(--rule);
  display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:20px 24px;
}
.kv dt{font-size:13px; color:var(--quiet)}
.kv dd{margin:2px 0 0; font-size:14.5px; color:var(--body)}

.entry > section{margin-top:96px}
.entry > section > h2, .entry > section > .q{max-width:720px; margin-left:auto; margin-right:auto}
.entry > section > .q{margin-top:-16px; margin-bottom:28px}
.write{max-width:720px; margin-left:auto; margin-right:auto}
.write h3{font-size:32px; line-height:1.15; margin:56px 0 12px; scroll-margin-top:80px}
.write h3:first-child{margin-top:0}
.write p, .write li{font-size:17px; line-height:1.7; color:var(--body)}
.write p{margin:0 0 16px}
.write ul{padding-left:20px; margin:0 0 16px}
.write li{margin-bottom:6px}
.write .inline{margin:32px 0 40px}
.entry > section > .galw{margin-bottom:32px}
.galw p{scroll-margin-top:80px}
.galw p:last-child{margin-bottom:0}
.entry > section > .galw.more{margin:40px auto 0}
.galw h3{font-size:26px; margin:40px 0 10px}
.galw h3:first-child{margin-top:0}

/* ---------- the stage: the lead pictures on a soft grey field ---------- */
.stage{margin:56px 0 0; padding:56px 40px 40px; background:var(--surface); border-radius:28px}
.stagecap{font-size:14px; color:var(--quiet); text-align:center; margin:-16px 0 32px}
.stage .row.phone{--pmax:270px}

/* ---------- media ----------
   build-work.mjs measures every picture and sorts it by shape: phones side
   by side at roughly phone size, long pages in a window that scrolls, wide
   screens at the width of the column. */
.gal, .inline{display:flex; flex-direction:column; gap:28px}
.row{display:flex; gap:24px; align-items:flex-start}
.fig{margin:0; min-width:0}
.m{position:relative}
.m img, .m video{width:100%; height:auto; border-radius:14px}
.m video{background:#000}
.fig figcaption{font-size:13px; color:var(--quiet); margin-top:10px; text-align:center}
.hint{margin-left:6px; opacity:.8}
img[data-zoom]{cursor:zoom-in}

.row.wide .fig, .row.pair .fig{flex:1 1 0}
.row.wide .m img, .row.wide .m video, .row.pair .m img, .row.pair .m video{box-shadow:var(--shadow)}
.row.pair{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px}
.stage img[src$=".png"], .stage .row.wide .m img[src$=".png"]{box-shadow:none}
/* A screen in a plain browser window. The bar stays light in dark mode,
   because the screens it holds are light. */
.m.web{border-radius:14px; overflow:hidden; background:#fff; box-shadow:var(--shadow)}
.m.web .chrome{display:grid; grid-template-columns:1fr minmax(0,34%) 1fr; align-items:center; height:28px; padding:0 12px;
               background:#ececef; border-bottom:1px solid #dcdce0}
.m.web .chrome span{display:flex; gap:6px}
.m.web .chrome i{width:9px; height:9px; border-radius:50%; background:#c9c9cf}
.m.web .chrome b{height:14px; border-radius:7px; background:#fff}
.row .m.web img, .row .m.web video{display:block; border-radius:0; box-shadow:none}
@media (max-width:560px){ .m.web .chrome{height:20px; padding:0 8px} .m.web .chrome i{width:6px; height:6px} .m.web .chrome b{height:10px} }
/* A flow: one window, its screens side by side in a strip that snaps */
.fl-track{display:flex; overflow-x:auto; scroll-snap-type:x mandatory; overscroll-behavior-x:contain; scrollbar-width:none; outline-offset:-3px}
.fl-track::-webkit-scrollbar{display:none}
.fl-slide{flex:0 0 100%; scroll-snap-align:start}
.row .fl-slide img{display:block; width:100%; height:auto; border-radius:0; box-shadow:none; cursor:pointer}
.fl-nav{position:absolute; top:calc(50% + 14px); transform:translateY(-50%); width:44px; height:44px; border:0; border-radius:50%;
        background:rgba(32,33,36,.72); color:#fff; font-size:26px; line-height:1; cursor:pointer; transition:opacity .2s}
.fl-nav.prev{left:12px} .fl-nav.next{right:12px}
.fl-nav:disabled{opacity:0; pointer-events:none}
.fl-steps{list-style:none; display:flex; flex-wrap:wrap; justify-content:center; gap:8px; margin:16px 0 0; padding:0}
.fl-steps button{display:flex; align-items:center; gap:8px; font:inherit; font-size:13px; padding:6px 12px 6px 6px; border-radius:999px;
                 border:1px solid var(--rule); background:transparent; color:var(--quiet); cursor:pointer}
.fl-steps button span{display:grid; place-items:center; width:20px; height:20px; border-radius:50%; background:var(--surface); color:var(--ink); font-size:11px; font-weight:600}
.fl-steps button:hover{color:var(--ink)}
.fl-steps button[aria-current]{color:var(--ink); border-color:var(--ink)}
.fl-steps button[aria-current] span{background:var(--ink); color:var(--bg)}
@media (max-width:560px){
  .fl-steps{flex-wrap:nowrap; overflow-x:auto; justify-content:flex-start; scrollbar-width:none; padding-bottom:4px}
  .fl-steps button{white-space:nowrap}
  .fl-nav{width:34px; height:34px; font-size:20px; top:calc(50% + 10px)}
}

.row.phone{overflow-x:auto; scroll-snap-type:x mandatory; padding:8px 8px 16px; margin:0 -8px;
           scrollbar-width:thin; -webkit-overflow-scrolling:touch}
.row.phone > :first-child{margin-left:auto}
.row.phone > :last-child{margin-right:auto}
.row.phone .fig{flex:0 0 max(176px, min(var(--pmax,250px), calc((100% - (var(--n) - 1) * 24px) / var(--n))));
                scroll-snap-align:center}
.hand{display:block; overflow:hidden; border-radius:28px; background:#000; box-shadow:var(--shadow)}
.hand img, .hand video{width:100%; height:100%; object-fit:cover; border-radius:0; display:block}

.row.long{flex-wrap:wrap; justify-content:center}
.row.long .fig{flex:1 1 300px; max-width:100%}
.row.long .fig:has(.narrow){flex:0 1 320px}
.win{max-height:640px; overflow:auto; overscroll-behavior:contain; border-radius:14px;
     background:var(--surface-2); box-shadow:var(--shadow); scrollbar-width:thin}
.win img{border-radius:0}

.row.portrait{flex-wrap:wrap; justify-content:center}
.row.portrait .fig{flex:0 1 auto}
.row.portrait .m img, .row.portrait .m video{max-height:540px; width:auto; max-width:100%; box-shadow:var(--shadow)}

.m.v{cursor:pointer}
.m.v::after{
  content:""; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:56px; height:56px; border-radius:50%; pointer-events:none;
  background:rgba(255,255,255,.92) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5v14l11-7z' fill='%23202124'/%3E%3C/svg%3E") center / 26px no-repeat;
  box-shadow:var(--shadow); transition:opacity .2s;
}
.m.v.playing::after{opacity:0}

/* ---------- previous / next ---------- */
.pn{max-width:720px; margin:112px auto 0; display:grid; grid-template-columns:1fr 1fr; gap:16px; padding-top:28px; border-top:1px solid var(--rule)}
.pn a{display:flex; flex-direction:column; gap:2px; padding:12px; margin:-12px; border-radius:14px; font-size:26px; line-height:1.15}
.pn a .q{font-family:"Instrument Sans",sans-serif; font-size:13px}
.pn a:hover{background:var(--hover); color:var(--blue)}
.pn .nx{text-align:right; align-items:flex-end}

/* ---------- full size ---------- */
.lb{border:0; padding:0; margin:auto; background:transparent; max-width:96vw; max-height:94vh; overflow:visible}
.lb::backdrop{background:rgba(0,0,0,.86)}
.lb .lbin{max-width:96vw; max-height:88vh; overflow:auto; border-radius:12px}
.lb img{display:block; max-width:96vw; max-height:88vh; width:auto; height:auto; margin:0 auto}
.lb.tallimg .lbin{width:min(760px,96vw)}
.lb.tallimg img{max-height:none; width:100%}
.lb .btn{position:absolute; top:-56px; right:0; background:#fff; color:#202124; border:0}
@media (max-width: 720px){ .lb .btn{top:auto; bottom:-58px} }

/* ---------- small screens ---------- */
@media (max-width: 760px){
  section{margin-top:64px}
  h2{font-size:34px; margin-bottom:20px}
  .hero{padding-top:56px}
  .nums{grid-template-columns:repeat(2, minmax(0,1fr)); gap:32px 20px}
  .cards{grid-template-columns:1fr; gap:44px}
  .roles li{grid-template-columns:1fr auto}
  .roles .rr{grid-column:1 / -1; grid-row:2; font-size:15px}
  .ehead{margin-top:36px}
  .brief{margin-top:44px}
  .brief div{grid-template-columns:1fr; gap:4px}
  .stage{margin:40px -16px 0; padding:32px 16px 24px; border-radius:0}
  .row.pair{grid-template-columns:1fr}
  .row.phone .fig{flex-basis:min(62vw, 250px)}
  .win{max-height:540px}
  .entry > section{margin-top:72px}
}
@media (max-width: 520px){
  .bar{gap:8px}
  .bar .opt{display:none}
  .roomlink:not(.big) span{display:none}
  .bar .links a{padding:8px 10px}
  .cover.phones{padding-top:24px; gap:14px}
}

/* the lead case: picture and words side by side across the full width */
.cards .lead{grid-column:1 / -1}
.lead .card{display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); gap:40px; align-items:center}
.lead .cover{aspect-ratio:10 / 7}
.lead .ctext{padding:0}
.lead .ctitle{font-size:44px; line-height:1.05}
.lead .cline{font-size:17px; -webkit-line-clamp:4; margin-top:10px}
@media (max-width: 760px){
  .lead .card{display:block}
  .lead .cover{aspect-ratio:4 / 3}
  .lead .ctext{padding:18px 4px 0}
  .lead .ctitle{font-size:28px}
  .lead .cline{font-size:15px}
}


/* ---------- the ask box ----------
   A search field, because that is the gesture everyone already knows. */
.askwrap{max-width:640px; margin:56px auto 0; text-align:left}
.ask{
  display:flex; align-items:center; gap:10px; height:56px; padding:0 8px 0 18px;
  border:1px solid var(--rule); border-radius:999px; background:var(--bg);
  transition:box-shadow .2s, border-color .2s;
}
.ask:hover, .ask:focus-within{box-shadow:var(--shadow); border-color:transparent}
.ask-ic{color:var(--blue); flex:0 0 auto}
.ask input{
  flex:1; min-width:0; height:100%; border:0; outline:0; background:transparent;
  font:inherit; font-size:16px; color:var(--ink);
}
.ask input::placeholder{color:var(--quiet)}
.ask input::-webkit-search-cancel-button{display:none}
.ask button{
  width:40px; height:40px; border-radius:50%; border:0; display:grid; place-items:center; cursor:pointer;
  background:transparent; color:var(--quiet);
}
.ask button:hover{background:var(--hover); color:var(--blue)}
.ask.busy button{opacity:.4; pointer-events:none}
.chips{display:flex; flex-wrap:wrap; gap:8px; justify-content:center; margin:16px 0 0}
.chips button{
  font:inherit; font-size:13.5px; color:var(--body); cursor:pointer;
  height:34px; padding:0 14px; border-radius:10px; border:1px solid var(--rule); background:transparent;
}
.chips button:hover{background:var(--hover); border-color:var(--quiet)}

.answer{margin:24px 0 0; padding:22px 24px; border-radius:var(--radius); background:var(--surface-2); animation:rise .3s cubic-bezier(.2,0,0,1)}
@keyframes rise{from{opacity:0; transform:translateY(6px)}}
@media (prefers-reduced-motion: reduce){ .answer{animation:none} }
.a-q{margin:0 0 10px; font-size:13.5px; color:var(--quiet)}
.a-text{margin:0; font-size:17px; line-height:1.6; color:var(--ink)}
.a-text.quote{border-left:3px solid var(--rule); padding-left:14px; color:var(--body)}
.a-text a, .a-src a{color:var(--blue)}
.a-src{display:flex; flex-wrap:wrap; gap:6px 8px; align-items:center; margin:16px 0 0; font-size:13.5px}
.a-src .q{margin-right:4px}
.a-src a{padding:4px 10px; border-radius:999px; background:var(--bg); border:1px solid var(--rule)}
.a-src a:hover{border-color:var(--blue)}
.a-note{margin:12px 0 0; font-size:12.5px; color:var(--quiet)}
.a-load{display:grid; gap:10px; padding:4px 0}
.a-load span{height:12px; border-radius:6px; background:linear-gradient(90deg, var(--rule), var(--surface), var(--rule)); background-size:200% 100%; animation:shimmer 1.2s linear infinite}
.a-load span:nth-child(2){width:86%} .a-load span:nth-child(3){width:58%}
@keyframes shimmer{to{background-position:-200% 0}}

/* ---------- the way back to the room ----------
   The room's pixel face, a pixel house and the room's pixel pointer: the
   only retro on the page, so it reads as a door rather than a theme. */
.roomlink{
  display:inline-flex; align-items:center; gap:8px;
  font-family:"Silkscreen","Courier New",monospace; font-size:11px; letter-spacing:.06em;
  cursor:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='28' viewBox='0 0 11 14' shape-rendering='crispEdges'%3E%3Cpath fill='%23fff' d='M0 0h2v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v2H7v1h1v2H6v1H5v-2H4v-1H3v1H2v1H0z'/%3E%3Cpath fill='%23000' d='M1 1h1v1h1v1h1v1h1v1h1v1h1v1h1v1h1v1H6v1h1v2H6v-2H5v-1H4v1H3v1H2v1H1z'/%3E%3C/svg%3E") 1 1, pointer;
}
.bar .links a.contact{background:var(--blue); color:var(--blue-ink); font-weight:500; margin-left:6px; padding:8px 16px}
.bar .links a.contact:hover{background:var(--blue); color:var(--blue-ink); box-shadow:var(--shadow)}
.roomlink .px{width:14px; height:14px; flex:0 0 auto}
.roomlink:hover .px{animation:hop .5s steps(2) infinite}
@keyframes hop{50%{transform:translateY(-2px)}}
@media (prefers-reduced-motion: reduce){ .roomlink:hover .px{animation:none} }
.foot p{margin:0}
.roomlink.big{
  margin:16px 0; font-size:14px; gap:12px; padding:14px 22px; border-radius:6px;
  background:var(--ink); color:var(--bg); box-shadow:4px 4px 0 var(--blue);
}
.roomlink.big .px{width:20px; height:20px}
.roomlink.big:hover{transform:translate(-1px,-1px); box-shadow:5px 5px 0 var(--blue)}
.roomlink.big:active{transform:translate(3px,3px); box-shadow:1px 1px 0 var(--blue)}
.foot .q a{color:var(--blue)}

/* ---------- a card's recording, over its still ---------- */
.cover > img, .cover .hand{position:relative}
.cover{position:relative}
.cover video.hov{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .25s}
.cover .hand{position:relative}
.cover video.hov.on{opacity:1}

/* ---------- moving between pages ----------
   A card's picture and title carry their names into the case page, where
   the stage and the heading take them, so opening a case is one motion
   rather than a cut. Browsers without cross-document view transitions
   simply navigate. */
@media (prefers-reduced-motion: no-preference){
  @view-transition{navigation:auto}
}
::view-transition-group(*){animation-duration:.42s; animation-timing-function:cubic-bezier(.2,0,0,1)}
::view-transition-old(root), ::view-transition-new(root){animation-duration:.25s}

/* ---------- the paged part: hello, results, one screen per project ----------
   Native scroll-snap, not a scroll hijack: trackpads, keys, screen readers
   and the back button all behave as they do everywhere else, and one
   swipe moves one screen because every screen is a stop. The canvas is
   sticky behind all of them, so its particles stay put while the screens
   slide over it and portfolio.js moves them from object to object.
   Everything here is dark in both themes, so its colours are fixed. */
html:has(body.home){scroll-snap-type:y mandatory}
@media (prefers-reduced-motion: no-preference){ html:has(body.home){scroll-behavior:smooth} }
.deck{position:relative; background:#141416; color:#f1f1f1}
/* The backdrop is the deck's full height, and the canvas is sticky inside
   it, so the canvas can only stay pinned while the deck is on screen. A
   sticky element with a negative margin instead (the first version) stays
   stuck for a further screen and covered the page below. */
.backdrop{position:absolute; inset:0; z-index:0; overflow:clip}
.backdrop canvas.face{position:sticky; top:0; display:block; width:100%; height:100vh; height:100svh}
.nodots .backdrop canvas.face{display:none}
.slide{
  position:relative; z-index:1; min-height:100vh; min-height:100svh; margin:0;
  scroll-snap-align:start; scroll-snap-stop:always;
  display:flex; flex-direction:column; justify-content:flex-end; pointer-events:none;
}
.slide a, .slide button, .slide .nums{pointer-events:auto}
.tail{scroll-snap-align:start}
.sin, .hero .who{padding:0 max(16px, calc((100% - 1080px) / 2)) 128px; max-width:calc(600px + max(32px, calc(100% - 1080px)))}
.sin{display:flex; flex-direction:column; justify-content:center; min-height:100vh; min-height:100svh; padding-bottom:0}
.kick{font-family:"Instrument Sans",sans-serif; font-size:13px; font-weight:500; letter-spacing:.08em; text-transform:uppercase; color:#8ab4f8; margin:0 0 20px}
.kick span{color:#6c6c72}

/* hello */
.hello{
  font-family:"Instrument Serif",Georgia,serif; font-weight:400; color:#fff;
  font-size:clamp(56px, 8.4vw, 128px); line-height:.92; letter-spacing:-.025em; margin:0;
}
.hello .w{display:inline-block}
.hello .brk{display:none}
@media (min-width: 761px){ .hello .brk{display:inline} }
.years{margin:28px 0 0; font-size:clamp(17px, 1.5vw, 20px); line-height:1.45; color:#b4b4b9; max-width:23em}
/* The sans, not the serif: the serif's 1 has no flag and 11 reads as "ll". */
/* What I am looking for, under the years: one quiet line with a live dot. */
.seek{margin:18px 0 0; font-size:clamp(14px, 1.1vw, 16px); line-height:1.45; color:#e8e8ec; max-width:36em; text-wrap:pretty; display:flex; align-items:baseline; gap:10px}
.seek .dot{flex:none; width:8px; height:8px; border-radius:50%; background:#5fd38d; box-shadow:0 0 0 4px rgba(95,211,141,.16); transform:translateY(-1px)}
.years .count{font-weight:500; color:#fff; font-size:2.2em; line-height:.8; letter-spacing:-.04em; margin-right:.14em; vertical-align:-.1em; font-variant-numeric:tabular-nums}
/* The roles, as a ticker tape along the foot of the hero: two identical
   runs side by side, the pair sliding left by one run's width, so the loop
   has no seam. It pauses under the pointer. */
.ticker{position:absolute; z-index:1; left:0; right:0; bottom:0; height:52px; overflow:hidden;
        border-top:1px solid rgba(255,255,255,.08); background:rgba(20,20,22,.55);
        -webkit-mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
        mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); pointer-events:auto}
.tape{display:flex; width:max-content; height:100%; animation:tape 38s linear infinite}
.ticker:hover .tape{animation-play-state:paused}
.run{display:flex; align-items:center; flex:0 0 auto}
.run span{display:inline-flex; align-items:center; white-space:nowrap; font-size:15px; font-weight:500; letter-spacing:.01em; color:#c9c9cd; padding:0 22px}  /* own case: uppercase makes iOS read IOS */
.run span::after{content:""; width:6px; height:6px; border-radius:50%; background:#8ab4f8; margin-left:44px}
@keyframes tape{to{transform:translateX(-50%)}}
.down{position:absolute; left:50%; bottom:68px; margin-left:-20px; width:40px; height:40px; border-radius:50%; display:grid; place-items:center; color:#8a8a90}
.down:hover{color:#fff; background:rgba(255,255,255,.06)}
.down svg{animation:nudge 2.4s 3.2s ease-in-out infinite}
@keyframes nudge{0%,60%,100%{transform:none} 30%{transform:translateY(4px)}}
.hero .w{opacity:0; transform:translateY(18px); animation:arrive .9s cubic-bezier(.2,0,0,1) forwards; animation-delay:calc(var(--i) * 140ms + 350ms)}
.hello .w{transform:translateY(.35em); filter:blur(6px); animation-name:arrive-blur}
@keyframes arrive{to{opacity:1; transform:none}}
@keyframes arrive-blur{to{opacity:1; transform:none; filter:none}}

/* results */
.stats .nums{grid-template-columns:repeat(2, minmax(0,1fr)); gap:36px 40px; max-width:560px}
.stats .nums li > a:hover{background:rgba(255,255,255,.06)}
.stats .nums b{color:#fff; font-size:clamp(40px, 4.6vw, 56px)}
.stats .nums .nl{color:#d6d6da}
.stats .nums .ns{color:#8a8a90}
/* With the dots forming the numbers they are the screen's picture, so on
   a wide screen they get the whole width: three columns, set large. */
@media (min-width: 1001px){
  .stats .sin{max-width:calc(1080px + max(32px, calc(100% - 1080px)))}
  .stats .nums{grid-template-columns:repeat(2, minmax(0,1fr)); max-width:none; gap:40px 64px}
  .stats .nums b{font-size:clamp(56px, min(6.6vw, 10.5vh), 100px); line-height:.95}
  .stats .nums .nl{font-size:16px; margin-top:12px}
}
/* The heading reads like a project's title: same face and size. */
.stats h2.kick{font-family:"Instrument Serif",Georgia,serif; font-weight:400; text-transform:none;
  font-size:clamp(44px, min(6.4vw, 9vh), 96px); line-height:.95; letter-spacing:-.025em; color:#fff; margin:0 0 36px}
@media (max-width: 1000px){ .stats h2.kick{font-size:clamp(40px, 12vw, 56px); margin-bottom:22px} }
/* one line each: the dots are drawn from the number as one line, so the type must be too */
.stats .nums b{white-space:nowrap}
/* Once the particles have formed the numbers (portfolio.js), the type
   beneath steps aside: still there for screen readers, selection and
   anything that cannot draw the canvas. */
.dotnums .stats .nums b{color:transparent}

/* Designs without a recording, in motion: a whole page scrolling in a
   window, and screens fading one into the next. Both run only while their
   screen is up (portfolio.js marks it .current). */
.scrollwin{background:#fff}
.scrollwin .chrome{position:absolute; z-index:1; top:0; left:0; right:0; height:22px; background:#ececef; display:flex; gap:6px; align-items:center; padding:0 10px}
.scrollwin .chrome i{width:8px; height:8px; border-radius:50%; background:#c9c9cf}
.preview .scrollwin img{position:absolute; inset:22px 0 0; width:100%; height:calc(100% - 22px); object-fit:cover; object-position:50% 0%;
               animation:pagescroll 26s cubic-bezier(.45,0,.55,1) 1s infinite alternate}
@keyframes pagescroll{0%, 6%{object-position:50% 0%} 94%, 100%{object-position:50% 100%}}
/* The first screen is always there and never animated, so the preview can
   never be blank; the others fade in over it in turn and away again. */
.fades img{position:absolute; inset:0}
.fades img:first-child{position:relative; opacity:1}
.fades img + img{opacity:0; animation:fadecycle calc(var(--n) * 4s) linear infinite; animation-delay:calc(var(--k) * 4s - 4s)}
@keyframes fadecycle{0%{opacity:0; transform:scale(1)} 6%{opacity:1} 33%{opacity:1} 40%{opacity:0; transform:scale(1.04)} 100%{opacity:0}}
.slide:not(.current) .scrollwin img, .slide:not(.current) .fades img{animation-play-state:paused}
@media (prefers-reduced-motion: reduce){ .preview .scrollwin img, .fades img, .fades img + img{animation:none} .fades img + img{opacity:0} }

/* The logo behind a project runs the full width of the screen; this fade
   dims it under the words, so they read, and leaves it bright behind and
   around the design. */
.proj::before{content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(90deg, rgba(20,20,22,.92) 0%, rgba(20,20,22,.82) 38%, rgba(20,20,22,0) 56%)}
.proj .sin{position:relative; z-index:1}
@media (max-width: 1000px){
  .proj::before{background:linear-gradient(0deg, rgba(20,20,22,.94) 0%, rgba(20,20,22,.84) 44%, rgba(20,20,22,0) 62%)}
}

/* a project: the words hold to 480px, so the design beside them never covers a line */
.proj .sin{max-width:calc(480px + max(32px, calc(100% - 1080px)))}
/* a project */
.ptitle{font-size:clamp(48px, 6.4vw, 96px); line-height:.95; letter-spacing:-.025em; margin:0; color:#fff}
.ptitle a{display:inline-block}
.ptitle a:hover{color:#8ab4f8}
.ptitle .note{display:block; font-family:"Instrument Sans",sans-serif; font-size:15px; letter-spacing:0; color:#8a8a90; margin-top:10px}
.pline{margin:22px 0 0; font-size:clamp(17px, 1.5vw, 20px); line-height:1.5; color:#d6d6da; max-width:28em}
.pmeta{margin:16px 0 0; font-size:13px; color:#6c6c72}
.pgo{display:flex; flex-wrap:wrap; align-items:center; gap:10px 18px; margin:28px 0 0}
.btn.light{background:#fff; color:#141416; border-color:transparent}
.btn.light:hover{background:#e8e8ea; box-shadow:none}
.pgo .ext{font-size:14px; color:#a6a6ab}
.pgo .ext:hover{color:#fff}

/* the design, on the right of each project's screen, over its logo's haze */
.preview{
  position:absolute; z-index:1; pointer-events:auto;
  /* the words keep the first 480px of the column; the design takes the rest, clear of the rail */
  left:calc(max(16px, (100% - 1080px) / 2) + 528px); right:max(150px, calc((100% - 1080px) / 2));
  top:50%; transform:translateY(-50%); height:min(66vh, 620px); height:min(66svh, 620px);
  display:flex; align-items:center; justify-content:center; gap:22px;
  container-type:size;
}
.preview .pv{display:block; position:relative; overflow:hidden; max-width:100%; max-height:100%; flex:0 1 auto;
             border-radius:14px; background:#0b0b0c; box-shadow:0 30px 80px -24px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.07);
             transition:transform .5s cubic-bezier(.2,0,0,1)}
/* Anything else: as large as the box allows at its own proportions. */
.preview:not(.phones) .pv{height:auto; flex:0 0 auto; width:min(100cqw, calc(100cqh * var(--ar, 1.5)))}
/* Phones are sized from the box: as wide as half of it allows, or as tall as
   its height allows, whichever is smaller, so they never get squeezed. */
.preview.phones .pv{height:auto; flex:0 0 auto; width:min(calc((100cqw - 22px) / 2), calc(100cqh * var(--ar, .4615))); border-radius:30px}
.preview.phones .pv + .pv{width:calc(min(calc((100cqw - 22px) / 2), calc(100cqh * var(--ar, .4615))) * .88); align-self:flex-end; margin-bottom:2%}
/* one phone: as tall as the box allows */
.preview.phones .pv:only-child{width:min(100cqw, calc(100cqh * var(--ar, .4615)))}
.preview .pv img, .preview .pv video{display:block; width:100%; height:100%; object-fit:cover}
.preview .pv.cut{background:none; box-shadow:none; overflow:visible}
.preview .pv.cut img{object-fit:contain}
.preview:hover .pv{transform:translateY(-6px)}
@media (prefers-reduced-motion: reduce){ .preview:hover .pv{transform:none} }

/* Phones in a phone: a dark bezel with a thin rim of light, the screen set
   inside it with its own corners, and the island over a top strip (the
   clips have their real status bar cropped off). */
.preview.phones .pv.device{padding:30px 8px 8px; background:#060607; border-radius:42px; overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,.14), inset 0 0 0 1px rgba(255,255,255,.05), 0 40px 90px -30px rgba(0,0,0,.95)}
.preview.phones .pv.device::before{content:""; position:absolute; z-index:1; top:10px; left:50%; width:30%; height:12px; margin-left:-15%;
  border-radius:999px; background:#000; box-shadow:0 0 0 1px rgba(255,255,255,.06)}
.preview.phones .pv.device video, .preview.phones .pv.device img{border-radius:32px; background:#000}
@media (max-width: 1000px){
  .preview.phones .pv.device{padding:18px 5px 5px; border-radius:26px}
  .preview.phones .pv.device::before{top:6px; height:7px}
  .preview.phones .pv.device video, .preview.phones .pv.device img{border-radius:20px}
}

/* Rocket Mortgage: the landing page scrolling, the rebrand's menu beside it */
.preview.combo{padding-bottom:8%}
.preview.combo .pv.inset{position:absolute; z-index:2; right:2%; bottom:0; width:42%; height:auto; border-radius:12px;
  box-shadow:0 0 0 1px rgba(255,255,255,.12), 0 30px 60px -18px rgba(0,0,0,.95)}
.preview.combo .pv.inset video{border-radius:12px}
.btn.ghost{color:#f1f1f1; border-color:rgba(255,255,255,.28); background:transparent}
.btn.ghost:hover{background:rgba(255,255,255,.08); border-color:#fff}

/* the rail: which screen is up, and a way to any other. Ticks at the edge
   of the screen; the current one is named, the rest on hover. */
.rail{position:fixed; z-index:4; right:20px; top:50%; transform:translateY(-50%);
      display:flex; flex-direction:column; align-items:flex-end; gap:0; transition:opacity .3s}
.rail.gone{opacity:0; pointer-events:none}
.rail a{display:flex; align-items:center; gap:10px; font-size:12.5px; color:#6c6c72; padding:4px 0; transition:color .2s}
.rail a span{opacity:0; transform:translateX(6px); transition:opacity .2s, transform .2s; white-space:nowrap}
.rail a::after{content:""; width:12px; height:2px; border-radius:1px; background:currentColor; transition:width .3s cubic-bezier(.2,0,0,1)}
.rail:hover a span, .rail a:focus-visible span, .rail a[aria-current] span{opacity:1; transform:none}
.rail a:hover{color:#c9c9cd}
.rail a[aria-current]{color:#fff}
.rail a[aria-current]::after{width:28px}
.rail:hover{background:linear-gradient(90deg, transparent, rgba(20,20,22,.85) 30%); padding-left:40px}
/* over the white page below the screens, the rail takes the page's colours */
.rail.onlight a{color:#9aa0a6}
.rail.onlight a:hover{color:#5f6368}
.rail.onlight a[aria-current]{color:#202124}
.rail.onlight:hover{background:linear-gradient(90deg, transparent, rgba(255,255,255,.92) 30%)}
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]) .rail.onlight a[aria-current]{color:#e3e3e3} :root:not([data-theme="light"]) .rail.onlight:hover{background:linear-gradient(90deg, transparent, rgba(31,31,31,.92) 30%)} }

/* the bar floats over the dark screens, then turns back to the page's own */
.home .bar{position:fixed; left:0; right:0; top:0; transition:background .25s, color .25s}
.home .bar.ondark{background:transparent; -webkit-backdrop-filter:none; backdrop-filter:none; color-scheme:dark}
.home .bar.ondark .home, .home .bar.ondark .links a{color:#e8e8ea}
.home .bar.ondark .links a:hover{background:rgba(255,255,255,.08); color:#fff}
.home .bar.ondark .links a.contact{background:#fff; color:#141416}
.home .bar.ondark .links a.contact:hover{background:#e8e8ea; color:#141416}

/* after the screens: the ordinary page */
.tail{padding-top:96px}
.tail .intro{text-align:center}
.tail .intro h2{margin-bottom:24px}
.tail .intro .meta{font-size:14px; color:var(--quiet); margin:24px 0 0}
.tail .intro .meta a{color:var(--blue)}

@media (prefers-reduced-motion: reduce){
  .tape{animation:none}
  .ticker{-webkit-mask-image:none; mask-image:none}
  .hero .w, .hello .w{animation:none; opacity:1; transform:none; filter:none}
  .down svg{animation:none}
}

@media (max-width: 760px){
  .rail{right:8px}
  .rail a span{display:none}
  .rail a{padding:4px 0}
  .rail a::after{width:9px}
  .rail a[aria-current]::after{width:20px}
  .hero .who{padding:0 22px 116px; max-width:none}
  .sin{padding:0 40px 56px 22px; max-width:none; justify-content:flex-end}
  .hello{font-size:clamp(48px, 14vw, 64px)}
  .years{margin-top:18px; font-size:16px}
  .seek{margin-top:12px; font-size:14px}
  .ptitle{font-size:clamp(40px, 12vw, 56px)}
  .stats .nums{gap:24px 20px}
  .stats .nums b{font-size:34px}
  .preview.phones .pv{border-radius:20px}
  .pline{font-size:16px; margin-top:14px}
  .pgo{margin-top:20px}
  .down{bottom:60px}
  .ticker{height:44px}
  .run span{font-size:13.5px; padding:0 16px}
  .run span::after{margin-left:32px}
  .tail{padding-top:104px}
}

/* Below 1000px there is no room beside the words: the design goes above
   them, as on a phone. */
@media (max-width: 1000px){
  .preview{left:0; right:0; top:76px; transform:none; width:auto; height:min(40vh, 340px); height:min(40svh, 340px); padding:0 22px; gap:14px}
  .proj .sin{justify-content:flex-end; padding-bottom:64px}
}
/* Short phones: a smaller design, so the words below keep their room. */
@media (max-width: 1000px) and (max-height: 700px){
  .preview{top:68px; height:min(28vh, 220px); height:min(28svh, 220px)}
  .proj .pline{display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden}
}
/* Below 600px of height a design would be a thumbnail: the words alone, over the haze. */
@media (max-width: 1000px) and (max-height: 600px){ .preview{display:none} }

/* ---------- the contact form ----------
   A plain dialog in the page's own colours, over whatever screen opened
   it. The hidden field is for bots; people never see it. */
.contactbox{
  width:min(520px, calc(100vw - 32px)); max-height:calc(100vh - 32px); max-height:calc(100dvh - 32px); overflow:auto;
  border:0; border-radius:24px; padding:0; background:var(--bg); color:var(--ink); box-shadow:0 24px 80px -20px rgba(0,0,0,.6);
}
.contactbox::backdrop{background:rgba(10,10,12,.62); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px)}
.contactbox[open]{animation:ctin .28s cubic-bezier(.2,0,0,1)}
@keyframes ctin{from{opacity:0; transform:translateY(10px) scale(.98)}}
@media (prefers-reduced-motion: reduce){ .contactbox[open]{animation:none} }
.ct, .ct-done{position:relative; padding:32px 32px 28px}
.contactbox h2{font-size:36px; margin:0 0 8px}
.ct-sub{margin:0 0 22px; color:var(--quiet); font-size:14.5px}
.ct label{display:block; font-size:13px; font-weight:500; color:var(--body); margin:0 0 14px}
.ct input, .ct textarea{
  display:block; width:100%; margin-top:6px; padding:12px 14px; border-radius:12px;
  border:1px solid var(--rule); background:var(--bg); color:var(--ink); font:inherit; font-size:16px;
}
.ct textarea{resize:vertical; min-height:120px; line-height:1.5}
.ct input:focus, .ct textarea:focus{outline:2px solid var(--blue); outline-offset:0; border-color:transparent}
.ct-trap{position:absolute !important; left:-9999px; width:1px; height:1px; overflow:hidden}
.ct-x{position:absolute; top:14px; right:14px; width:40px; height:40px; border-radius:50%; border:0; background:transparent;
      color:var(--quiet); font-size:26px; line-height:1; cursor:pointer}
.ct-x:hover{background:var(--hover); color:var(--ink)}
.ct-status{min-height:1.4em; margin:2px 0 10px; font-size:14px; color:var(--body)}
.ct-status.bad{color:#d93025}
.ct-status a{color:var(--blue); text-decoration:underline}
.ct-go{display:flex; flex-wrap:wrap; align-items:center; gap:10px 18px; margin:0}
.ct-go .btn[disabled]{opacity:.6; cursor:default}
.ct-mail{font-size:14px; color:var(--quiet)}
.ct-mail:hover{color:var(--blue)}
@media (max-width: 520px){ .ct, .ct-done{padding:26px 20px 22px} .contactbox h2{font-size:30px} }
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]) .ct-status.bad{color:#f28b82} }
:root[data-theme="dark"] .ct-status.bad{color:#f28b82}
@media (max-width: 360px){ .stats .nums b{font-size:27px} }
/* Phones: the results start below the bar; on short ones the source line under
   each number goes (the case pages carry it) so all six fit on one screen. */
@media (max-width: 1000px){ .stats .sin{padding-top:76px} }
@media (max-width: 1000px) and (max-height: 720px){
  .stats .nums .ns{display:none}
  .stats .nums{gap:18px 18px}
  .stats .sin{padding-bottom:40px}
}

/* A recording the phone would not autoplay: a play button over its still. */
.preview .pv.tap{cursor:pointer}
.preview .pv.tap::after{
  content:""; position:absolute; z-index:3; left:50%; top:50%; width:64px; height:64px; margin:-32px 0 0 -32px; border-radius:50%;
  background:rgba(255,255,255,.94) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5v14l11-7z' fill='%23141416'/%3E%3C/svg%3E") 56% 50% / 28px no-repeat;
  box-shadow:0 10px 30px -8px rgba(0,0,0,.7);
}

/* ---------- the story intro (intro.js) ----------
   Captions low on the left, one phrase at a time, in the headline face;
   while the story plays, the hero's own words step back. */
.storybox{position:absolute; inset:0; z-index:2; pointer-events:none}
.storybox .story-video{position:absolute; width:1px; height:1px; opacity:0; pointer-events:none}
.story-cap{position:absolute; left:max(16px, calc((100% - 1080px) / 2)); bottom:128px; max-width:min(560px, 46vw); margin:0;
  font-family:"Instrument Serif",Georgia,serif; font-size:clamp(26px, 2.6vw, 40px); line-height:1.15; color:#f4f4f6;
  text-shadow:0 2px 24px rgba(20,20,22,.9), 0 0 2px rgba(20,20,22,.8);
  opacity:0; transform:translateY(8px); transition:opacity .45s ease, transform .45s cubic-bezier(.2,0,0,1)}
.story-cap.on{opacity:1; transform:none}
.story-ctl{position:absolute; left:max(16px, calc((100% - 1080px) / 2)); bottom:76px; margin:0; display:flex; gap:8px; opacity:0; transition:opacity .3s}
.storybox.live .story-ctl, .storybox.done .story-ctl{opacity:1; pointer-events:auto}
.storybox:not(.done) [data-replay]{display:none}
.storybox.done [data-sound]{display:none}
.story-ctl button, .story-watch button{font:inherit; font-size:13px; color:#d6d6da; background:rgba(20,20,22,.6); border:1px solid #3a3a40; border-radius:999px; padding:6px 14px; cursor:pointer}
.story-ctl button:hover, .story-watch button:hover{border-color:#f1f1f1; color:#fff}
.story-ctl [data-sound][aria-pressed="true"]{border-color:#8ab4f8; color:#8ab4f8}
.story-watch{position:absolute; left:max(16px, calc((100% - 1080px) / 2)); bottom:76px; margin:0; display:none; pointer-events:auto}
.storybox.fallback .story-watch{display:block}
.story-text{position:absolute; left:max(16px, calc((100% - 1080px) / 2)); right:max(16px, calc((100% - 1080px) / 2)); bottom:124px; max-width:560px;
  pointer-events:auto; background:rgba(20,20,22,.92); border:1px solid #3a3a40; border-radius:16px; padding:18px 20px; max-height:50vh; overflow:auto}
.story-text p{margin:0 0 8px; font-size:15px; line-height:1.5; color:#d6d6da}
.hero .who, .hero .ticker, .hero .down{transition:opacity .6s ease}
.hero.storying .who, .hero.storying .ticker, .hero.storying .down{opacity:0 !important; pointer-events:none}
@media (max-width: 760px){
  .story-cap{left:22px; right:22px; max-width:none; bottom:118px; font-size:26px}
  .story-ctl, .story-watch{left:22px; bottom:64px}
  .story-text{left:22px; right:22px; bottom:110px}
}

/* The play button by the face: just right of the cheek, where the eye is
   already. */
.story-play{
  position:absolute; pointer-events:auto; z-index:3;
  left:calc(62% + min(73.9vh, 44vw) * 0.3); top:calc(16% + 84% * 0.42);
  display:inline-flex; align-items:center; gap:10px; height:48px; padding:0 18px 0 8px; border-radius:999px;
  font:inherit; font-size:14px; font-weight:500; color:#141416; background:rgba(255,255,255,.94); border:0; cursor:pointer;
  box-shadow:0 14px 40px -12px rgba(0,0,0,.8); transition:opacity .4s, transform .25s cubic-bezier(.2,0,0,1);
  animation:playin .7s cubic-bezier(.2,0,0,1) 2.2s both;
}
.story-play:hover{transform:scale(1.04)}
/* two soft rings ripple out from the button in turn, and the play icon
   breathes, so it reads as something to press without shouting */
.story-play::before, .story-play::after{content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  border:1.5px solid rgba(255,255,255,.55); opacity:0; animation:playring 2.8s cubic-bezier(.2,0,0,1) 3s infinite}
.story-play::after{animation-delay:4.4s}
@keyframes playring{0%{opacity:.7; transform:scale(1)} 70%{opacity:0; transform:scale(1.22, 1.6)} 100%{opacity:0; transform:scale(1.22, 1.6)}}
.story-play .pi{animation:playpulse 2.8s ease-in-out 3s infinite}
@keyframes playpulse{0%,100%{transform:scale(1)} 12%{transform:scale(1.12)} 24%{transform:scale(1)}}
.story-play:hover::before, .story-play:hover::after{animation-duration:1.6s}
.story-play:hover .pi{background-position:62% 50%}
.story-play .pi{width:32px; height:32px; border-radius:50%; background:#141416 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6.5v11l9-5.5z' fill='%23fff'/%3E%3C/svg%3E") 55% 50% / 18px no-repeat}
.story-play .pd{color:#6c6c72; font-weight:400; font-variant-numeric:tabular-nums}
.story-play .pd:empty{display:none}
/* while the intro plays, the play button steps aside: Mute and the captions take over */
.storybox.live .story-play{opacity:0; pointer-events:none; transform:scale(.94)}
/* the mute button: a speaker, struck through when muted */
.story-ctl [data-sound]{display:inline-flex; align-items:center; gap:8px}
.story-ctl .mi{width:16px; height:16px; background:currentColor; -webkit-mask:var(--spk) center / contain no-repeat; mask:var(--spk) center / contain no-repeat;
  --spk:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 9h4l5-4v14l-5-4H4z'/%3E%3Cpath d='M16 8.5a5 5 0 0 1 0 7M18.5 6a8.5 8.5 0 0 1 0 12' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E")}
.story-ctl .mi.off{--spk:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 9h4l5-4v14l-5-4H4z'/%3E%3Cpath d='M16 9l6 6M22 9l-6 6' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E")}
@keyframes playin{from{opacity:0; transform:translateY(8px)}}
@media (prefers-reduced-motion: reduce){ .story-play, .story-play::before, .story-play::after, .story-play .pi{animation:none} }
.storybox.fallback .story-watch{display:block}
@media (max-width: 760px){
  /* phones: the face fills the top of the screen; the button sits at its lower right */
  .story-play{left:auto; right:22px; top:calc(40px + min(116vw, 62%) * 0.62); height:44px; font-size:13px}
}

/* Pause: holds the intro where it is, so Play reads "Resume" after. Only
   there while it plays. Two bars rather than an ×, because the press does
   not throw the words away. */
.story-ctl .story-pause{width:32px; padding:0; display:inline-grid; place-items:center; line-height:1}
.story-ctl .story-pause .pzi{width:14px; height:14px; background:currentColor;
  -webkit-mask:var(--pz) center / contain no-repeat; mask:var(--pz) center / contain no-repeat;
  --pz:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 4h3.4v16H7zM13.6 4H17v16h-3.4z'/%3E%3C/svg%3E")}
.storybox:not(.live) .story-pause{display:none}
/* On a phone the bar keeps the mark, the name and the links on one line */
@media (max-width: 480px){
  .bar .home{font-size:15px; gap:8px; white-space:nowrap}
  .bar .home .mark{width:22px; height:22px; border-radius:5px}
  .bar .links a{white-space:nowrap}
}
@media (max-width: 350px){ .bar .home .mark{display:none} .bar .home{font-size:14px} .bar .links a{padding:8px 9px; font-size:13px} }

/* On a phone the intro takes the screen while it plays: the rail joins the
   ticker and the arrow in stepping aside; the top nav stays, and scrolling
   still leaves (the intro pauses once the hero is out of view). */
@media (max-width: 760px){
  html.storying .rail{opacity:0; pointer-events:none}
}
