.page-hero{
  min-height:clamp(510px,41.667vw,800px);
  padding:0 var(--gutter) clamp(48px,4.6875vw,90px);
  display:flex;
  align-items:flex-end;
}
.page-hero-inner{width:100%}
.page-title{
  font-size:clamp(72px,8.4375vw,162px);
  font-weight:500;
  line-height:.92;
  letter-spacing:-.038em;
  text-wrap:balance;
}
.page-deck{
  max-width:34ch;
  margin:clamp(32px,3.333vw,64px) 0 0 auto;
  font-size:clamp(22px,2.083vw,40px);
  line-height:1.2;
  text-wrap:pretty;
}

.work-page{padding:0 var(--gutter) clamp(96px,8.333vw,160px)}
.work-row{display:grid;gap:var(--gap);margin:0 0 clamp(80px,6.667vw,128px);list-style:none;padding:0}
.work-row>li{display:block;min-width:0}
.work-row--wide-narrow{grid-template-columns:minmax(0,936fr) minmax(0,552fr)}
.work-row--full{grid-template-columns:1fr}
.work-row--narrow-wide{grid-template-columns:minmax(0,552fr) minmax(0,936fr)}
.project-card{display:block;min-width:0}
.project-card-media{
  display:block;
  position:relative;
  width:100%;
  height:clamp(350px,28.75vw,552px);
  overflow:hidden;
  border-radius:var(--radius-card);
  background:var(--ground);
  box-shadow:inset 0 0 0 1px var(--frame);
}
.project-card-media img,.project-card-media video{width:100%;height:100%;object-fit:cover}
/* Drops the row's shared height and sizes the box to --media-ratio, the
   width/height pair the card sets inline on this element, so that card's
   own crop drives its height at every width. A ratio states how much of the
   artwork's own outer margin the frame crops away, so every one of them is
   read against its file: no card states a ratio more than a percent off its
   picture's own shape unless the crop is a decision, and the one that is
   keeps 95.4 percent of Penn Street Tower's width. Every other card keeps at
   least 99.95 percent of both axes, cch+a's 99.95 the tightest of them, and
   the five composited cards whose delivery window was cut to the piece state
   that window's own ratio, so they keep all of both. Two rows use it to land
   level:
   Innovate or Evaporate at 6/7 beside Brightwell at 234/161, and Launch day
   at 3/2 beside Hoosier Heater at 552/624, each pair ending on one line at
   1440 because the wide column is exactly 936/552 of the narrow one and each
   pair's ratios carry that same factor. Every other row is deliberately
   unequal. */
.project-card-media.is-ratio{height:auto;aspect-ratio:var(--media-ratio)}
.project-card-info{display:flex;align-items:baseline;justify-content:space-between;gap:24px;padding-top:clamp(20px,2.083vw,40px)}
.project-card-title{font-size:clamp(28px,2.083vw,40px);font-weight:500;line-height:1.2}
.project-card-meta{font-family:var(--mono);font-size:clamp(16px,1.042vw,20px);line-height:1.3;color:var(--ink-soft);text-align:right;white-space:nowrap}
/* Title and meta stack left-bound per card at width >=768px; the block
   below handles the <=767px stack. */
@media (min-width:768px){
  .project-card-info{display:block}
  .project-card-title,.project-card-meta{display:block}
  .project-card-meta{margin-top:clamp(6px,.625vw,10px);text-align:left}
}
/* A level pair arrives as one item rather than two: the right hand card's
   reveal starts 90ms after the left one's. Only rows marked level get it,
   because a pair whose two cards end at different heights already reads as
   two beats, and it lives inside the motion query so the JS off default
   (every [data-reveal] painted at rest) is untouched. The wall's rhythm is
   in the heights now, not in an offset. Re-measured at 1440 after the two
   cuts and the Eisenbarth re-crop: the wall is five pairs, two of them level
   and three unequal, and the widest of the three is Settled beside Penn
   Street Tower, whose right hand card's foot lands 435.80px above its
   neighbour's, 48.9 percent of the way down it. The two pairs that stay
   level do so because their cards' stated ratios were chosen to land
   together, and they land within 0.02px of each other. */
@media (prefers-reduced-motion:no-preference){
  .js .work-row--level>li:nth-child(2) [data-reveal]{transition-delay:90ms}
}
.project-card--link:focus-visible{outline:0}
/* A full width row is 16/9 unless its card states its own ratio. No card
   ships stating one: Turtle Tuesday, the only full width row now, is 16/9
   through .project-card-video-wrap below, which is the clip's own shape. */
