A Typographic Refactoring

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

On Giant Robots, we’ve switched from using Skolar and Proxima Nova via Typekit for our body and header typefaces, to Chronicle Text and Sentinel via the typography.com cloud. We’ve adjusted line-height, weights, vertical rhythm, and the CSS we use to render the type. Typographers sweat every curve and corner when designing a typeface, and as designers we need to take equal care in selecting them. This article explains the intent and technical reasoning behind each adjustment, beginning with the choice of the new typefaces.

Body Text — What Makes Chronicle Text Better?

The first thing to notice is Chronicle Text’s larger size — it’s the main reason the typeface appears more readable, but both faces are set to 16px. Skolar looks smaller because its ascenders and descenders don’t reach the boundaries of its glyph’s bounding box — each glyph in a typeface is contained within a bounding box, the digital descendant of the sort. When type was made in metal, each glyph of the same size was cast into a sort of the same size; Chronicle Text would have just filled more of the sort than Skolar.

Chronicle Text also has a large x-height, the height of its lowercase letters. It’s proportionally taller than Skolar’s x-height, and still clearly differentiated from the uppercase. More height means larger letters and larger counter forms, the enclosed or partially enclosed spaces within a letter. At small sizes, the lines around a counter can blend together due to anti-aliasing and create a fuzzy texture; note the small counter on the letter “e” in “Toomey”.

Skolar is very curvy, you can see how much more consistently vertical and horizontal Chronicle Text’s strokes are in “vim” vs the arched feet of Skolar’s “vim” — the “v” even has an ink trap. This may reproduce well at medium sizes or in print, but on screen at 16px, these details are obscured by pixelated approximations.

Chronicle Text’s lines look closer together due to its larger apparent size, so its line-height needed to be increased. Line-height is somewhat dependent on font weight, x-height, medium, and preference, but a good guideline is to avoid creating a lined texture with too large a line-height, and a dense texture with too little — if the space between lines is smaller than the space between words, it’s definitely too small.

Typography.com allows you to select OpenType features à la carte like kerning pairs and ligatures, but you need to enable text-rendering: optimizeLegibility in your CSS to render these features. There’s a cost to render time relative to the amount of text, but we think it’s worthwhile since our articles are usually short to medium length.

Subheads — Standing Out and Pairing Up

We previously used an all caps Proxima Nova for our subheads. Ellen Lupton (among others) has a rule of thumb to never change more than two things to differentiate a piece of type. The Proxima Nova subhead was larger, bolder, a different case, a separate typeface, and had a different bottom margin than the paragraph text. It’s been replaced by Sentinel Bold, which only changes the typeface and the weight. Sentinel is a beautiful almost-slab-serif from Hoefler & Frere-Jones, and a recommended combination with Chronicle Text. We almost used Chronicle Text Bold for subheads, but decided to go with H&FJ’s recommendation. Sentinel, like slab serifs in general, is built to be bold, so less detail is lost at heavier weights.

Typographic choices are often a matter of taste, and the choice between Sentinel Bold and Chronicle Text Bold is an example. Differences can be small when comparing two typefaces of the same category, and sometimes you have to rely on taste or some other meta information to come to a conclusion. In their rebranding of the Whitney Museum, Experimental Jetset used Neue Haas Grotesk, the product of a collaboration between Swiss and New York type designers, mimicking the collaborations behind the museum’s collection and architecture. In this case, the typeface’s history, not just its appearance, played heavily into the designer’s choice.

Thin Weights and Headlines

H&FJ makes beautiful headline typefaces, but many of them have specific personalities that will end up dominating a page if you’re not careful. We want our headlines to be obvious but unobtrusive, so we chose to keep Proxima Nova at a heavier weight. We didn’t use a light weight anywhere except the headline previously, and it displayed poorly on older and Windows systems. Increasing its weight improves the site’s consistency, scannability, and the reading experience for many of our visitors.

Vertical Rhythm

