/* ------------------------------------------------------------------
   Geppetto Studio

   Type    Gloock (display) / Archivo (body) / Space Mono (utility)
   Ground  near-black, a hair of blue so it is chosen and not inherited
   Ink     cream, kept bright enough to read at every level
   Accent  blue = Tools, violet = Toys. Interim CI until O's lands.

   Two standing rules this file obeys:
   - No tinted callout panel with a left accent bar. Emphasis is a hairline
     rule and a label, or it is folded into the sentence.
   - The accent never lands on a stray punctuation mark. It marks a category
     (which hand a thing belongs to) or an action. Never decoration.
   ------------------------------------------------------------------ */

:root{
  --ink:#0A0A0B;
  --ink-2:#131317;
  --ink-3:#1B1B21;

  --paper:#F2EDE3;
  --paper-dim:rgba(242,237,227,.80);
  --paper-mid:rgba(242,237,227,.64);
  --paper-faint:rgba(242,237,227,.50);
  --paper-ghost:rgba(242,237,227,.30);
  --rule:rgba(242,237,227,.16);
  --rule-soft:rgba(242,237,227,.09);

  /* the five lines, stepping blue to violet */
  --envision:#58C0F0;
  --engineer:#6FA8FF;
  --enchant:#9E8DFF;
  --enrich:#B98AFF;
  --express:#D98BE8;
  --blue:#6FA8FF;
  --violet:#B38CFF;
  --blue-dim:rgba(111,168,255,.42);
  --violet-dim:rgba(179,140,255,.42);

  --display:'Gloock',Georgia,'Times New Roman',serif;
  --body:'Archivo',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  --mono:'Space Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  --pad:clamp(20px,5vw,64px);
  --max:1280px;
  --ease:cubic-bezier(.16,1,.3,1);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:80px}
body{
  margin:0;background:var(--ink);color:var(--paper);
  font-family:var(--body);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg,video{max-width:100%}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}
.narrow{max-width:66ch}
p{margin:0 0 1.05em}
p:last-child{margin-bottom:0}
h1,h2,h3,h4{margin:0;font-weight:400;text-wrap:balance}
strong{font-weight:600;color:var(--paper)}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--blue);outline-offset:3px}

.lab{font-family:var(--mono);font-size:11px;letter-spacing:.17em;text-transform:uppercase;color:var(--paper-faint)}
.dim{color:var(--paper-mid)}
h2.big{font-family:var(--display);font-size:clamp(29px,4.3vw,46px);line-height:1.06}
h3.mid{font-family:var(--body);font-weight:600;font-size:19px;line-height:1.3;letter-spacing:-.01em}

/* One rule paints every line-coloured element from its data-line attribute. */
[data-line=envision]{--c:var(--envision)}
[data-line=engineer]{--c:var(--engineer)}
[data-line=enchant]{--c:var(--enchant)}
[data-line=enrich]{--c:var(--enrich)}
[data-line=express]{--c:var(--express)}

/* ---------------------------------------------------------- masthead */
.mast{border-bottom:1px solid var(--rule);position:sticky;top:0;z-index:50;
  background:rgba(10,10,11,.94);backdrop-filter:blur(14px)}
.mast .wrap{display:flex;align-items:center;justify-content:space-between;gap:24px;height:66px}
.mast .wm{display:block;width:136px;color:var(--paper);flex:0 0 auto}
.mast .wm svg{display:block;width:100%;height:auto}
.nav{display:flex;gap:clamp(16px,2.6vw,32px);font-family:var(--mono);font-size:11.5px;
  letter-spacing:.14em;text-transform:uppercase}
.nav a{color:var(--paper-faint);padding:6px 0;border-bottom:1px solid transparent;
  transition:color .25s var(--ease),border-color .25s var(--ease)}
.nav a:hover{color:var(--paper)}
.nav a.on{color:var(--paper);border-bottom-color:var(--blue)}
@media(max-width:600px){
  .mast .wrap{height:auto;padding-top:14px;padding-bottom:12px;flex-direction:column;
    align-items:flex-start;gap:11px}
  .nav{flex-wrap:wrap;gap:16px}
}

/* ---------------------------------------------------------- hero */
.hero{padding:clamp(60px,11vw,140px) 0 clamp(44px,6vw,76px);position:relative;overflow:hidden}
.hero .wrap{position:relative;z-index:1}

