diff --git a/ui (gen4)/css/widget/drawer.css b/ui (gen4)/css/widget/drawer.css
new file mode 100755
index 00000000..1f2cabcc
--- /dev/null
+++ b/ui (gen4)/css/widget/drawer.css	
@@ -0,0 +1,54 @@
+
+.drawer-widget {
+	position: absolute;
+
+	width: 100%;
+	height: 100%;
+	top: 0px;
+	left: 0px;
+
+	overflow: auto;
+
+	background: rgba(0, 0, 0, 0.5);
+
+	-webkit-transform-style: preserve-3d;
+	-moz-transform-style: preserve-3d;
+	transform-style: preserve-3d;
+}
+.drawer-widget~.drawer-widget {
+	background: rgba(0, 0, 0, 0.1);
+}
+
+
+.drawer-widget .content {
+	position: relative;
+	display: inline-block;
+
+	top: 100%;
+	left: 0px;
+
+	width: 100%;
+	height: auto;
+
+	overflow: hidden;
+
+
+	box-shadow: rgba(0, 0, 0, 0.1) 0.3em 0.3em 5em;
+}
+.drawer-widget~.drawer-widget .content {
+	box-shadow: rgba(0, 0, 0, 0.05) 0.1em 0.1em 3em;
+}
+
+/* NOTE: this does not include text... 
+		...need a way to go around this...
+*/
+.blur>* {
+	-webkit-filter: blur(2px) saturate(0.3);
+	filter: blur(2px) saturate(0.3);
+}
+.blur>.drawer-widget {
+	-webkit-filter: none;
+	filter: none;
+}
+
+
diff --git a/ui (gen4)/lib/widget/drawer.html b/ui (gen4)/lib/widget/drawer.html
new file mode 100755
index 00000000..40b907f0
--- /dev/null
+++ b/ui (gen4)/lib/widget/drawer.html	
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Theme: ')
+			.addClass('drawer-widget')
+			.on(options.nonPropagatedEvents.join(' '), function(){
+				event.stopPropagation()
+			})
+			.append($('
')
+				.addClass('content')
+				.click(function(){
+					event.stopPropagation()
+				})
+				.append(client))
+
+		return overlay
+	},
+}
+
+
+var OverlayPrototype = {
+	dom: null,
+	client: null,
+
+	options: {
+		nonPropagatedEvents: [
+			'click',
+			'keydown',
+		],
+	},
+
+	keyboard: {
+		General: {
+			pattern: '.browse-widget',
+
+			Esc: 'close',
+		},
+	},
+
+	// XXX triggering events from here and from jQuery/dom has a 
+	// 		different effect...
+	trigger: widget.triggerEventWithSource,
+
+	// proxy event api...
+	on: widget.proxyToDom('on'),
+	one: widget.proxyToDom('one'),
+	off: widget.proxyToDom('off'),
+	bind: widget.proxyToDom('bind'),
+	unbind: widget.proxyToDom('unbind'),
+	deligate: widget.proxyToDom('deligate'),
+	undeligate: widget.proxyToDom('undeligate'),
+
+	// custom events...
+	close: function(handler){
+		// trigger the event...
+		if(handler == null){
+			var that = this
+			this.dom.animate({
+					scrollTop: 0,
+					opacity: 0,
+					filter: 'none',
+				}, 
+				120,
+				function(){
+					that.dom.detach()
+					if(that.parent.children('.overlay-widget').length == 0){
+						that.parent.removeClass('blur')
+					}
+					that.trigger('close')
+				})
+
+		// register a handler...
+		} else {
+			this.on('close', handler)
+		}
+	},
+
+	__init__: function(parent, client, options){
+		var that = this
+		parent = this.parent = $(parent || 'body')
+		options = options || {}
+
+		this.client = client
+		var client_dom = client.dom || client
+
+		// merge options...
+		var opts = Object.create(this.options)
+		Object.keys(options).forEach(function(n){ opts[n] = options[n] })
+		options = this.options = opts
+
+		var dom = this.dom = this.constructor.make(client_dom, options)
+			.click(function(){
+				that.close()
+			})
+
+		parent
+			.addClass('blur')
+			.append(dom)
+
+		// add keyboard handler...
+		dom.keydown(
+			keyboard.makeKeyboardHandler(
+				this.keyboard,
+				options.logKeys,
+				this))
+			.css({opacity: 0})
+			.animate({
+					scrollTop: Math.min(
+						client_dom.outerHeight(), 
+						// do not scroll more than the container height and
+						// keep a bit on top...
+						(parent.is('body') ? $(document) : parent).outerHeight()-100)+'px',
+					opacity: 1,
+				}, 
+				120,
+				function(){
+					dom.scroll(function(){
+						var st = $(this).scrollTop()
+						var h = Math.min(100, client_dom.outerHeight())
+						// start fading...
+						if(st < h){
+							dom.css({ opacity: Math.min(1, st/h) })
+						} else if(dom.css('opacity') < 1){
+							dom.css('opacity', 1)
+						}
+						// close drawer when scrolling to the top...
+						if(st < 10){
+							that.close()
+						}
+					})
+				})
+
+		// focus the client...
+		if(client.focus){
+			client.focus()
+		}
+
+		return this
+	},
+}
+
+
+var Overlay = 
+module.Overlay = 
+object.makeConstructor('Drawer', 
+		OverlayClassPrototype, 
+		OverlayPrototype)
+
+
+
+/**********************************************************************
+* vim:set ts=4 sw=4 :                                                */
+return module })