Vertical rhythm encompasses a lot of ideas on layout, all of which revolve around the vertical spacing of items and type on a page. Print designers work with the finite widths and heights of paper. To avoid overrun, print designers have to use a vertical grid just like most websites use a horizontal one, this ensures that each page ends in the same place, and any two pages on the same system look aligned side-by-side. Since we have no control over our canvas on the web, many of these paradigms no longer make sense. Line heights need to be taller to accommodate longer lines, and the page is arbitrarily cut off in the viewport, vertically and horizontally. The idea of vertical consistency should apply in some places, but not others.

Our sidebar showing tags and the author was previously unaligned with our content; this is easily passed over, but becomes obviously wrong once noticed. In the new design, all the side-by-side pieces are aligned to a vertical grid.

Wrap-up

"I think it’s important for us not to be under the illusion that anybody else cares"
Saul Bass on making beautiful work

Tens (sometimes hundreds) of thousands of people read our blog every month, and although very few of them likely noticed the change, we feel an obligation to create a great reading experience designed with intent down to every detail. If you have a question on anything mentioned, or notice anything unmentioned, tweet @thoughtbot.

Written by Edwin Morris

Episode #408 - October 4th, 2013

Posted 7 months back at Ruby5

Better layouts with Nestive, a Ruby port of the Resty tool, more extensible exception handling with rescue_from, flexible bindings for IRB, compliance with Sandi's rules of Ruby, and Faye 1.0 all in this episode of the Ruby5!

Listen to this episode on Ruby5

This episode is sponsored by New Relic
New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.

Nestive
Want more control over template injection that what `content_for` affords? Take a look at nestive!

Ruby Resty
Now there is a Ruby implementation of the Resty command-line tool!

rescue_from
Rails has a handy but little-known macro called rescue_from. Learn about it in this blog post!

binding.repl
Pry has long held the monopoly on runtime invocation, but now binding.repl allows you to get similar functionality in IRB, Ripl, and Pry.

Sandi-Meter
Sandi Metz' rules have become pretty famous as of late, this tool allows you to visualize your complicance to them.

Faye 1.0
Faye 1.0 was released! Your favorite pub/sub library now with promises!

Chrome for Android gets full-screen web apps

Posted 7 months back at mir.aculo.us - Home

Mobile web apps just got even cooler, with Chrome for Android adding support for full-screen, saved to home screen web apps, making them first-class app citizens like on iOS.

Read about how to implement this on Google’s Developer Docs.

BubbleConf 2013 Recap (Director’s Cut)

Posted 7 months back at Phusion Corporate Blog

BubbleConf is a conference on tech, design and entrepreneurship by Nedap and Phusion. It is targetted towards startups and the 2013 edition was held in the Beurs van Berlage in Amsterdam on September 27th. It had close to 400 people from all over the world attend and we were blown away once again by the positive energy we received from the crowd.

We can’t even describe how much it meant for us to have you all come out to our venue that day: you folks really were the icing on the cake for us in working on this conference for the past 8 months or so. The atmosphere was warm and welcoming, and we couldn’t be happier to have shared a day filled with inspiration with all of you.

But all good things have to come to an end, and in wrapping up BubbleConf 2013, we’d like to list the photos, videos and reviews that were taken on that day.

Videos

The guys over at TayloredTales did an amazing job at capturing the day itself. The first video should give you an idea of what BubbleConf 2013 was like from an attendee’s point of view.

<iframe src="//player.vimeo.com/video/75995428" width="640" height="360" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

The videos of the talks themselves that were held in the main room will be put up shortly as well. Please stay tuned, you really don’t want to miss out any of them!

Pics or it didn’t happen

Photos by Cuong Bui. Be sure to check out the entire gallery.











Reviews

Survey

If you’ve attended BubbleConf, please let us know what we got right/wrong, we’d love to know! You should have received a link to our survey via the mailinglist about this, but feel free to send in happy thoughts to us via email!

Stay Classy Amsterdam!

BubbleConf was born out of the desire to have a conference that would cater to startups in a multifaceted way by covering the topics we felt were most important for tech startups: tech, design and entrepreneurship. By putting these topics in wedlock, we had hoped to be able to bring together as many people from different fields to come share their war stories with one another. And possibly even form new startups. We felt there were so many diamonds in the rough in the Netherlands that really deserved a spot in the limelight: they would be able to do amazing things when given the right opportunities.

