anchor.diff:    3 : 'Are Neutral'
   
   ##
  -# StyleAnimator mixin
  -# Helper for components that implement animations.
  +# PageTransition mixin
  +# Helper for components that implement a page transition animation.
   # Applies styles defined in the component that change
   # depending on state. Right now this mixin assumes that
   # animations will be applied only on route changes. 
  
positive.code:   componentWillUnmount : -> 
      $el = $(@getDOMNode())
      $el.find('.fixed_proposal_heading').stickyTopBottom('destroy')
      
    ##
    # State-dependent styling
    applyStyles : (animate = true) ->  
      $el = $(@getDOMNode())
      duration = if animate then TRANSITION_SPEED else 0
      root = @data('root')
  
      # • Velocity requires properties to be pulled out (e.g. paddingLeft, 
      #   translateX, rather than using padding or transform)
      # • We use velocity even for 0 duration style applications to maintain 
      #   parity of style definition
      switch root.page_name
        when 'crafting'
          styles = 
            '.histogram_bar':        { opacity: '.2' }
            '.decision_board_body':  { translateX: 0, translateY: 0, width: "#{DECISION_BOARD_WIDTH}px", minHeight: "275px"}
            '.pros_by_community':    { translateX: 0 }
            '.cons_by_community':    { translateX: "#{DECISION_BOARD_WIDTH}px" }
          
          @applyStylesToElements styles, duration
  
          $el.find('.give_opinion_button').css 'visibility', 'hidden'
          _.delay => 
            #delay & check in case of quick switch between pages
            if root.page_name == 'crafting'
              $el.find('.your_points, .save_opinion_button, .cancel_opinion_button').css 'display', ''
          , duration
  
        when 'results'
          slider = @data('slider')
          stance = slider.stance
          segment = slider.stance_segment
  
          give_opinion_button_width = 186
          gutter = .1 * give_opinion_button_width
  
          opinion_region_x = -gutter + (DECISION_BOARD_WIDTH - give_opinion_button_width + 2 * gutter) * -(stance-1) / 2.0
  
          styles = 
            '.histogram_bar':         { opacity: '1' }
            '.decision_board_body':   { translateX: opinion_region_x, translateY: -18, width: "#{give_opinion_button_width}px", minHeight: "32px"}
            '.pros_by_community':     { translateX:  DECISION_BOARD_WIDTH / 2 }
            '.cons_by_community':     { translateX:  DECISION_BOARD_WIDTH / 2 }
          
          @applyStylesToElements styles, duration
  
          $el.find('.your_points, .save_opinion_button, .cancel_opinion_button').css 'display', 'none'
          _.delay => 
            #check in case of quick switch between pages
            if root.page_name == 'results'
              $el.find('.give_opinion_button').css 'visibility', ''
          , duration  
  
    ##
    # Make this thing!
  
negative.code: # A component that implements this mixin should define a method:
  #     applyStyles : (animate = true)
  # which puts the styles on the desired elements. 
  PageTransition = 
  
    componentDidMount : -> @applyStyles false
  
    componentDidUpdate : (prev_props, prev_page) -> 
      @applyStyles _route_changed
  
    applyStyles : (animate = true) -> 
      duration = if animate then TRANSITION_SPEED else 0
      root = @data('root')        
      $el = $(@getDOMNode())
  
      switch @name
  
        # The histogram will get transparent when moving to crafting page
        when 'histogram'
          opacity = if root.page_name == 'crafting' then '0.2' else '1.0'
          $el.find('.histogram_bar').velocity {opacity: opacity}, {duration}
  
        # The position of the CommunityPoints will move to the wings on crafting, and 
        # be close together in results
        when 'communitypoints'
  
          if root.page_name == 'crafting'
            offset_x = if @props.key == 'pros' then 0 else DECISION_BOARD_WIDTH
          else if root.page_name == 'results'
            offset_x = DECISION_BOARD_WIDTH / 2
  
          $el.velocity { translateX: offset_x }, {duration}
  
        # The slider handle and mouth will change size and location when moving between crafting and results
        when 'slider'
          slider = @data('slider')
  
          mouth_scaler = if slider.stance_segment >  3 then -1 else 1
          mouth_x      = if slider.stance_segment == 3 then  0 else -7.5
  
          if root.page_name == 'crafting'
            bubblemouth_style = { scaleX: mouth_scaler * 1.5, scaleY: 1.5, translateY: 7, translateX: mouth_x * 1.5  }
            handle_style = { scale: 2.5, translateY: -8 }
          else 
            bubblemouth_style = { scaleX: mouth_scaler, scaleY: 1, translateY: -4.5, translateX: mouth_x  }
            handle_style = { scale: 1, translateY: -9 }
  
          $el.find('.bubblemouth').velocity bubblemouth_style, {duration}
          $el.find('.the_handle').velocity handle_style, {duration}
  
        # The decision board will have to expand for crafting and collapse into to the Give Opinion button in results
        when 'decisionboard'
          if root.page_name == 'crafting'
            decision_board_style =  { translateX: 0, translateY: 0, width: "#{DECISION_BOARD_WIDTH}px", minHeight: "275px"}
  
            $el.find('.decision_board_body').velocity decision_board_style, {duration}
  
            $el.find('.give_opinion_button').css 'visibility', 'hidden'
            _.delay => 
              #delay & check in case of quick switch between pages
              if root.page_name == 'crafting'
                $el.find('.your_points, .save_opinion_button, .cancel_opinion_button').css 'display', ''
            , duration
  
          else 
            slider = @data('slider')
            stance = slider.stance
  
            give_opinion_button_width = 186
            gutter = .1 * give_opinion_button_width
  
            opinion_region_x = -gutter + (DECISION_BOARD_WIDTH - give_opinion_button_width + 2 * gutter) * -(stance-1) / 2.0
  
            decision_board_style =  { translateX: opinion_region_x, translateY: -18, width: "#{give_opinion_button_width}px", minHeight: "32px"}
  
            $el.find('.decision_board_body').velocity decision_board_style, {duration}
  
            $el.find('.your_points, .save_opinion_button, .cancel_opinion_button').css 'display', 'none'
            _.delay => 
              #check in case of quick switch between pages
              if root.page_name == 'results'
                $el.find('.give_opinion_button').css 'visibility', ''
            , duration  
        else
          throw "The #{@name} component does not define any styles to animate"
  
  
  ## ##################
  