Q:

making vars accessible across phases

How can I make the same variable accessible across multiple phases? For instance:

(define foo 1)
(define-for-syntax bar foo)

would complain that foo is not defined in phase 0.

A:

It depends on what you want this "variable" for. Here are some options:

You want it to be an immutable, primitive value.
You want it to be immutable, but complex data like a struct (not primitive).
You want it to be mutable.

In Leif Andersen's comment, where she said "you can't really, and shouldn't even if you could". I'm guessing she was talking about (3). The Racket compiler tries to make (3) impossible within the "internal" Racket runtime system. In the Racket documentation this is called the The Separate Compilation Guarantee. There are good reasons behind The Separate Compilation Guarantee and why (3) is a bad idea, and Leif Andersen or Matthew Flatt could explain those reasons much better than me. The paper Composable and Compilable Macros: You Want it When? and the talk Racket: Metaprogramming Time! explain some of those reasons.
However, in case an immutable value is enough, I will try to show answers for (1) and (2).
1: immutable, primitive data
Since the data is immutable, it's okay to have "two different identifiers" at different phases. If they start with the same value, and neither one is mutated, then they will stay at the same value.
(begin-for-syntax
  (define foo 1))
(define foo 1)

However, this does not guarantee that the two foo variables have the same value, even if they look the same. It is possible for the "for-syntax" environment and the normal environment to be different, and interpret those expressions differently. To make sure that doesn't happen, it's better to have a single definition of foo in a module. This makes sure that it always has the same consistent environment. Then you can require that module multiple times, for both "for-syntax" and the normal way:
(module foo racket
  (provide foo)
  (define foo 1))

(require (for-syntax 'foo)
         'foo)

2: immutable, complex data
There are two ways to extend this to complex data like structs:

using prefab structs
using cross-phase-persistent modules

2a: immutable, complex data, prefab structs
Normally structs are "generative" meaning the a definition that looks the same written in two different places will generate two different struct types, and those structs will never be equal
However, structs with #:prefab are special because if you have the same definition in two different places, even at both "for-syntax" and normal levels, they do produce equal values.
(begin-for-syntax
  (struct rgb-color [r g b] #:prefab)
  (define red (rgb-color 255 0 0)))
(struct rgb-color [r g b] #:prefab)
(define red (rgb-color 255 0 0))

Or you can put this in a module as well, and require it at both the for-syntax and normal levels:
(module red racket
  (provide red)
  (struct rgb-color [r g b] #:prefab)
  (define red (rgb-color 255 0 0)))

(require (for-syntax 'red)
         'red)

2b: immutable, complex data, cross-phase-persistent structs
If prefab structs aren't good enough, and you want structs that feel less like "anything goes" primitive data, and more like an abstraction, there is a way to define a struct in a module that is specifically marked as cross-phase-persistent.
It's not a simple as writing struct however. The syntax of a cross-phase-persistent is very restrictive. As far as I know, you would have to go low-level and use only #%kernel forms like define-values and make-struct-type. Your struct declarations might have to look like this:
#lang racket/kernel
(#%declare #:cross-phase-persistent)

(define-values [_1 rgb-color rgb-color? rgb-color-ref _5]
  (#%app make-struct-type 'rgb-color '#f '3 '0 '#f '() 'prefab '#f
         (#%app list '0 '1 '2)))

This is a much bigger hastle, so the more common solution is to just use prefab structs instead.