We’re incredibly excited to see that we have at least been able to accomplish a few of those goals that we set out to achieve when looking back at BubbleConf. We really hope our attendees will continue working on their projects and work towards putting the Netherlands/Europe on the startup map. We will certainly continue to do so with our own startup Phusion ;)

As for a 2014 edition of BubbleConf, that might be a bit too early to think about at this point: everyone involved from Nedap and Phusion are still recovering from the 8 months or so of time they put into organizing BubbleConf 2013. Regardless of whether or not there will be a 2014 edition, we hope you have enjoyed BubbleConf 2012 and 2013: we certainly did!

New ebook: Geocoding on Rails, Your Map to Geocoding Rails Applications

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

If you’ve worked on a web application in the past eight years or so, there’s a good chance you’ve written mapping or geocoding functionality. I’ve worked on multiple Rails applications in the past year which geocode certain pieces of data; each time, I had to remind myself which Ruby gems to use for searching, how to retrieve coordinate information from the browser, and the correct way to write tests for the behavior I wanted to add.

Introducing “Geocoding on Rails”

Today, I’m proud to announce thoughtbot’s newest publication, Geocoding on Rails, written by Laila Winner and myself. The 60 page ebook covers the following topics:

  • Which gems to use based on application requirements
  • How to build out a Rails application which geocodes data
  • How to use the W3C Geolocation and Google Geocoding APIs to reverse-geocode at a browser level
  • How to speed up responses with caching
  • How to test virtually every aspect of the app as it’s built

Includes the source code of a Rails app with easy to read code and high performing geospatial queries

The book includes a fully functional Rails application written in Rails 4 and Ruby 2 with a full test suite of RSpec acceptance tests (using Capybara), unit tests, and CoffeeScript unit tests using Konacha. Also included is a dataset with almost 11,000 Starbucks locations to get you started.

As with all our books, you initial purchase of the book gets you all future updates we make. We even give you access to the GitHub repository.

Get your copy of Geocoding on Rails today!

Available for Free with Learn Prime

If Geocoding on Rails interests you, you may want to check out our subscription service, Learn Prime.

For as little as $29/month, you get ongoing access to our books like Geocoding on Rails, screencasts, exclusive subscriber content, a forum to ask thoughtbot your toughest Ruby, Rails, and refactoring questions, and more. We also provide online workshops, and one-on-one mentoring.

Backbone.js, JSON API, and Relational Data: A Primer

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

While following patterns suggested by JSON API with Ember may be straightforward, little documentation exists for its usage within Backbone.js. With feed-readers popular in the past few months, I’ve decided to demonstrate how to follow the specification defined by JSON API to provide data to a Backbone application; namely, how to populate collections and models with associated data.

The Application API

Let’s start with the Rails application’s API implementation, which is fairly straightforward:

# app/controllers/api/feeds_controller.rb
class Api::FeedsController < ApplicationController
  respond_to :json

  def index
    feeds = Feed.rss
    respond_with feeds, each_serializer: FeedSerializer
  end

  def show
    feeds = Feed.where(id: params[:id]).rss
    respond_with feeds, each_serializer: FeedSerializer
  end
end

The controller is using ActiveModel::Serializers to generate JSON responses for both Feed and Entry objects.

# app/serializers/feed_serializer.rb
class FeedSerializer < ActiveModel::Serializer
  attributes :id, :title, :url, :feed_url, :etag, :description

  has_many :entries, serializer: EntrySerializer,
    embed: :ids, include: true, key: :entries
end

# app/serializers/entry_serializer.rb
class EntrySerializer < ActiveModel::Serializer
  attributes :id, :url, :title, :published, :author, :content

  def content
    object.content || object.summary
  end
end

These classes result in a JSON structure like this when retrieving api/feeds.json:

{
  "entries"=> [
    {"id"=>"a9f9283c34af5c6f7ab6fc461e5ba8ee",
      "url"=> "",
      "title"=> "",
      "published"=>"2013-09-22T18:25:02Z",
      "author"=>"",
      "content"=>""},
    {"id"=>"e805ed779257cd0d1f69b747fb01b591",
      "url"=> "",
      "title"=>"",
      "published"=>"2013-09-22T18:16:06Z",
      "author"=>"",
      "content"=> ""},
    {"id"=>"6601a53c98e690a46b8bbeca46a6904a",
      "url"=>"",
      "title"=>"",
      "published"=>"2013-08-30T15:16:03Z",
      "author"=>"",
      "content"=> ""}
  ],
  "feeds"=> [
    {"id"=>"e74786582200ea744c0d0a72fc616199",
      "title"=>"",
      "url"=>"",
      "feed_url"=>"",
      "etag"=>"\"4762e3773a5404de50dcfaef49697460\"",
      "description"=>"",
      "entries"=> ["a9f9283c34af5c6f7ab6fc461e5ba8ee", "e805ed779257cd0d1f69b747fb01b591"]},
    {"id"=>"1a33061dccfdc80aff5ce04df9591f6e",
      "title"=>"",
      "url"=>"",
      "feed_url"=>"",
      "etag"=>"\"7896d-eaef-4e6c07d3b7300\"",
      "description"=> "",
      "entries" => ["6601a53c98e690a46b8bbeca46a6904a"]}
  ]
}

There are two keys, feeds and entries, returned. Each item within feeds maintains a reference to its list of entry IDs, which will need to be associated when building up the structure within the Backbone collection.

The Backbone Application

Let’s look at the Backbone collection:

# app/assets/javascripts/collections/feeds.coffee
class @App.Collections.Feeds extends Backbone.Collection
  model: App.Models.Feed
  url: '/api/feeds'
  parse: (response) =>
    @entries = response.entries
    response.feeds

parse is doing most of the heavy lifting here, assigning a property entries to the collection (to be used later) and returning response.feeds, which gets assigned internally to models().

With the collection of feeds knowing about entries, it becomes the responsibility of each App.Models.Feed to correctly reference each App.Models.Entry:

# app/assets/javascripts/models/feed.coffee
class @App.Models.Feed extends Backbone.RelationalModel
  relations: [
    {
      type: Backbone.HasMany
      relatedModel: 'App.Models.Entry'
      collectionType: 'App.Collections.Entries'
      key: 'entries'
    }
  ]

  initialize: ->
    @set 'entries', _.filter @collection.entries, (entry) =>
      _.indexOf(@get('entries'), entry.id) >= 0

  title: ->
    @get 'title'

  description: ->
    @get 'description'

  entries: ->
    @get 'entries'

Within App.Models.Feed's initialize, we bootstrap the JSON data from the collection’s entries into the entries attribute on the App.Models.Feed model. Because the entries array may contain IDs of entries for other feeds, however, we filter out everything that doesn’t belong. Once the records have been filtered correctly, Backbone-relational.js handles the rest.

For reference, here are App.Models.Entry and App.Collections.Entries:

# app/assets/javascripts/models/entry.coffee
class @FeedMe.Models.Entry extends Backbone.RelationalModel
  title: ->
    @get 'title'

  url: ->
    @get 'url'

  published: ->
    @get 'published'

  content: ->
    @get 'content'

  author: ->
    @get 'author'

# app/assets/javascripts/collections/entries.coffee
class @FeedMe.Collections.Entries extends Backbone.Collection
  model: FeedMe.Models.Entry

Results

While there is a bit of wiring involved, it’s fairly easy to set up a Backbone app to interact with associated data provided by an API following the patterns of JSON API. If you’re using Marionette.js to handle associated data and have examples to share, tweet @thoughtbot to let us know!

Learn More About Backbone.js

If you’re interested in learning how to build Backbone apps, I recommend you check out thoughtbot’s book Backbone.js on Rails, which includes an example app in addition to the book itself.

Go grab a copy today!