/* The carved panel. Full bleed behind the headline, masked away on the left so
   it never sits under the type, and held at a weight where it is texture rather
   than picture. The canvas paints nothing until masthead.js decides it should
   run, which is why the opacity is on a data flag and not on the element. */
.mh{position:absolute;inset:0;width:100%;height:100%;display:block;
  pointer-events:none;z-index:0;opacity:0;transition:opacity 1.2s var(--ease);
  -webkit-mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,rgba(0,0,0,.30) 50%,#000 63%);
  mask-image:linear-gradient(90deg,transparent 0%,transparent 34%,rgba(0,0,0,.30) 50%,#000 63%)}
.mh[data-on]{opacity:1}
@media(max-width:760px){.mh{display:none}}
.hero.short{padding:clamp(48px,8vw,96px) 0 clamp(28px,4vw,48px)}
.hero h1{font-family:var(--display);font-size:clamp(42px,8.4vw,102px);line-height:1;
  letter-spacing:-.015em;margin-bottom:.36em}
.hero.short h1{font-size:clamp(36px,6.2vw,68px)}
.hero .sub{max-width:56ch;font-size:clamp(17px,2vw,21px);color:var(--paper-dim);line-height:1.55}
.heroact{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(30px,4vw,44px)}

.cta{display:inline-block;font-family:var(--mono);font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;padding:13px 20px;border:1px solid var(--blue);color:var(--blue);
  transition:background .25s var(--ease),color .25s var(--ease)}
.cta:hover{background:var(--blue);color:var(--ink)}
.cta.ghost{border-color:var(--rule);color:var(--paper-dim)}
.cta.ghost:hover{background:transparent;border-color:var(--paper-ghost);color:var(--paper)}
.cta.off{border-color:var(--rule);color:var(--paper-faint);cursor:default}
.cta.off:hover{background:transparent;color:var(--paper-faint)}

/* ---------------------------------------------------------- sections */
.sec{padding:clamp(50px,7vw,96px) 0;border-top:1px solid var(--rule)}
.sechead{display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;margin-bottom:clamp(18px,2.6vw,28px)}
.sechead .more{margin-left:auto;color:var(--blue)}
.closer{background:var(--ink-2)}
.closer .big{margin-bottom:.5em}

/* ---------------------------------------------------------- two hands */
.hands{display:grid;gap:clamp(30px,5vw,52px);margin-top:8px}
@media(min-width:900px){
  .hands{grid-template-columns:1fr 1fr;gap:0}
  .hands>*:first-child{padding-right:clamp(28px,4vw,52px);border-right:1px solid var(--rule)}
  .hands>*:last-child{padding-left:clamp(28px,4vw,52px)}
}
.handhead{display:flex;align-items:center;gap:12px;margin-bottom:8px}
.handhead h2{font-family:var(--display);font-size:clamp(27px,3.5vw,38px);line-height:1}
.handline{color:var(--paper-mid);margin-bottom:24px;max-width:46ch}
.brow{display:block;border-top:1px solid var(--rule);padding:15px 0;
  transition:background .3s var(--ease),padding-left .3s var(--ease)}
.brow:last-of-type{border-bottom:1px solid var(--rule)}
.brow:hover{background:var(--ink-2);padding-left:10px}
.brow .top{display:flex;align-items:baseline;gap:14px}
.brow .ct{margin-left:auto;font-family:var(--mono);font-size:12px;color:var(--paper-faint)}
.brow .q{color:var(--paper-mid);font-size:15px;margin-top:3px;max-width:52ch}

/* ---------------------------------------------------------- jump nav */
.jump{border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
  position:sticky;top:66px;z-index:40;background:rgba(10,10,11,.95);backdrop-filter:blur(14px)}
.jump .wrap{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;padding-top:14px;padding-bottom:14px}
.jump a{font-family:var(--mono);font-size:11px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--paper-faint);transition:color .2s var(--ease)}
.jump a:hover{color:var(--paper)}
@media(max-width:600px){.jump{position:static}}

/* ---------------------------------------------------------- cards */
.grid{display:grid;gap:0;border-top:1px solid var(--rule);border-left:1px solid var(--rule)}
@media(min-width:720px){.grid{grid-template-columns:1fr 1fr}}
@media(min-width:1080px){.grid{grid-template-columns:1fr 1fr 1fr}}
.card{background:var(--ink);padding:clamp(18px,2.2vw,26px);display:flex;flex-direction:column;
  border-right:1px solid var(--rule);border-bottom:1px solid var(--rule);
  transition:background .3s var(--ease)}
.card:hover{background:var(--ink-2)}
.cbody{flex:1 1 auto}
.card h3{font-family:var(--display);font-size:26px;line-height:1.1;margin-bottom:9px}
.card .what{color:var(--paper-dim);font-size:15.5px;line-height:1.5;margin-bottom:14px}
.card .does{color:var(--paper-mid);font-size:14px;line-height:1.55;margin-bottom:16px}
.card .does .k{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.15em;
  text-transform:uppercase;margin-bottom:4px}
.card .does .k.tools{color:var(--blue)}
.card .does .k.toys{color:var(--violet)}

.well{aspect-ratio:16/10;border:1px solid var(--rule);background:var(--ink-2);
  position:relative;overflow:hidden;margin-bottom:16px;
  display:flex;align-items:center;justify-content:center;transition:border-color .35s var(--ease)}
.card:hover .well{border-color:var(--paper-ghost)}
.well canvas{position:absolute;inset:0;width:100%;height:100%}
.well img,.well video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* A video card answers a hover by playing its clip. A still had nothing to
   answer with, so on two thirds of the catalogue the gesture read as dead. The
   picture pushes in slowly instead - the same promise the clip makes, that
   staying on a card shows you more of the thing than the card did.

   Slow on the way in and quick on the way out: a long push reads as the picture
   breathing, a long retreat just reads as lag. Only the still moves; a playing
   clip is already the answer and does not need to drift as well. */
.well img{transform-origin:center 42%;transition:transform .5s var(--ease)}

.card:hover .well img:not(.post),.card:focus-visible .well img:not(.post){
  transform:scale(1.07);transition:transform 3.2s cubic-bezier(.18,.7,.3,1)}

@media (prefers-reduced-motion:reduce){
  .card:hover .well img,.card:focus-visible .well img{transform:none}
}

/* img.post is the clip's own first frame, sitting under it. It never pushes:
   the clip that fades over it is not pushing either, and a still that drifted
   for the moment before the video arrived would hand off with a jump.

   The clip is transparent until it is actually running - see catalogue.js. That
   is what keeps a hover from blanking the card while the file loads. */
.well video[data-hover]{opacity:0;transition:opacity .3s var(--ease)}
.well video[data-hover].on{opacity:1}
.well .cap{position:relative;text-align:center;padding:0 14px;
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;line-height:1.8;color:var(--paper-faint)}
.well .cap .need{display:block;color:var(--violet);letter-spacing:.16em;
  text-transform:uppercase;font-size:9px;margin-bottom:5px}

.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;
  padding:4px 9px;border:1px solid var(--rule);color:var(--paper-faint);white-space:nowrap}

