diff --git a/blogposts/gophercon-2019-portable-immediate-mode-gui-programs-for-mobile-and-desktop-in-100-go.md b/blogposts/gophercon-2019-portable-immediate-mode-gui-programs-for-mobile-and-desktop-in-100-go.md
deleted file mode 100644
index b679ba0246c..00000000000
--- a/blogposts/gophercon-2019-portable-immediate-mode-gui-programs-for-mobile-and-desktop-in-100-go.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "GopherCon 2019 - Portable, immediate mode GUI programs for mobile and desktop in 100% Go"
-description: "Gio is a new open source Go library for writing immediate mode GUI programs that run on all the major platforms: Android, iOS/tvOS, macOS, Linux, Windows. The talk will cover Gio's unusual design and how it achieves simplicity, portability and performance."
-author: $LIVEBLOGGER_NAME for the GopherCon 2019 Liveblog
-publishDate: 2019-07-25T00:00-10:50
-tags: [
- gophercon
-]
-slug: gophercon-2019-portable-immediate-mode-gui-programs-for-mobile-and-desktop-in-100-go
-heroImage: /gophercon2019.png
-published: false
----
-
-Presenter: Elias Naur
-
-Liveblogger: [$LIVEBLOGGER_NAME]($LIVEBLOGGER_URL)
-
-## Overview
-
-Gio is a new open source Go library for writing immediate mode GUI programs that run on all the major platforms: Android, iOS/tvOS, macOS, Linux, Windows. The talk will cover Gio's unusual design and how it achieves simplicity, portability and performance.
-
----
-
-Liveblog content here.
diff --git a/blogposts/gophercon-2019-simple-portable-efficient-graphical-interfaces-in-go.md b/blogposts/gophercon-2019-simple-portable-efficient-graphical-interfaces-in-go.md
new file mode 100644
index 00000000000..b2c7fe89d85
--- /dev/null
+++ b/blogposts/gophercon-2019-simple-portable-efficient-graphical-interfaces-in-go.md
@@ -0,0 +1,669 @@
+---
+title: "GopherCon 2019 - Simple, Portable and Efficient Graphical Interfaces in Go"
+description: "Gio is a new open source Go library for writing immediate mode GUI programs that run on all the major platforms: Android, iOS/tvOS, macOS, Linux, Windows. The talk will cover Gio's unusual design and how it achieves simplicity, portability and performance."
+author: Christina Forney for the GopherCon 2019 Liveblog
+publishDate: 2019-07-25T00:00-10:50
+tags: [
+ gophercon
+]
+slug: gophercon-2019-simple-portable-efficient-graphical-interfaces-in-go
+heroImage: /gophercon2019.png
+published: true
+---
+
+Presenter: Elias Naur
+
+Liveblogger: [Christina Forney](https://www.linkedin.com/in/christinaforney/)
+
+## Overview
+
+Gio is a new open source Go library for writing immediate mode GUI programs that run on all the major platforms: Android, iOS/tvOS, macOS, Linux, Windows. The talk will cover Gio's unusual design and how it achieves simplicity, portability and performance.
+
+---
+
+## Why GUIs?
+
+Last year at GopherCon we asked what the biggest challenges that Go developers faced. Here are the results:
+
+
+
+As you heard in the keynote, Modules, generics, and error handling is being handled by the Go team, so I wanted to focus on making writing GUIs in Go easy.
+
+## Introduction
+
+Gio - [gioui.org](https://gioui.org/)
+
+- Gio is a simple Go module for writing portable and fast graphical interfaces.
+
+Scatter - [scatter.im](https://scatter.im/)
+
+- Scatter is a Gio program for end-to-end encrypted messaging over email.
+
+## Demo - Scatter
+
+Scatter is a multi-platform messaging application for sending and receiving encrypted chat messages, implementing the Signal protocol over federated email.
+
+
+
+### Features
+
+I wanted to be able to write a GUI program in GO that I could implement only once and have it work on every platform. This, to me, is the most interesting feature of Gio.
+
+Features:
+
+- Immediate mode design.
+ - UI state owned by program.
+- Only depends on lowest-level platform libraries.
+ - Minimal dependency tree to keep things low level as possible.
+- GPU accelerated vector and text rendering.
+ - It’s super efficient
+- No garbage generated in drawing or layout code.
+- Cross platform (macOS, Linux, Windows, Android, iOS, tvOS, Webassembly).
+- Core is 100% Go. OS-specific native interfaces are optional.
+
+### Immediate mode UI
+
+Some programs require you to maintain state for your widgetry. In Gio, you draw what you need to draw, you layout what you need to layout, and that’s it!
+
+- UI state is owned by the program. Even layout and widget tree.
+- No callbacks. Events are handled while drawing.
+
+### Blank window
+
+This is all you need to render a simple blank window:
+
+```golang
+package main
+
+import (
+ “gioui.org/ui/app”
+)
+
+func main() {
+ go func() {
+ w := app.NewWindow(nil)
+ for range w.Events() {
+ }
+ }()
+ app.Main()
+}
+```
+
+This is odd, because you’re doing the event loop in your go routine.
+
+### Hello, World
+
+Slightly more advanced example, but in this case you are loading up some support structures and adding `text.Label` to display your label:
+
+```golang
+func main() {
+ go func() {
+ w := app.NewWindow(nil)
+ regular, _ := sfnt.Parse(goregular.TTF)
+ var cfg ui.Config
+ var faces measure.Faces
+ ops := new(ui.Ops)
+ for e := range w.Events() {
+ if e, ok := e.(app.DrawEvent); ok {
+ cfg = &e.Config
+ cs := layout.RigidConstraints(e.Size)
+ ops.Reset()
+ faces.Reset(cfg)
+
+ // ADD YOUR LABELS
+ lbl := text.Label{Face: faces.For(regular, ui.Sp(72)), Text: “Hello, World!”}
+ lbl.Layout(ops, cs)
+
+ w.Draw(ops)
+ }
+ }
+ }()
+ app.Main()
+}
+```
+
+
+
+## Running Gio programs
+
+### Linux, macOS, Windows
+
+
+
+#### Enable modules
+
+`export GO111MODULE=on`
+
+I recommend you enable for convenience and also because I break the API often, so you will be shielded from updates that could break your application until you are ready to upgrade.
+
+#### Build, install or run the program
+
+
+
+```
+go build gioui.org/ui/apps/hello
+go install scatter.im/cmd/scatter
+go run helloworld.go
+```
+
+### Android
+
+There is a tool to package your application as an APK that you can install through the ads tool to run on a device or simulator.
+
+Install the gio tool:
+
+```
+go install gioui.org/cmd/gio
+$GOBIN/gio -target android -o hello.apk helloworld.go
+```
+
+Install on a connected device or emulator with adb:
+
+```
+adb install hello.apk
+```
+
+### iOS/tvOS
+
+For iOS/tvOS devices:
+
+```
+$GOBIN/gio -target -o hello.ipa -appid helloworld.go
+```
+
+Use the .app file extension for simulators:
+
+```
+$GOBIN/gio -target -o hello.app helloworld.go
+```
+
+Install on a running simulator:
+
+```
+xcrun simctl install booted hello.app
+```
+
+### Browsers
+
+To output a directory ready to serve:
+
+```
+$GOBIN/gio -target js -o www helloworld.go
+```
+
+Use a webserver or goexec to serve it:
+
+```
+go run github.com/shurcooL/goexec ‘http.ListenAndServe(“:8080”, http.FileServer(http.Dir(“www”)))’
+```
+
+Compile directly with the Go tool or use the Gio tool to build as a web assembly module, but also add the necessary file to supply it to work in your browser.
+
+## Operations
+
+The way you communicate each user interface update to gio. Gio has not state so you have to add it to every frame.
+
+Operations buffer and type called ui ops and you add operations to that to your ops buffers which sends to window.draw method.
+
+### Operations
+
+
+
+#### Serializing operations
+
+```golang
+import “gioui.org/ui” // Pure Go
+
+var ops ui.Ops
+// Add operations to ops
+ui.InvalidateOp{}.Add(ops)
+…
+```
+
+
+
+#### Only the app package depends on platform libraries
+
+```golang
+import “gioui.org/ui/app”
+
+var w app.Window
+w.Draw(&ops)
+```
+
+
+
+#### Position other operations
+
+```golang
+import “gioui.org/ui”
+
+ui.TransformOp{ui.Offset(f32.Point{…})}.Add(ops)
+```
+
+
+
+#### Request a redraw
+
+```golang
+ui.InvalidateOp{}.Add(ops) // Immediate
+ui.InvalidateOp{At: …}.Add(ops) // Delayed
+```
+
+
+
+### Drawing operations
+
+
+
+#### Set current color or image
+
+```golang
+import “gioui.org/ui/draw”
+
+draw.ColorOp{Color: color.RGBA{…}}.Add(ops)
+draw.ImageOp{Src: …, Rect: …}.Add(ops)
+```
+
+
+
+#### Draw with the current color or image
+
+`draw.DrawOp{Rect: …}.Add(ops)`
+
+### Clip operations
+
+
+
+#### Clip drawing to a rectangle
+
+```golang
+import “gioui.org/draw”
+
+draw.RectClip(image.Rectangle{…}).Add(ops)
+```
+
+
+
+#### Or to an outline
+
+```golang
+var b draw.PathBuilder
+b.Init(ops)
+b.Line(…)
+b.Quad(…) // Quadratic Beziér curve
+b.Cube(…) // Cubic Beziér curve
+b.End()
+```
+
+
+
+### Input operations
+
+
+
+#### Keyboard and text input
+
+```golang
+import “gioui.org/ui/key”
+
+// Declare key handler.
+key.HandlerOp{Key: handler, Focus: true/false}.Add(ops)
+
+// Hide soft keyboard.
+key.HideInputOp{}.Add(ops)
+```
+
+
+
+#### Mouse and touch input
+
+```golang
+import “gioui.org/ui/pointer”
+
+// Define hit area.
+pointer.RectAreaOp{Size: …}.Add(ops)
+pointer.EllipseAreaOp{Size: …}.Add(ops)
+
+// Declare pointer handler.
+pointer.HandlerOp{Key: c, Grab true/false}
+```
+
+## Drawing
+
+### Drawing (and animating)
+
+
+
+#### Drawing and animating a clipped square
+
+```golang
+ square := f32.Rectangle{Max: f32.Point{X: 500, Y: 500}}
+ radius := animateRadius(e.Config.Now(), 250)
+
+ // Position
+ ui.TransformOp{ui.Offset(f32.Point{
+ X: 100,
+ Y: 100,
+ })}.Add(ops)
+ // Color
+ draw.ColorOp{Color: color.RGBA{A: 0xff, G: 0xcc}}.Add(ops)
+ // Clip corners
+ roundRect(ops, 500, 500, radius, radius, radius, radius)
+ // Draw
+ draw.DrawOp{Rect: square}.Add(ops)
+ // Animate
+ ui.InvalidateOp{}.Add(ops)
+
+ // Submit operations to the window.
+ w.Draw(ops)
+```
+
+## Layout
+
+If you have non-trivial setup, you need some way to lay them out - you don’t want to use absolute coordinates for each item. Layout assembly helps you structure your user interface. As a result of calling their layout, widgets will give you their own size.
+
+### Constraints and dimensions
+
+
+
+#### Constraints are input
+
+```golang
+package layout // import gioui.org/ui/layout
+
+type Constraints struct {
+ Width Constraint
+ Height Constraint
+}
+
+type Constraint struct {
+ Min, Max int
+}
+```
+
+
+
+#### Dimensions are output
+
+```golang
+type Dimens struct {
+ Size image.Point
+ Baseline int
+}
+```
+
+
+
+#### Widgets accept constraints, output dimensions
+
+```golang
+package text // import gioui.org/ui/text
+
+func (l Label) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens
+func (e *Editor) Layout(ops *ui.Ops, cs layout.Constraints) layout.Dimens
+
+package widget // import gioui.org/ui/widget
+
+func (im Image) Layout(c ui.Config, ops *ui.Ops, cs layout.Constraints) layout.Dimens
+```
+
+
+
+### Example - two labels
+
+```golang
+func drawLabels(face text.Face, ops *ui.Ops, cs layout.Constraints) {
+ **cs.Height.Min = 0**
+ lbl := text.Label{Face: face, Text: “One label”}
+ **dimensions := lbl.Layout(ops, cs)**
+ ui.TransformOp{ui.Offset(f32.Point{
+ **Y: float32(dimensions.Size.Y),**
+ })}.Add(ops)
+ lbl2 := text.Label{Face: face, Text: “Another label”}
+ lbl2.Layout(ops, cs)
+}
+```
+
+
+
+### Layout helpers
+
+Can layout to the compass directions or to specific place, like the center.
+
+#### Aligning
+
+```golang
+var ops *ui.Ops
+var cs layout.Constraints
+
+align := layout.Align{Alignment: layout.Center}
+cs = align.Begin(ops, cs)
+…
+dimensions := someWidget.Layout(…, cs) // Draw widget
+…
+dimensions = align.End(dimensions)
+```
+
+#### Insetting
+
+```golang
+var cfg ui.Config
+inset := layout.Inset{Top: ui.Dp(8), …} // 8dp top inset
+cs = inset.Begin(c, ops, cs)
+…
+dimensions := anotherWidget.Layout(…, cs) // Draw widget
+…
+dimensions = inset.End(dimensions)
+```
+
+
+
+### Flex layout
+
+
+
+#### Lay out widgets on an axis.
+
+```golang
+func drawRects(c ui.Config, ops *ui.Ops, cs layout.Constraints) {
+ flex := layout.Flex{}
+ flex.Init(ops, cs)
+
+ cs = flex.Flexible(0.5)
+ dimensions := drawRect(c, ops, color.RGBA{A: 0xff, R: 0xff}, cs)
+ red := flex.End(dimensions)
+
+ cs = flex.Flexible(0.25)
+ dimensions = drawRect(c, ops, color.RGBA{A: 0xff, G: 0xff}, cs)
+ green := flex.End(dimensions)
+
+ cs = flex.Flexible(0.25)
+ dimensions = drawRect(c, ops, color.RGBA{A: 0xff, B: 0xff}, cs)
+ blue := flex.End(dimensions)
+
+ flex.Layout(red, green, blue)
+}
+```
+
+
+
+### Stack layout
+
+```golang
+func drawRects(c ui.Config, ops *ui.Ops, cs layout.Constraints) {
+ stack := layout.Stack{Alignment: layout.Center}
+ stack.Init(ops, cs)
+
+ cs = stack.Rigid()
+ dimensions := drawRect(c, ops, color.RGBA{A: 0xff, R: 0xff}, ui.Dp(50), cs)
+ red := stack.End(dimensions)
+
+ cs = stack.Rigid()
+ dimensions = drawRect(c, ops, color.RGBA{A: 0xff, G: 0xff}, ui.Dp(100), cs)
+ green := stack.End(dimensions)
+
+ cs = stack.Rigid()
+ dimensions = drawRect(c, ops, color.RGBA{A: 0xff, B: 0xff}, ui.Dp(150), cs)
+ blue := stack.End(dimensions)
+
+ stack.Layout(red, green, blue)
+}
+```
+
+
+
+### List layout
+
+```golang
+ list := &layout.List{
+ Axis: layout.Vertical,
+ }
+func drawList(c ui.Config, q input.Queue, list *layout.List, face text.Face, ops *ui.Ops, cs layout.Constraints) {
+ const n = 1e6
+ for list.Init(c, q, ops, cs, n); list.More(); list.Next() {
+ txt := fmt.Sprintf(“List element #%d", list.Index())
+
+ lbl := text.Label{Face: face, Text: txt}
+ dims := lbl.Layout(ops, list.Constraints())
+
+ list.Elem(dims)
+ }
+ list.Layout()
+}
+```
+
+## Input
+
+### Input queue and handler keys
+
+```golang
+// Queue maps an event handler key to the events
+// available to the handler.
+type Queue interface {
+ Events(k Key) []Event
+}
+
+// Key is the stable identifier for an event handler.
+// For a handler h, the key is typically &h.
+type Key interface{}
+```
+
+
+
+### Pointer event handling
+
+```golang
+func (b *Button) Layout(queue input.Queue, ops *ui.Ops) {
+ for _, e := range queue.Events(b) {
+ if e, ok := e.(pointer.Event); ok {
+ switch e.Type {
+ case pointer.Press:
+ b.pressed = true
+ case pointer.Release:
+ b.pressed = false
+ }
+ }
+ }
+
+ col := color.RGBA{A: 0xff, R: 0xff}
+ if b.pressed {
+ col = color.RGBA{A: 0xff, G: 0xff}
+ }
+ pointer.RectAreaOp{
+ Size: image.Point{X: 500, Y: 500},
+ }.Add(ops)
+ pointer.HandlerOp{Key: b}.Add(ops)
+ drawSquare(ops, col)
+}
+```
+
+Takes all available events, updates it’s own state, system can know whether the events belong to this button or not is you register the area rectangle arc with a handler.
+
+### Window input queue
+
+
+
+#### The Window’s Queue method returns an input.Queue for OS events.
+
+```golang
+package app // import gioui.org/ui/app
+
+func (w *Window) Queue() *Queue
+```
+
+
+
+### Gestures
+
+```golang
+import “gioui.org/ui”
+import “gioui.org/ui/gesture”
+import “gioui.org/ui/input”
+```
+
+
+
+#### Detect clicks
+
+```golang
+var queue input.Queue
+var c gesture.Click
+for _, event := range c.Events(queue) {
+ // event is a gesture.ClickEvent, not a raw pointer.Event.
+}
+```
+
+
+
+#### Determine scroll distance from mouse wheel or touch drag/fling
+
+```golang
+var cfg ui.Config
+var s gesture.Scroll
+
+distance := s.Scroll(cfg, queue, gesture.Vertical)
+```
+
+
+
+## Widgets
+
+### Widgets - the Editor
+
+Complete implementation of a text area field. It’s a complicated widget, but is simple to use. You have to keep state somewhere, but you give it font and font size. Simply call the layout methods and
+
+#### Initialize the editor
+
+```golang
+import “gioui.org/ui/text”
+
+ var faces measure.Faces
+ editor := &text.Editor{
+ Face: faces.For(regular, ui.Sp(52)),
+ }
+ editor.SetText(“Hello, Gophercon! Edit me.”)
+```
+
+
+
+#### Draw, layout and handle input in one call.
+
+```golang
+editor.Layout(cfg, queue, ops, cs)
+```
+
+
+
+## Why Gio?
+
+Gio is:
+
+- **Simple**. Immediate mode design, no hidden state.
+- **Portable**. The core of Gio is all Go.
+- **Fast**. GPU accelerated, very little per-frame garbage.
+- **Convenient**. Develop on desktop, deploy on mobile.
+- Public domain source (UNLICENCE). Dual licenced MIT to please your lawyers.
+ Most importantly, Gio needs your help to succeed!
+
+I want to bring Go from a place where GUI programming is a fringe activity to a state where it’s normal to use. Maybe in the future we can bring it to a place where you will choose Go for your GUI programming even if you aren’t interested in Go as a programming language, but because the tooling is so good.
diff --git a/website/static/gophercon-2019/gophercon-2019-gio-go-challenges.jpg b/website/static/gophercon-2019/gophercon-2019-gio-go-challenges.jpg
new file mode 100644
index 00000000000..b9a9833d21b
Binary files /dev/null and b/website/static/gophercon-2019/gophercon-2019-gio-go-challenges.jpg differ
diff --git a/website/static/gophercon-2019/gophercon-2019-gio-hello-world.jpg b/website/static/gophercon-2019/gophercon-2019-gio-hello-world.jpg
new file mode 100644
index 00000000000..adfef986737
Binary files /dev/null and b/website/static/gophercon-2019/gophercon-2019-gio-hello-world.jpg differ
diff --git a/website/static/gophercon-2019/gophercon-2019-gio-scatter-ui.jpg b/website/static/gophercon-2019/gophercon-2019-gio-scatter-ui.jpg
new file mode 100644
index 00000000000..78a6ad84272
Binary files /dev/null and b/website/static/gophercon-2019/gophercon-2019-gio-scatter-ui.jpg differ