Additionally, if you’re a Learn Prime subscriber, you’ll get access to the book for free. Learn Prime starts at $29/month and grants subscribers access to our books, screencasts, exclusive subscriber content, and more!

Build Phase Podcast Episode 10: Grandmas Are Twice as Efficient

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Build Phase Podcast Episode 10: Grandmas Are Twice as Efficient :

Gordon Fontenot and Mark Adams talk about Cookie Clicker and review listener feedback.

Giant Robots Podcast Episode 68: Simplicity and Elegance

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Giant Robots Podcast Episode 68: Simplicity and Elegance:

Ben Orenstein and Paul Farnell, CEO of Litmus, talk about starting up, business practices, and Litmus.

Lighthouse goodness

Posted 7 months back at entp hoth blog - Home

Howdy Lighthouse users! I come bearer of good news! We deployed a couple updates in the last few days. It particularly touches spam on public projects, but there are a number of other goodies that should make everyone happier.

Spam

A number of prominent public projects have been suffering a lot from spam, and it was time to alleviate the pain. So here are the changes we made:

  • If you are an account admin, you can now manage spam across your account by simply searching for spam:1. This will lead you to a dedicated view where you can mass delete/restore/preview content marked as spam, across all your projects. For big accounts, the first load may take a while, but after that it should work pretty well. If you have spammers with hundreds of post, we can clean them up for you, just email us at support@lighthouseapp.com.

  • We used to delete comments with a really high spam score. This was originally intended to limit spam but we found out the spam detection had some issues, and this resulted in false positives. Well no more! All content is created and kept, and you can review it on the spam page. This was the number one complaint we had, and it should now be a thing of the past.

  • As your mark content as spam/ham, we get notifications based on a number of parameters and heuristics. This means that in many cases, we’ll see when a legitimate user has been flagged as spam incorrectly, and when a spammer seems to be able to post unpunished. We’ll take care of those users appropriately so you don’t have to, and this should make for a smoother experience for everyone.

You can find more information on the KB: http://help.lighthouseapp.com/kb/project-management/managing-spam

Emails

  • It was a long time coming, but our notifications are now HTML emails. The style is simple and light, just like in Tender, and it should greatly improved readability.

  • Modifications to existing comments will now generate notifications. I realize this may not be ideal for a few users who edit comments a lot (and I apologize to them), but for the vast majority of users, this is a good thing. Many small changes on tickets went unnoticed before because there was no email.

  • The “Show me” dropdown now include every member of a project when on a project page. Before, it only included account admins. So if you have a lot of project members, and you want to see what they are into, this should help you out.

Conclusion

I hope this improves your Lighthouse experience, and I’ll be happy to hear your thoughts.

Cheers!

Episode #407 – October 1st, 2013

Posted 7 months back at Ruby5

Aimee and Gregg do Ruby together for the first time, covering Ruby 2.1, pairing with tmux, closures, gem config, executable web apps, a simple git branching model, and CI with sphero.

Listen to this episode on Ruby5

This episode is sponsored by Top Ruby Jobs
If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.

Ruby 2.1 Walkthrough
With the release of the first Ruby 2.1 preview last week, Konstantin Haase wrote up a great overview of what’s new.

Remote pairing and browser sharing with tmux
We do a lot of pair-programming here at Envy Labs, and recently one of our developers, Matthew Closson, wrote up a blog post about remote pairing and browser sharing with tmux.

Closures in Ruby: Blocks, Procs and Lambdas
This weekend I stumbled upon a great blog post by Ahsan Sharafuddin which has a thorough guide to Closures in Ruby: covering Blocks, Procs, and Lambdas.

Config and Generators in Gems
If you’ve ever been interested in writing your own gem, Lindsey Bieda wrote up a great introduction to writing configuration generators.

Creating executable web applications with ruby
Do you ever wish you could run a command line which runs a web application? Alexander Shvets shows you how to get it setup.

A simple git branching model
If you’ve ever collaborated on a project using git, you have probably run into some not-so-great workflows. Fortunately, Juan Batiz-Benet has written up a simple git branching model that’s pretty easy to follow.