/* ---------------------------------------------------------- work page */
.bline{color:var(--paper-mid);max-width:62ch;margin:0 0 clamp(18px,2.4vw,26px);font-size:15.5px}

/* ---------------------------------------------------------- plate page */
.phead{padding:clamp(34px,5vw,60px) 0 clamp(22px,3vw,34px)}
.crumb{display:flex;align-items:center;gap:10px;margin-bottom:clamp(16px,2.4vw,26px);
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase}
.crumb a{color:var(--paper-faint)}
.crumb a:hover{color:var(--paper)}
.crumb span{color:var(--paper-ghost)}
.crumb .rm.tools{color:var(--blue)}
.crumb .rm.toys{color:var(--violet)}
.phead h1{font-family:var(--display);font-size:clamp(38px,6.4vw,74px);line-height:1.02;margin-bottom:.22em}
.phead .lede{font-size:clamp(17px,2vw,21px);color:var(--paper-dim);max-width:56ch;margin-bottom:20px}

/* The hero spans the text column and takes the picture's own proportions, which
   build.py stamps on as an inline aspect-ratio. Two earlier versions were wrong
   in opposite directions: a fixed 16/9 box with object-fit:contain put a border
   around a letterbox (border, gap, then picture), and shrinking the box to the
   picture left the frame narrower than the column, which reads as padding. This
   crops nothing at all for any picture between 5:4 and 3:1, and crops the tall
   ones from the top, where a dashboard keeps its title and its headline row. */
.stage{border:1px solid var(--rule);background:var(--ink-2);aspect-ratio:16/10;
  position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;
  margin:0 0 clamp(28px,4vw,44px)}