.work-row--full .project-card-media:not(.is-ratio){height:auto;aspect-ratio:16/9}
.project-card-video-wrap{position:relative}
.project-card-video-wrap .project-card-media{height:auto;aspect-ratio:16/9}
/* The control sits beside the card's link rather than inside it, so the
   stylesheet puts it back over the media. A percentage margin resolves
   against the wrap's width and the media is that full width at 16/9, so
   56.25% lands on the media's bottom edge; the translate lifts the button
   back inside the frame by its own height. */
.project-card-video-pause{
  position:absolute;
  top:0;
  left:clamp(16px,2.083vw,40px);
  margin-top:calc(56.25% - clamp(16px,2.083vw,40px));
  transform:translateY(-100%);
  z-index:2;
  min-width:44px;
  min-height:44px;
  padding:0 16px;
  border:1px solid rgba(10,10,10,.6);
  border-radius:100px;
  background:#fff;
  color:#0a0a0a;
  font-family:var(--mono);
  font-size:13px;
  box-shadow:0 0 0 1px rgba(255,255,255,.5);
  transition:border-color .3s ease;
}
.project-card-video-pause:focus-visible{outline:3px solid #fff;outline-offset:3px;box-shadow:0 0 0 6px rgba(10,10,10,.85)}
@media (hover:hover){.project-card-video-pause:hover{border-color:rgba(10,10,10,.8)}}
/* The clip's first frame is a plain lazy <img> stacked under the <video>
   rather than the video's own poster attribute, because a poster is fetched
   at first paint whatever preload says and this card sits six viewports
   down. As an <img loading="lazy"> the still costs nothing until the card is
   near, and it is what paints under reduced motion, with scripting off, and
   in the moment between the clip's first request and its first frame. Both
   are given a position so the video is above the still rather than beside
   it, and the sprite is raised to the Pause control's level so both still
   paint over the pair. */
.project-card-video-poster{position:absolute;inset:0;z-index:0}
.project-card-video-wrap .project-card-media video{position:relative;z-index:1}
@media (prefers-reduced-motion:reduce){
  .project-card-video-wrap:not(.is-video-playing) .project-card-media video{display:none}
}
.no-js .project-card-video-wrap .project-card-media video{display:none}
.no-js .project-card-video-pause{display:none}
/* Flight Line is a screen recording of a 917 by 695 point prototype at 2x,
   so its pixels are only crisp painted at 917 CSS px or narrower. The box
   drops the ratio and takes the recording's own paper as its ground, the
   still sits in flow at that native width and centers, and the clip lies
   over it at the same size. Wider rows show more paper, never a blurrier
   picture; narrower ones scale both down together. The paper is the
   recording's, so it stays literal in dark mode like any other
   photograph. */
/* The box is the colour Chrome paints the clip's paper (measured at 2x), not the
   file's own value; the poster is repainted to match, so still and moving agree. */
[data-slug="flight-line"] .project-card-media{height:auto;aspect-ratio:auto;background:#f2f1eb}
[data-slug="flight-line"] .project-card-media img,
[data-slug="flight-line"] .project-card-media video{display:block;width:min(100%,917px);height:auto;margin:0 auto;object-fit:contain}
[data-slug="flight-line"] .project-card-video-poster{position:static}
[data-slug="flight-line"] .project-card-media video{position:absolute;inset:0}
/* Three disciplines is more than one mono line holds on a phone. */
@media (max-width:767px){[data-slug="flight-line"] .project-card-meta{white-space:normal}}
/* Three frames of the pixel turtle stepped across a one frame wide box: at
   rest, lifted by one pixel unit, then turned. It sits inside the media, in
   the corner opposite the Pause control at both widths, so the caption below
   is the same title and meta pair every other card runs. It runs only while
   the card's clip runs, because the wrap carries is-video-playing exactly
   while the Pause control reads Pause. So pressing Pause stops the turtle
   with the video, and reduced motion, which starts the card paused, leaves
   it still on the first frame until a visitor presses Play. It carries the
   Pause control's own z-index, because the clip it sits on is raised over
   the still behind it and a plain positioned element would paint under the
   clip. */
.project-card-sprite{
  position:absolute;
  right:clamp(16px,2.083vw,40px);
  bottom:clamp(16px,2.083vw,40px);
  z-index:2;
  width:52px;
  height:24px;
  background:url(assets/work/le/tt-pixel-turtle-sprite.svg) 0 50%/156px auto no-repeat;
  animation:tt-step .84s steps(3) infinite;
  animation-play-state:paused;
}
.project-card-video-wrap.is-video-playing .project-card-sprite{animation-play-state:running}
@keyframes tt-step{to{background-position:-156px 50%}}
/* Its own full width row, on its own rhythm, aligned to the grid's left edge
   rather than to page centre. Centred, its left edge landed within a pixel of
   the media edge of whichever card sat in the left column, which read as an
   accident. On the grid edge it reads as a decision. */
.work-source{display:flex;justify-content:flex-start;padding:clamp(24px,2.5vw,40px) 0 clamp(96px,8.333vw,160px)}

/* The client wall. One number per mark, --w, the width it takes of its own
   cell; height follows from the file's own ratio, so the wall scales with the
   column and there is nothing to retune per breakpoint.

   --w is not taste. Every mark was rendered mono into a fixed box and reduced
   to its ink bounding box and its luminance weighted ink area, then widths
   were solved to equalise that area, damped 0.8 toward equal height because a
   wordmark spreads its ink along a line and the eye reads the line by its
   height, not its total ink. Clamped at .80 of the cell wide and .50 of it
   tall; three marks hit a clamp (Brightwell, One Health, the Air Force seal)
   and the other twenty one land on the rule.

   Marks are full black at opacity 1. The strip that reads as wallpaper on
   every other studio site is caused by tinting marks to half opacity so they
   recede politely, not by the ground they sit on. These are receipts, so they
   are ink. */
.clients{padding:clamp(48px,5vw,96px) 0 clamp(16px,1.667vw,32px)}
.clients-label,.clients-note{font-family:var(--mono);font-size:clamp(16px,1.042vw,20px);line-height:1.3;color:var(--ink-soft)}
.clients-note{margin-top:.35em}
.clients-grid{margin-top:clamp(40px,4.167vw,80px);list-style:none;display:grid;grid-template-columns:repeat(5,minmax(0,1fr))}
/* No gap and no rules. The air is inside the cell, which is what lets a short
   last row read as a list that ended rather than a grid that broke. */
.clients-grid li{aspect-ratio:8/5;display:grid;place-items:center}
.clients-grid img{width:calc(var(--w)*100%);height:auto;filter:brightness(0)}
/* Salesforce paints its wordmark white inside a blue cloud, so brightness(0)
   flattens both to one shape and the name disappears into a nameless blob.
   This maps the cloud to ink and leaves the knockout as ground. It is the only
   mark here with mixed paint; every other white mark is white throughout. */
.clients-grid .is-knockout img{filter:grayscale(1) brightness(.62) contrast(24)}
@media (max-width:1279px) and (min-width:1024px){.clients-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (max-width:1023px) and (min-width:768px){.clients-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:767px){.clients-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* On dark the marks invert. invert(1) is APPENDED to each existing chain
   rather than a new chain being authored, so Salesforce's knockout inherits
   the contrast(24) tuning instead of re-deriving it and its cloud lands on the
   same value as its twenty three neighbours. At opacity 1 solid white marks
   bloom and read brighter than the body ink beside them; .9 composites them
   to about #e2e2e2, which is --ink's own weight. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme=light]) .clients-grid img{filter:brightness(0) invert(1);opacity:.9}
  :root:not([data-theme=light]) .clients-grid .is-knockout img{filter:grayscale(1) brightness(.62) contrast(24) invert(1)}
}
:root[data-theme=dark] .clients-grid img{filter:brightness(0) invert(1);opacity:.9}
:root[data-theme=dark] .clients-grid .is-knockout img{filter:grayscale(1) brightness(.62) contrast(24) invert(1)}

/* Three rows on screen, the rest of the roster cycling through them.

   The clamp is gated on `html.js:not(.reduced-motion)`, which the head script
   sets before the body paints, so there is no flash of twenty four marks
   collapsing to fifteen. Both fallbacks therefore keep the whole roster: with
   scripting off the class is still `no-js`, and under reduced motion the class
   is there, so neither one hides a client behind an animation it will never
   see. Reduced motion showing MORE than the default is the honest direction
   for a cycle: the movement is how fifteen slots hold twenty four marks, and
   without the movement you need twenty four slots.

   Positions are fixed. The cycle swaps a mark's data between a visible cell
   and a parked one, so nothing reflows and the grid never moves. */
html.js:not(.reduced-motion) .clients-grid li:nth-child(n+16){display:none}
@media (max-width:1279px) and (min-width:1024px){html.js:not(.reduced-motion) .clients-grid li:nth-child(n+13){display:none}}
@media (max-width:1023px) and (min-width:768px){html.js:not(.reduced-motion) .clients-grid li:nth-child(n+10){display:none}}
@media (max-width:767px){html.js:not(.reduced-motion) .clients-grid li:nth-child(n+7){display:none}}
/* A mark leaves upward and the next one arrives from below, so the swap reads
   as one thing replacing another rather than as a blink. `is-entering` kills
   the transition for one frame so the incoming mark snaps to its start offset
   instead of sliding there from wherever the outgoing one ended. */
html.js:not(.reduced-motion) .clients-grid li>img{transition:opacity .42s ease,transform .42s var(--ease)}
html.js:not(.reduced-motion) .clients-grid li.is-leaving>img{opacity:0;transform:translateY(-7px)}
html.js:not(.reduced-motion) .clients-grid li.is-entering>img{opacity:0;transform:translateY(7px);transition:none}
/* Draws the linked card's focus ring around its media box; the ring on
   the <a> itself is suppressed above. The ring reaches 8px past the media,
   3px of stroke at a 5px offset, and the block margin keeps that reach on
   screen: shift tabbing back onto this card from the Pause control used to
   scroll the media flush to the viewport top and leave the top stroke above
   it. 12px is the same margin the home page's cards carry. */
.project-card--link{scroll-margin-block:12px}
.project-card--link:focus-visible .project-card-media{outline:3px solid var(--accent);outline-offset:5px}

.page-pointer{padding:0 var(--gutter) clamp(64px,6.667vw,128px);font-family:var(--mono);font-size:clamp(16px,1.042vw,20px);line-height:1.35;color:var(--ink-soft)}
.page-pointer a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.28em;transition:color .3s ease}
@media (hover:hover){.page-pointer a:hover{color:var(--ink)}}
.page-pointer a:focus-visible{color:var(--ink)}

.reading-intro{padding:0 var(--gutter) clamp(96px,10.417vw,200px)}
.reading-grid{
  display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:clamp(48px,6.25vw,112px) var(--gap);
  list-style:none;
}
.reading-card{min-width:0}
.reading-card figure{margin:0}
.reading-cover{position:relative;overflow:hidden;aspect-ratio:1;border:1px solid var(--rule);border-radius:clamp(8px,.625vw,12px);background:var(--ground)}
.reading-cover img{display:block;width:100%;height:100%;object-fit:cover}
.reading-card figcaption{padding-top:clamp(16px,1.25vw,24px)}
.reading-title{font-size:clamp(18px,1.458vw,28px);font-weight:500;line-height:1.25;letter-spacing:0;text-wrap:pretty}
.reading-author{margin-top:8px;font-family:var(--mono);font-size:clamp(14px,.833vw,16px);line-height:1.35;color:var(--ink-soft)}
.venture-list{list-style:none;border-top:1px solid var(--rule)}

.venture-statement{
  padding:clamp(96px,10.417vw,200px) var(--gutter);
  background:var(--paper);
  color:var(--ink);
}
.venture-statement p{max-width:19ch;font-size:clamp(48px,6.25vw,120px);line-height:1.06;letter-spacing:-.03em;text-wrap:pretty}
.venture-statement strong{font-weight:500;color:var(--accent-ink)}
.venture-list-wrap{padding:clamp(96px,10.417vw,200px) var(--gutter)}

/* The list ends on the grid edge, where the title, the deck and the footer heading
   end. So did the status column, and because a status was set right it ended there
   too, in the 34px the fixed menu trigger occupies: "RIP" landed under the two bars
   whole, and "Acquired by New Alchemy Distilling" was struck through its last three
   letters, four times in one scroll, on the only news the page carries.

   The statuses read left now, off a track narrowed from 294px to 228px, which is the
   same way they are set at 767 and below and the way the other two columns are set at
   every width. The longest of them takes two lines, and swept from 768 to 1920 no
   status comes within 34px of the trigger at any width. What the column gives up is
   the phantom right rail it drew on the seventeen rows that carry no status at all. */
.venture-row{
  display:grid;
  grid-template-columns:minmax(190px,1.05fr) minmax(0,.85fr) minmax(0,.5fr);
  gap:var(--gap);
  align-items:baseline;
  padding:clamp(24px,2.5vw,48px) 0;
  border-bottom:1px solid var(--rule);
}
.venture-name{font-size:clamp(34px,3.333vw,64px);line-height:1.05;letter-spacing:-.02em}
/* Fourteen of the twenty one companies are still trading, and those rows
   carry a link out to them. The link is the name, not the row: a row is a
   baseline grid of three columns and a whole row link would have had to
   rebuild that grid inside an <a>, and the name is already the widest and
   tallest target in it.

   It states itself the way every other outward link on the site states
   itself, with the mark and the sr only note naming the host, and it is
   underlined at rest so a row that links is told apart from a row that does
   not without hovering anything.

   The hover answers instead of retreating. It used to take the name from
   near black to soft ink over 300ms and move nothing else, so pointing at a
   link on a page that is fourteen links and nothing else made the link look
   spent, and the same rule ran under the accent focus ring rather than with
   it. The two moves it makes now are both already in the system: the
   underline thickens into accent, which is what an inline link does on
   Contact, and the mark travels up and out, which is what an episode link
   does on About. The name holds its ink. The seven rows with no link gain no
   hover they cannot answer.

   min-height is the site's 44px, so the target holds at the widths where
   the name's own line box is shorter than that. Baseline alignment keeps
   the extra height below the text, which is what leaves the row's three
   columns sitting on one line. */
.venture-link{display:inline-flex;align-items:baseline;gap:.16em;min-height:44px}
.venture-link-label{line-height:1.15;
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:.14em;
  transition:text-decoration-color .3s ease,text-decoration-thickness .3s ease;
}
@media (hover:hover){
  .venture-link:hover .venture-link-label{text-decoration-color:var(--accent);text-decoration-thickness:2px}
  .venture-link:hover .venture-arrow{color:var(--accent-ink);transform:translate(4px,-4px)}
}
.venture-link:focus-visible .venture-link-label{text-decoration-color:var(--accent);text-decoration-thickness:2px}
.venture-link:focus-visible .venture-arrow{color:var(--accent-ink);transform:translate(4px,-4px)}
/* The mark is the size of the name it belongs to, near its x height, so a row
   that goes somewhere says so before the pointer arrives. */
.venture-arrow{font:inherit;color:var(--ink-soft);transition:transform .35s var(--ease),color .35s ease}
.venture-kind,.venture-status{font-family:var(--mono);font-size:clamp(16px,1.042vw,20px);line-height:1.35}
.venture-kind{color:var(--ink-soft)}
/* The trigger is a fixed 44px square sitting on the grid's right edge, and the
   status column is the only type on the site that runs all the way out to that
   edge. The column keeps its track and gives up the corner: the text wraps
   inside the width that is left, so no status can be painted under the bars at
   any width from 768 up. Below that the row stacks and the statuses start at
   the left margin, nowhere near it. */
@media (min-width:768px){.venture-status{padding-right:clamp(44px,3.9vw,56px)}}
/* The exits stay in the page's own ink. A green here would have handed a monochrome
   editorial list a dashboard's good/dead colour semantic, and green is not in the
   system. RIP keeps the accent ink it already had. */
.venture-status--exit{color:var(--ink)}.venture-status--rip{color:var(--accent-ink);letter-spacing:.08em}

/* Contact is not an inverted band, it IS the page, inverted once, for one
   page. Under a naive swap the darkest page on the site would become the
   lightest, so it is pinned instead: the island below holds the light values
   in both schemes, which is what the composer card, the route rules and the
   arrows were always painted with. The site footer sits outside this element
   and stays a band, the way it is on every other page. */
.contact-page{
  --paper:#fff;
  --ink:#0a0a0a;
  --ground:#f2f2f2;
  --rule:#e0e0e0;
  --ink-soft:#666;
  --ink-mid:#666;
  --accent-ink:#b33600;
  --frame:rgba(10,10,10,.08);
  min-height:100dvh;
  padding:clamp(120px,10vw,192px) var(--gutter) clamp(96px,10.417vw,200px);
  background:#0a0a0a;
  color:#fff;
  overflow:hidden;
}
.contact-hero{min-height:clamp(560px,64dvh,820px);display:grid;grid-template-columns:minmax(150px,1fr) minmax(0,2fr);gap:var(--gap);align-content:end;padding-bottom:clamp(80px,8.333vw,160px)}
.contact-kicker,.contact-composer-label,.contact-composer-head>p:last-child,.contact-context-label{font-family:var(--mono)}
.contact-kicker{align-self:start;font-size:clamp(16px,1.042vw,20px);line-height:1.35;color:#999}
.contact-title{max-width:9ch;font-size:clamp(68px,8.4375vw,162px);font-weight:500;line-height:.9;letter-spacing:-.045em;text-wrap:balance}
/* The closing stop, and only the closing stop. This named the element by its
   tag until the heading started arriving line by line: the split wraps every
   rendered line in spans of its own, a bare `span` matched those too, and the
   whole heading turned accent instead of one period. */
.contact-title .contact-stop{color:var(--accent)}
.contact-deck{max-width:34ch;margin-top:clamp(32px,3.333vw,64px);font-size:clamp(22px,2.083vw,40px);line-height:1.2;color:#bdbdbd;text-wrap:balance}
.contact-composer{padding:clamp(28px,3.333vw,64px);border-radius:var(--radius-card);background:var(--paper);color:var(--ink)}
.contact-composer-head{display:flex;justify-content:space-between;gap:32px;padding-bottom:clamp(28px,2.5vw,48px)}
.contact-composer-head p{font-size:clamp(16px,1.042vw,20px);line-height:1.35}
.contact-composer-head>p:last-child{color:var(--ink-soft)}
.contact-composer-head>p+p{text-align:right}
.contact-routes{border-top:1px solid var(--rule)}
/* The type size sits on the row rather than on the label, so the arrow's em
   resolves against the same figure the label is set in. Both grid items then
   carry identical line boxes, which is what keeps align-items:center honest. */
.contact-route{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--gap);align-items:center;padding:clamp(22px,2.083vw,40px) 0;border-bottom:1px solid var(--rule);isolation:isolate;font-size:clamp(28px,3.333vw,64px);line-height:1.02}
.contact-route::before{content:"";position:absolute;inset:0 calc(0px - clamp(28px,3.333vw,64px));z-index:-1;background:var(--accent);transform:scaleY(0);transform-origin:bottom;transition:transform .48s var(--ease)}
.contact-route-arrow{font:inherit;color:var(--ink-soft);transition:color .35s ease,transform .35s var(--ease)}
.contact-route>span:first-child{letter-spacing:-.02em}
@media (max-width:767px){.contact-route>span:first-child{letter-spacing:-.01em}}
@media (hover:hover){.contact-route:hover::before{transform:none}.contact-route:hover .contact-route-arrow{color:var(--ink);transform:translate(5px,-5px)}}
.contact-route:focus-visible{outline:3px solid var(--accent);outline-offset:5px}
/* Hover fills the row with the same accent the ring is drawn in, so a visitor whose
   cursor rests on a row they tabbed to would lose the ring. Black holds on the band. */
.contact-route:hover:focus-visible{outline-color:var(--ink)}
.contact-route:focus-visible .contact-route-arrow{color:var(--ink);transform:translate(5px,-5px)}
.contact-composer-foot{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:32px;align-items:end;padding-top:clamp(48px,5vw,96px)}
.contact-composer-foot>p{max-width:24ch;font-size:clamp(18px,1.458vw,28px);line-height:1.25;color:var(--ink-soft)}
.contact-email{display:inline-flex;align-items:baseline;min-height:44px;font-size:clamp(28px,3.333vw,64px);line-height:1;letter-spacing:-.025em;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.16em}
.contact-email span{display:inline-block;color:var(--accent-ink);transition:transform .35s var(--ease)}
@media (hover:hover){.contact-email:hover span{transform:translate(5px,-5px)}}
.contact-email:focus-visible span{transform:translate(5px,-5px)}
.contact-context{display:grid;grid-template-columns:minmax(150px,1fr) minmax(0,2fr);gap:var(--gap);padding-top:clamp(80px,8.333vw,160px)}
.contact-context-label{font-size:clamp(16px,1.042vw,20px);line-height:1.35;color:#999}
/* The copy beside it starts below its own rule and padding, so the label takes the same
   inset and the two cap lines start together. At 390 the column stacks, so it does not. */
@media (min-width:768px){.contact-context-label{padding-top:clamp(22px,2.083vw,40px)}}
.contact-context-copy{max-width:34ch;padding-top:clamp(22px,2.083vw,40px);border-top:1px solid rgba(255,255,255,.18);font-size:clamp(22px,2.083vw,40px);line-height:1.2;text-wrap:pretty}
/* The page's one inline link sits in white copy at the same weight and colour as the
   sentence around it, so the cursor was carrying the whole signal and a touch visitor
   got none of it. The underline is the signal now, and hover thickens it in accent. */
.contact-context-copy a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.18em;transition:text-decoration-color .3s ease,text-decoration-thickness .3s ease}
@media (hover:hover){.contact-context-copy a:hover{text-decoration-color:var(--accent);text-decoration-thickness:2px}}
.contact-footer{padding-top:clamp(64px,6.25vw,120px)}

@media (max-width:1279px) and (min-width:768px){
  .project-card-media{height:390px}
  .work-row--full .project-card-media{height:auto}
  .reading-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .venture-row{grid-template-columns:minmax(160px,1fr) minmax(0,.8fr) minmax(0,.5fr)}
}

@media (max-width:1599px) and (min-width:1280px){.reading-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}

@media (max-width:767px){
  .page-hero{min-height:414px;padding:0 var(--gutter) 32px}
  .page-title{font-size:64px;line-height:60px;letter-spacing:-2.43px}
  .page-deck{max-width:none;margin-top:32px;font-size:20px;line-height:27px}
  .work-page{padding:0 var(--gutter) 80px}
  .work-row,.work-row--wide-narrow,.work-row--full,.work-row--narrow-wide{display:flex;flex-direction:column;gap:64px;margin-bottom:64px}
  .project-card-media{height:auto;aspect-ratio:1}
  /* A ratio card keeps its desktop crop here unless its JSON entry states
     a second one for this width, where a wide crop can shrink the artwork
     to an unreadable strip. */
  .project-card-media.is-ratio{aspect-ratio:var(--media-ratio-mobile,var(--media-ratio))}
  /* The media is short enough here that a pill inset into its bottom-left
     corner lands on the skateboard, so the control moves to the media's
     top-left corner instead, 12px in from both edges. Across every frame of
     the clip the turtle stays clear of that corner: the nearest artwork in
     the pill's column band starts 35px below the pill's bottom edge. */
  .project-card-video-pause{left:12px;margin-top:12px;transform:none}
  /* The sprite makes the same crossing, for the same reason and to the
     corner opposite the pill. It is a fixed 52x24 in a frame that is 350x197
     here and 280x158 at 320, so the ground it sits on at 1440 has stopped
     being ground: measured against all 38 frames of the clip and its still,
     the box it needs at the bottom right is 77 percent background at 390 and
     64 percent at 320, and what fills the rest is the skateboard's rear
     wheel coming through the pale pixels. The top band is the only ground
     left that holds the mark with a 6px margin, and it holds it whole:
     100 percent at both widths, on every frame. Same 16px inset, same size,
     other corner. */
  .project-card-sprite{top:16px;bottom:auto}
  .project-card-info{display:block;padding-top:20px}
  .project-card-title,.project-card-meta{display:block}
  .project-card-title{font-size:28px;line-height:34px}
  .project-card-meta{margin-top:8px;font-size:16px;text-align:left}
  .reading-intro{padding:0 var(--gutter) 80px}
  .reading-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:48px var(--gap)}
  .reading-card figcaption{padding-top:16px}
  .reading-title{font-size:18px;line-height:23px}
  .reading-author{font-size:14px;line-height:18px;margin-top:8px}
  .venture-statement{padding:80px var(--gutter)}
  .venture-statement p{font-size:48px;line-height:54px}
  .venture-list-wrap{padding:80px var(--gutter)}
  .venture-row{display:block;padding:28px 0}
  .venture-name,.venture-kind,.venture-status{display:block}
  .venture-name{font-size:34px;line-height:38px}
  /* The link is a flex row, and a flex row's second item sits after the first
     item's box rather than after its last word. At 320 "Hydro Wind Energy"
     wraps inside the label, the label's box is still the full column, and the
     mark was stranded 170px past the last letter where it reads as a stray
     tick instead of part of the link. Inline, it follows the word the way
     every other outward mark on the site does. The 44px target the flex box
     was holding is held by padding here: an inline box takes block padding
     into its hit area without moving the line it sits on, and 3px on a 38px
     line is exactly the 44 it had. */
  .venture-link{display:inline;min-height:0;padding-block:3px}
  .venture-arrow{margin-left:.4em}
  .venture-kind,.venture-status{margin-top:12px;font-size:16px;text-align:left}
  .contact-page{padding:112px var(--gutter) 80px}
  .contact-hero{min-height:560px;display:block;padding-bottom:80px}
  .contact-kicker{margin-bottom:64px}
  .contact-title{font-size:64px;line-height:58px;letter-spacing:-2.88px}
  .contact-deck{margin-top:32px;font-size:22px;line-height:28px}
  .contact-composer{padding:24px 20px;border-radius:20px}
  .contact-composer-head{display:block;padding-bottom:28px}
  .contact-composer-head>p:last-child{margin-top:6px}
  .contact-composer-head>p+p{text-align:left}
  .contact-route{grid-template-columns:minmax(0,1fr) auto;gap:12px;padding:22px 0;font-size:28px;line-height:31px}
  .contact-route::before{inset:0 -20px}
  .contact-composer-foot{display:block;padding-top:48px}
  .contact-composer-foot>p{font-size:18px;line-height:24px}
  .contact-email{display:inline-flex;margin-top:28px;font-size:28px;line-height:32px;letter-spacing:-.01em}
  .contact-context{display:block;padding-top:80px}
  .contact-context-label{margin-bottom:24px}
  .contact-context-copy{padding-top:22px;font-size:20px;line-height:27px;text-wrap:pretty}
  .contact-footer{padding-top:64px}
}

/* ------------------------------------------------------------------ *
 * Work's inverted hero. Added by the Bierut round, move 15; nothing
 * else in this file belongs to that move.
 * ------------------------------------------------------------------ */

/* Work leads with what it has to say and files itself underneath, so the
   sentence is the h1 and the word Work is the mono eyebrow above it, set
   in the same label the wall's own group labels are set in.

   The sentence is promoted to the display size a sentence takes on this
   site, the one .story-lede sets About's opening line at, rather than to
   .page-title's own clamp(72px,8.4375vw,162px). A one word title can carry
   162px. This is 238 characters, and set at .page-title's size it measures
   1,117.66px over 10 lines at 1440 and 1,390.92px over 21 lines at 390,
   against the 311.95px and 249.5px it takes here. */
.page-eyebrow{
  font-family:var(--mono);
  font-size:clamp(16px,1.042vw,20px);
  line-height:1.3;
  color:var(--ink-soft);
  margin-bottom:clamp(20px,1.667vw,32px);
}
.page-title--deck{
  font-size:clamp(30px,4.167vw,80px);
  line-height:1.04;
  letter-spacing:-.025em;
  max-width:26ch;
}
@media (max-width:767px){.page-title--deck{letter-spacing:-.015em}}
/* The deck waits for the headline: the h1 lands its last line at about 1.2s, so the
   deck arrives after it instead of before it. */
@media (prefers-reduced-motion:no-preference){.js .contact-deck[data-reveal]{transition-delay:1.1s}}
/* A piece with something true to say past its discipline says it here: the
   page's own sans at the label's size, held to a reading measure so it never
   runs the width of a wide card. */
.project-card-note{display:block;max-width:44ch;margin-top:clamp(10px,.833vw,16px);font-size:clamp(16px,1.042vw,20px);line-height:1.35;color:var(--ink-soft);text-wrap:pretty}

/* The 404 is the interview's one wrong exchange. The page hero pattern as
   Work and Reads use it, the closing mark in the accent like Contact's
   question mark (the two questions asked in Lee's voice share the mark),
   and three pills that are the other pages' opening questions. */
.lost-hero{min-height:clamp(440px,36vw,680px)}
.lost-hero .page-deck{margin-left:0;margin-top:clamp(16px,1.667vw,32px);max-width:32ch}
.lost-stop{color:var(--accent)}
.lost-routes{padding:0 var(--gutter) clamp(96px,10.417vw,200px)}
.lost-list{display:flex;flex-wrap:wrap;gap:12px 16px;list-style:none;margin:0;padding:0}
/* The route label stays on one line down to 320. */
@media (max-width:374px){.contact-route{font-size:22px;line-height:26px}.contact-route>span:first-child{white-space:nowrap}}
/* Flight Line keeps its control inside the picture, bottom left like the
   other loops, whatever the box's height. */
[data-slug="flight-line"] .project-card-video-pause{top:auto;bottom:clamp(16px,2.083vw,40px);left:calc(50% - min(50%,458.5px) + clamp(16px,2.083vw,40px));margin:0;transform:none;z-index:3}
@media (max-width:767px){[data-slug="flight-line"] .project-card-video-pause{left:clamp(16px,2.083vw,40px)}}