Check your build status by Sphero
You may have heard of Sphero. It’s that small spherical ball that you can control with your iPhone, and play games with it. Alexey Vasiliev wrote a script to show you how to check you build status and have your Sphero react accordingly.

Episode #406 – September 27th, 2013

Posted 7 months back at Ruby5

Well, better late than never! The podcast was recorded, but the lack of bandwidth at a campsite delayed the publication. Still, we have interesting news on a/b testing tools, encryption with Snowden, poking fun at Canada, and other news in this RubyLoco-powered Ruby5.

Listen to this episode on Ruby5

This episode is sponsored by New Relic
You should be using New Relic by now, but don't forget to regularly check out their blog! We recently saw their infographic where they take stats from hundreds of thousands of iphone app users and torture the numbers to confess to some pretty interesting stuff. You should check it out!

Lambdas in Case
Bozhidar Batsov wrote a blog post with some examples of using procs and lambdas as the conditions for when branches. Its an option for expressive code that you might nt be using, so you should check it out!

Rocker-Box
Rocker-Box is a gem by Nick Esposito that lets you a/b test static pages.

Snowden
Snowden is a gem published by cambridge healthcare for managing encrypted search indices. It can do fuzzy search on the encrypted indices and supports pluggable backends. they got the idea from the published paper “Fuzzy Keyword Search over Encrypted Data in Cloud Computing”

Canada Gem
Don't blame us, we just report the news. If you know anyone from Canada, poke some fun at them with this little doozy.

Our Community's Future
A little bit of a soapbox rant on where to look for new ideas to continue to breathe new life into our community. Interesting, but the Clojure community should be on the short list he mentions!

Retrospective: High Performance Browser Networking

Posted 7 months back at igvita.com

This past Friday the first print copies of High Performance Browser Networking landed on my desk. After carrying it in my head for the past year, it was an interesting feeling to finally hold something tangible: a sense of relief, excitement, and "man, I hope they like it."

With the book in hand, I could finally put a mental checkmark on it, which also prompted a retrospective into the entire process from start to finish. A self-professed quantified self geek that I am, it should not surprise you to know that I've kept a detailed log along the way. Not knowing what I was getting myself into when I first started, it's interesting to now look back at the lessons learned and patterns that emerged. Let's take a look...

Writing HPBN by the numbers

Chapter Writing (hours) Research + Review (hours) Words
41250690,056
Preface21900
Primer on Latency and Bandwidth752,930
Building Blocks of TCP25155,533
Building Blocks of UDP1282,759
Transport Layer Security (TLS)27387,362
Introduction to Wireless Networks10162,763
WiFi7212,590
Mobile Networks6414311,133
Optimizing for Mobile Networks9214,015
Brief History of HTTP762,475
Primer on Web Performance37164,943
HTTP 1.X28155,156
HTTP 2.X37466,464
Optimizing Application Delivery23154,776
Primer on Browser Networking531,618
XMLHttpRequest16145,109
Server-Sent Events (SSE)6111,681
WebSocket38255,583
WebRTC528712,266

In total, I've spent 412 hours staring into my text editor. This number is exact and based on RescueTime logging the foreground window. The research and review time was a harder one to track, since that involved online and offline time (e.g., reading books, research papers, etc.), but I'm confident of the data: writing time resolution is down to minutes, research and review are down to hours, with a total of 918 hours and 90,056 words.

Alas, writing, research, and review are not the end of it. RescueTime tells me that I've spent 46 hours iterating on feedback from early release iterations - discussions, followup, and so on. I've also logged 29 hours in OmniGraffle, creating and adjusting all the diagrams. Finally, I've spent 9 hours fiddling with the tooling - waiting for builds, configuration, debugging errors, etc. All said and done the grand total adds up to just north of 1,000 hours.

Taking it a day at a time

The whole process from getting the nod from the O'Reilly team, to handing off the content to the production crew took 381 days. In that time, my Git repository tells me that I've had 239 days with at least one commit, plus another 32 days where I didn't touch the repo but still spent time working on the book: 271 active days.