/* A canvas has no intrinsic size, so those plates keep the aspect box. */
.stage:has(canvas){aspect-ratio:16/9}
.stage.empty{aspect-ratio:auto;min-height:180px;padding:40px 0}
.stage canvas{position:absolute;inset:0;width:100%;height:100%}
.stage img,.stage video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center top;background:var(--ink)}
.stage .cap{position:relative;text-align:center;padding:0 8%;max-width:60ch;
  font-family:var(--body);font-size:15px;letter-spacing:0;color:var(--paper-mid);line-height:1.6}
.stage .cap .need{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--violet);margin-bottom:10px}

.filmstrip{display:grid;gap:0;border-top:1px solid var(--rule);border-left:1px solid var(--rule);
  margin-bottom:clamp(28px,4vw,44px)}
@media(min-width:720px){.filmstrip{grid-template-columns:1fr 1fr}}
.filmstrip figure{margin:0;background:var(--ink);aspect-ratio:16/10;position:relative;overflow:hidden;
  border-right:1px solid var(--rule);border-bottom:1px solid var(--rule)}

/* A diagram is not a photograph. Photographs are shot with room to lose and crop
   to 16/10 happily; a flowchart cropped to 16/10 loses its title off one edge and
   its caption off the other, which is the part it was drawn to say. So figures
   get their own block, sized by the drawing, never cropped. */
.figures{display:grid;gap:clamp(14px,2vw,22px);margin-bottom:clamp(28px,4vw,44px)}

.figures figure{margin:0;border:1px solid var(--rule);background:var(--ink-2);
  display:flex;align-items:center;justify-content:center;
  padding:clamp(10px,1.6vw,20px)}

.figures img{display:block;width:auto;height:auto;max-width:100%;
  max-height:min(80vh,860px)}
.filmstrip img,.filmstrip video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

.pbody{display:grid;gap:clamp(26px,4vw,44px)}
@media(min-width:900px){.pbody{grid-template-columns:minmax(0,1fr) 280px;gap:0 clamp(40px,5vw,76px)}}
.tsec{border-top:1px solid var(--rule);padding:22px 0}
.tsec:first-child{border-top:0;padding-top:0}
.tsec h4{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-faint);margin-bottom:10px}
.tsec p{max-width:64ch;color:var(--paper-dim)}
.tsec.doing p{color:var(--paper);font-size:18px;line-height:1.6}

.side{border-top:1px solid var(--rule);padding-top:22px;align-self:start}
@media(min-width:900px){.side{position:sticky;top:92px;border-top:0;padding-top:0}}
.srow{border-top:1px solid var(--rule);padding:14px 0}
.srow:first-child{border-top:0;padding-top:0}
.srow .k{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--paper-faint);margin-bottom:5px}
.srow .v{font-size:15px;color:var(--paper)}
.srow .note{font-size:13px;color:var(--paper-mid);margin-top:4px}
.srow .cta{margin-top:2px}

.pager{display:flex;justify-content:space-between;gap:20px;border-top:1px solid var(--rule);
  padding-top:24px;margin-top:clamp(32px,5vw,56px);
  /* and space BELOW it, or the descenders sit on the footer's own rule */
  margin-bottom:clamp(40px,6vw,72px)}
.pager a{max-width:44%}
.pager .k{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--paper-faint);margin-bottom:5px}
.pager .t{font-family:var(--display);font-size:20px;color:var(--paper-mid);transition:color .25s var(--ease)}
.pager a:hover .t{color:var(--paper)}
.pager .r{text-align:right}

/* ---------------------------------------------------------- services */
.steps{display:grid;gap:0;border-top:1px solid var(--rule);border-left:1px solid var(--rule);
  margin-top:clamp(28px,4vw,42px)}
@media(min-width:720px){.steps{grid-template-columns:1fr 1fr}}
@media(min-width:1080px){.steps{grid-template-columns:repeat(4,1fr)}}
.step{background:var(--ink);padding:clamp(20px,2.4vw,28px);
  border-right:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.step .k{font-family:var(--mono);font-size:10px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--blue);margin-bottom:10px}
.step h3{margin-bottom:8px}
.step p{color:var(--paper-mid);font-size:14.5px;line-height:1.55}

/* ---------------------------------------------------------- studio */
/* ---------------------------------------------------------- stack rows */
.stack{border-top:1px solid var(--rule)}
.stack .row{display:grid;gap:5px;padding:19px 0;border-bottom:1px solid var(--rule)}
@media(min-width:760px){.stack .row{grid-template-columns:210px minmax(0,1fr);gap:0 32px;align-items:start}}
.stack .row .k{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--paper-faint);padding-top:4px}
.stack .row .v{color:var(--paper-dim);max-width:66ch}

/* ---------------------------------------------------------- footer */
footer{border-top:1px solid var(--rule);padding:clamp(38px,5vw,64px) 0 clamp(48px,7vw,84px)}
footer .ft{display:flex;justify-content:space-between;gap:28px;flex-wrap:wrap;
  font-size:14px;color:var(--paper-mid);line-height:1.8}
footer a{border-bottom:1px solid var(--rule)}
footer a:hover{color:var(--paper);border-bottom-color:var(--blue)}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}


/* ---------------------------------------------------------- the five lines */
/* Five cells across, one per line. They were full-width stacked rows with a
   coloured tick down the left edge; the tick read as a stray pipe character and
   the stack ate the top of the page. The colour is carried by the verb now. */
.lstrip{display:grid;gap:0;border-top:1px solid var(--rule);border-left:1px solid var(--rule)}
@media(min-width:620px){.lstrip{grid-template-columns:1fr 1fr}}
@media(min-width:1000px){.lstrip{grid-template-columns:repeat(5,1fr)}}
.lcell{background:var(--ink);padding:18px clamp(14px,1.5vw,20px) 22px;
  border-right:1px solid var(--rule);border-bottom:1px solid var(--rule);
  transition:background .3s var(--ease)}
.lcell:hover{background:var(--ink-2)}
.lcell .lverb{font-size:clamp(21px,2vw,26px)}
.lcell .lnoun{display:block;margin-top:6px}
.lcell .lline{font-size:13.5px;line-height:1.55;margin-top:10px;max-width:none}
.ltop{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.lverb{font-family:var(--display);font-size:clamp(26px,3.4vw,36px);line-height:1;color:var(--c)}
.lnoun{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-faint)}
.ltop .ct,.lhead .ct{margin-left:auto;font-family:var(--mono);font-size:12px;color:var(--paper-faint)}
.lline{color:var(--paper-dim);margin:7px 0 0;max-width:62ch;font-size:16px}
.lgroups{font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--paper-faint);
  margin:9px 0 0}

.lsec .lhead{display:flex;align-items:center;gap:14px;margin-bottom:6px}
.lsec .lhead .big{color:var(--c)}
.lsec .lline{margin-bottom:clamp(26px,3.6vw,42px)}
.bgroup{margin-bottom:clamp(34px,4.5vw,58px)}
.bgroup:last-child{margin-bottom:0}
.bgroup .bhead{display:flex;align-items:baseline;gap:14px;margin-bottom:4px}
.bgroup .bhead .ct{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--paper-faint)}

.bgroup .bhead h3{color:var(--paper)}
.jump a[data-line]{color:var(--c);opacity:.72}
.jump a[data-line]:hover{opacity:1}
.stack .row .k[data-line]{color:var(--c)}
.card .does .k[data-line]{color:var(--c)}
.crumb .rm[data-line]{color:var(--c)}


/* ---------------------------------------------------------- studio portrait */
.pfolio{padding:clamp(36px,6vw,84px) 0 clamp(30px,4vw,56px)}
.pgrid{display:grid;gap:clamp(28px,4vw,56px);align-items:center}
@media(min-width:860px){.pgrid{grid-template-columns:minmax(0,420px) minmax(0,1fr)}}
.portrait{margin:0;position:relative;border:1px solid var(--rule);overflow:hidden;
  background:var(--ink-2)}
.portrait img{display:block;width:100%;height:auto}
/* The headshot is lit warm on a grey wall; hold it back a touch so it sits in the page
   rather than glowing off it, and bring it up on hover. */
.portrait img{filter:saturate(.82) contrast(1.04) brightness(.94);
  transition:filter .5s var(--ease)}
.portrait:hover img{filter:saturate(1) contrast(1) brightness(1)}
.pintro .lab{display:block;margin-bottom:16px}
.pintro h1{font-family:var(--display);font-size:clamp(34px,5.4vw,64px);line-height:1.02;
  letter-spacing:-.015em;margin-bottom:.4em}
.pintro .mid-name{color:var(--engineer)}
.pintro .sub{font-size:clamp(16.5px,1.9vw,20px);color:var(--paper-dim);max-width:44ch;line-height:1.55}
.bio p{font-size:17.5px}
.bio p+p{margin-top:0}