I wouldn't call myself a morning person, but writing in the evenings after a full day at work didn't yield the results I wanted. Instead, as the Git commit log shows, I've tried to carve out a dedicated chunk of time each morning. Typically, that meant 7-9AM on weekdays, and 8-noon on weekends (hence the commit spikes between 12-2PM). The drop in number of commits on Tuesday/Thursday is interesting as that was not intentional - looking back it seems to coincide with higher amount of time spent on research and review.

  • 1.72 hours (writing) / day
  • 1.59 pages / day or 0.92 pages / hour
  • 377 words / day or 219 words / hour

Reminding myself that a "shitty first draft" should be the initial goal was a continuous struggle - 200 words/hour is not a fast clip. Then again, seeing another page or two appear at the end of the PDF was a great reward and all I was aiming for each day. My best day ever was 11 pages — a full weeks work in one day! Of course, then I had to rewrite most of it. Conversely, there were plenty of days where all I managed was a paragraph or two.

Lessons learned along the way

Collecting above data along the way proved to be a valuable feedback mechanism - e.g. focusing on working in the mornings, setting realistic expectations, and tracking progress. Case in point, my early delivery estimates were off by months and by the end I could project down to a week. Also, a few other interesting lessons learned:

  • Consistency is key - things get in the way (e.g. work, travel, etc.), but showing up is key.
  • Getting early feedback is invaluable - O'Reilly's Atlas toolchain worked really well.
  • Incremental milestones and deadlines are a necessary forcing function.
  • Nothing helps clarify your thinking and expose the flaws and inconsistencies than attempting to put it down on paper in simple terms.

Last point in particular is one of the reasons I keep this blog - writing helps me understand the topic in a way that reading and talking about it never does. Working on HPBN forced me to clarify a lot of important details I've overlooked before; relearn topics I thought I understood but really didn't; learn a lot of new material.

With all that said, ultimately you'll have to be the judge on whether the book actually delivers - hope you learn a useful thing or two as well! Speaking of which, do check it out, and if you do, please leave a review!

New thoughtbot.com

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

We’re pleased to announce the redesign of thoughtbot.com!

People generally know us as a Ruby on Rails consultancy. While true, we are a well-balanced team of designers, web (Rails) developers, and mobile (iOS) developers.

Therefore, we redesigned the site with a focus on aesthetics to better provide future clients an accurate view of our capabilities by:

  • providing a profound visual experience
  • maintaining exceptionally smooth interactions
  • featuring our mobile work

As with the previous version, the primary purpose of our website is to offer an efficient way for prospective clients to hire us. We chose a single-page site to easily afford that action even if the user is reviewing other aspects of the company such as our people or offices.

Like any project, we have ideas for future improvements such as more in-depth case studies. However, we released once we were proud of the core workflow, quality of visual and interaction design, and had tested multiple browsers and devices.

Enjoy the new thoughtbot.com! I hope to hear from you in via the sales or hiring forms.

New thoughtbot.com

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

We’re pleased to announce the redesign of thoughtbot.com!

People generally know us as a Ruby on Rails consultancy. While true, we are a well-balanced team of designers, web (Rails) developers, and mobile (iOS) developers.

Therefore, we redesigned the site with a focus on aesthetics to better provide future clients an accurate view of our capabilities by:

  • providing a profound visual experience
  • maintaining exceptionally smooth interactions
  • featuring our mobile work

As with the previous version, the primary purpose of our website is to offer an efficient way for prospective clients to hire us. We chose a single-page site to easily afford that action even if the user is reviewing other aspects of the company such as our people or offices.

Like any project, we have ideas for future improvements such as more in-depth case studies. However, we released once we were proud of the core workflow, quality of visual and interaction design, and had tested multiple browsers and devices.

Enjoy the new thoughtbot.com! I hope to hear from you in via the sales or hiring forms.

Build Phase Podcast Episode 9: Don't Call Me Shirley

Posted 7 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Build Phase Podcast Episode 9: Don't Call Me Shirley:

Gordon Fontenot and Mark Adams talk about iOS7 aftermath and Airplane!