diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,23 @@
 Brick changelog
 ---------------
 
+2.11
+----
+
+Bug fixes:
+
+* Fixed a bug in FileBrowser: if a user pressed Enter when the cursor
+  was on a selected entry, it was omitted from the list of
+  selected browser entries. As part of this change, the function
+  `actionFileBrowserSelectCurrent` previously toggled the selection
+  of the entry at the cursor, but should have selected it instead.
+  It now does so, and a new function for toggling was introduced:
+  `actionFileBrowserToggleCurrent`.
+
+Other changes:
+
+* Upper bounds on `base` and `microlens` were adjusted.
+
 2.10
 ----
 
@@ -1848,7 +1865,7 @@
 Bug fixes:
 * Fixed viewport behavior when the image in a viewport reduces its size
   enough to render the viewport offsets invalid. Before, this behavior
-  caused a crash during image croppin in vty; now the behavior is
+  caused a crash during image cropping in vty; now the behavior is
   handled sanely (fixes #22; reported by Hans-Peter Deifel)
 
 0.2.2
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -105,13 +105,14 @@
 | [`wrapping-editor`](https://github.com/ta0kira/wrapping-editor) | An embeddable editor with support for Brick |
 | [`youbrick`](https://github.com/florentc/youbrick) | A feed aggregator and launcher for Youtube channels |
 
-These third-party packages also extend `brick`:
+These additional packages also extend `brick`:
 
 | Project | Description | Hackage |
 | ------- | ----------- | ------- |
 | [`brick-filetree`](https://github.com/ChrisPenner/brick-filetree) | A widget for exploring a directory tree and selecting or flagging files and directories | [Hackage](https://hackage.haskell.org/package/brick-filetree) |
 | [`brick-panes`](https://github.com/kquick/brick-panes) | A Brick overlay library providing composition and isolation of screen areas for TUI apps. | [Hackage](https://hackage.haskell.org/package/brick-panes) |
 | [`brick-calendar`](https://github.com/ldgrp/brick-calendar) | A library providing a calendar widget for Brick-based applications. | [Hackage](https://hackage.haskell.org/package/brick-calendar) |
+| [`brick-skylighting`](https://github.com/jtdaugherty/brick-skylighting) | A library providing integration support for [Skylighting](https://hackage.haskell.org/package/skylighting)-based syntax highlighting. | [Hackage](https://hackage.haskell.org/package/brick-skylighting) |
 
 Getting Started
 ---------------
@@ -213,6 +214,8 @@
 If you decide to contribute, that's great! Here are some guidelines you
 should consider to make submitting patches easier for all concerned:
 
+ - Patches written completely or partially by AI are unlikely to be
+   accepted.
  - If you want to take on big things, talk to me first; let's have a
    design/vision discussion before you start coding. Create a GitHub
    issue and we can use that as the place to hash things out.
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             2.10
+version:             2.11
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal user interfaces (TUIs) painlessly with 'brick'! You
@@ -108,7 +108,7 @@
     Brick.Types.Internal
     Brick.Widgets.Internal
 
-  build-depends:       base >= 4.9.0.0 && < 4.22.0.0,
+  build-depends:       base >= 4.9.0.0 && < 4.23.0.0,
                        vty >= 6.0,
                        vty-crossplatform,
                        bimap >= 0.5 && < 0.6,
@@ -117,7 +117,7 @@
                        exceptions >= 0.10.0,
                        filepath,
                        containers >= 0.5.7,
-                       microlens >= 0.3.0.0,
+                       microlens >= 0.3.0.0 && < 0.5,
                        microlens-th,
                        microlens-mtl,
                        mtl,
diff --git a/programs/AnimationDemo.hs b/programs/AnimationDemo.hs
--- a/programs/AnimationDemo.hs
+++ b/programs/AnimationDemo.hs
@@ -94,9 +94,9 @@
     [ withDefAttr attr6 $ str "0"
     , withDefAttr attr5 $ str "O"
     , withDefAttr attr4 $ str "o"
-    , withDefAttr attr3 $ str "*"
-    , withDefAttr attr2 $ str "~"
-    , withDefAttr attr1 $ str "."
+    , withDefAttr attr3 $ str "•"
+    , withDefAttr attr2 $ str "*"
+    , withDefAttr attr2 $ str "."
     ]
 
 attr6 :: AttrName
diff --git a/src/Brick/Types/Common.hs b/src/Brick/Types/Common.hs
--- a/src/Brick/Types/Common.hs
+++ b/src/Brick/Types/Common.hs
@@ -24,7 +24,7 @@
 #endif
 
 -- | A terminal screen location.
-data Location = Location { loc :: (Int, Int)
+data Location = Location { loc :: !(Int, Int)
                          -- ^ (Column, Row)
                          }
                 deriving (Show, Eq, Ord, Read, Generic, NFData)
@@ -48,7 +48,7 @@
     mempty = origin
     mappend = (Sem.<>)
 
-data Edges a = Edges { eTop, eBottom, eLeft, eRight :: a }
+data Edges a = Edges { eTop, eBottom, eLeft, eRight :: !a }
     deriving (Eq, Ord, Read, Show, Functor, Generic, NFData)
 
 suffixLenses ''Edges
diff --git a/src/Brick/Types/Internal.hs b/src/Brick/Types/Internal.hs
--- a/src/Brick/Types/Internal.hs
+++ b/src/Brick/Types/Internal.hs
@@ -103,16 +103,16 @@
 import Brick.AttrMap (AttrName, AttrMap)
 import Brick.Widgets.Border.Style (BorderStyle)
 
-data ScrollRequest = HScrollBy Int
-                   | HScrollPage Direction
+data ScrollRequest = HScrollBy !Int
+                   | HScrollPage !Direction
                    | HScrollToBeginning
                    | HScrollToEnd
-                   | VScrollBy Int
-                   | VScrollPage Direction
+                   | VScrollBy !Int
+                   | VScrollPage !Direction
                    | VScrollToBeginning
                    | VScrollToEnd
-                   | SetTop Int
-                   | SetLeft Int
+                   | SetTop !Int
+                   | SetLeft !Int
                    deriving (Read, Show, Generic, NFData)
 
 -- | Widget size policies. These policies communicate how a widget uses
@@ -131,9 +131,9 @@
 
 -- | The type of widgets.
 data Widget n =
-    Widget { hSize :: Size
+    Widget { hSize :: !Size
            -- ^ This widget's horizontal growth policy
-           , vSize :: Size
+           , vSize :: !Size
            -- ^ This widget's vertical growth policy
            , render :: RenderM n (Result n)
            -- ^ This widget's rendering function
@@ -230,21 +230,21 @@
                        }
 
 data VisibilityRequest =
-    VR { vrPosition :: Location
-       , vrSize :: DisplayRegion
+    VR { vrPosition :: !Location
+       , vrSize :: !DisplayRegion
        }
        deriving (Show, Eq, Read, Generic, NFData)
 
 -- | Describes the state of a viewport as it appears as its most recent
 -- rendering.
 data Viewport =
-    VP { _vpLeft :: Int
+    VP { _vpLeft :: !Int
        -- ^ The column offset of left side of the viewport.
-       , _vpTop :: Int
+       , _vpTop :: !Int
        -- ^ The row offset of the top of the viewport.
-       , _vpSize :: DisplayRegion
+       , _vpSize :: !DisplayRegion
        -- ^ The size of the viewport.
-       , _vpContentSize :: DisplayRegion
+       , _vpContentSize :: !DisplayRegion
        -- ^ The size of the contents of the viewport.
        }
        deriving (Show, Read, Generic, NFData)
@@ -274,9 +274,9 @@
        }
 
 data VtyContext =
-    VtyContext { vtyContextBuilder :: IO Vty
-               , vtyContextHandle :: Vty
-               , vtyContextThread :: ThreadId
+    VtyContext { vtyContextBuilder :: !(IO Vty)
+               , vtyContextHandle :: !Vty
+               , vtyContextThread :: !ThreadId
                , vtyContextPutEvent :: Event -> IO ()
                }
 
@@ -330,27 +330,27 @@
 -- | A border character has four segments, one extending in each direction
 -- (horizontally and vertically) from the center of the character.
 data BorderSegment = BorderSegment
-    { bsAccept :: Bool
+    { bsAccept :: !Bool
     -- ^ Would this segment be willing to be drawn if a neighbor wanted to
     -- connect to it?
-    , bsOffer :: Bool
+    , bsOffer :: !Bool
     -- ^ Does this segment want to connect to its neighbor?
-    , bsDraw :: Bool
+    , bsDraw :: !Bool
     -- ^ Should this segment be represented visually?
     } deriving (Eq, Ord, Read, Show, Generic, NFData)
 
 -- | Information about how to redraw a dynamic border character when it abuts
 -- another dynamic border character.
 data DynBorder = DynBorder
-    { dbStyle :: BorderStyle
+    { dbStyle :: !BorderStyle
     -- ^ The 'Char's to use when redrawing the border. Also used to filter
     -- connections: only dynamic borders with equal 'BorderStyle's will connect
     -- to each other.
-    , dbAttr :: Attr
+    , dbAttr :: !Attr
     -- ^ What 'Attr' to use to redraw the border character. Also used to filter
     -- connections: only dynamic borders with equal 'Attr's will connect to
     -- each other.
-    , dbSegments :: Edges BorderSegment
+    , dbSegments :: !(Edges BorderSegment)
     } deriving (Eq, Read, Show, Generic, NFData)
 
 -- | The type of result returned by a widget's rendering function. The
@@ -394,23 +394,23 @@
            }
 
 -- | The type of events.
-data BrickEvent n e = VtyEvent Event
+data BrickEvent n e = VtyEvent !Event
                     -- ^ The event was a Vty event.
-                    | AppEvent e
+                    | AppEvent !e
                     -- ^ The event was an application event.
-                    | MouseDown n Button [Modifier] Location
+                    | MouseDown !n !Button ![Modifier] !Location
                     -- ^ A mouse-down event on the specified region was
                     -- received. The 'n' value is the resource name of
                     -- the clicked widget (see 'clickable').
-                    | MouseUp n (Maybe Button) Location
+                    | MouseUp !n !(Maybe Button) !Location
                     -- ^ A mouse-up event on the specified region was
                     -- received. The 'n' value is the resource name of
                     -- the clicked widget (see 'clickable').
                     deriving (Show, Eq, Ord)
 
-data EventRO n = EventRO { eventViewportMap :: M.Map n Viewport
-                         , latestExtents :: [Extent n]
-                         , oldState :: RenderState n
+data EventRO n = EventRO { eventViewportMap :: !(M.Map n Viewport)
+                         , latestExtents :: ![Extent n]
+                         , oldState :: !(RenderState n)
                          }
 
 -- | Clickable elements of a scroll bar.
@@ -432,22 +432,22 @@
 -- to render, which bordering style should be used, and the attribute map
 -- available for rendering.
 data Context n =
-    Context { ctxAttrName :: AttrName
-            , availWidth :: Int
-            , availHeight :: Int
-            , windowWidth :: Int
-            , windowHeight :: Int
-            , ctxBorderStyle :: BorderStyle
-            , ctxAttrMap :: AttrMap
-            , ctxDynBorders :: Bool
-            , ctxVScrollBarOrientation :: Maybe VScrollBarOrientation
-            , ctxVScrollBarRenderer :: Maybe (VScrollbarRenderer n)
-            , ctxHScrollBarOrientation :: Maybe HScrollBarOrientation
-            , ctxHScrollBarRenderer :: Maybe (HScrollbarRenderer n)
-            , ctxVScrollBarShowHandles :: Bool
-            , ctxHScrollBarShowHandles :: Bool
-            , ctxVScrollBarClickableConstr :: Maybe (ClickableScrollbarElement -> n -> n)
-            , ctxHScrollBarClickableConstr :: Maybe (ClickableScrollbarElement -> n -> n)
+    Context { ctxAttrName :: !AttrName
+            , availWidth :: !Int
+            , availHeight :: !Int
+            , windowWidth :: !Int
+            , windowHeight :: !Int
+            , ctxBorderStyle :: !BorderStyle
+            , ctxAttrMap :: !AttrMap
+            , ctxDynBorders :: !Bool
+            , ctxVScrollBarOrientation :: !(Maybe VScrollBarOrientation)
+            , ctxVScrollBarRenderer :: !(Maybe (VScrollbarRenderer n))
+            , ctxHScrollBarOrientation :: !(Maybe HScrollBarOrientation)
+            , ctxHScrollBarRenderer :: !(Maybe (HScrollbarRenderer n))
+            , ctxVScrollBarShowHandles :: !Bool
+            , ctxHScrollBarShowHandles :: !Bool
+            , ctxVScrollBarClickableConstr :: !(Maybe (ClickableScrollbarElement -> n -> n))
+            , ctxHScrollBarClickableConstr :: !(Maybe (ClickableScrollbarElement -> n -> n))
             }
 
 suffixLenses ''RenderState
diff --git a/src/Brick/Widgets/Core.hs b/src/Brick/Widgets/Core.hs
--- a/src/Brick/Widgets/Core.hs
+++ b/src/Brick/Widgets/Core.hs
@@ -340,7 +340,7 @@
 -- input text should not contain escape sequences or carriage returns.
 txt :: T.Text -> Widget n
 txt s =
-    -- Althoguh vty Image uses lazy Text internally, using lazy text at this
+    -- Although vty Image uses lazy Text internally, using lazy text at this
     -- level may not be an improvement.  Indeed it can be much worse, due
     -- the overhead of lazy Text being significant compared to the typically
     -- short string content used to compose UIs.
diff --git a/src/Brick/Widgets/FileBrowser.hs b/src/Brick/Widgets/FileBrowser.hs
--- a/src/Brick/Widgets/FileBrowser.hs
+++ b/src/Brick/Widgets/FileBrowser.hs
@@ -71,6 +71,7 @@
   , actionFileBrowserBeginSearch
   , actionFileBrowserSelectEnter
   , actionFileBrowserSelectCurrent
+  , actionFileBrowserToggleCurrent
   , actionFileBrowserListPageUp
   , actionFileBrowserListPageDown
   , actionFileBrowserListHalfPageUp
@@ -602,7 +603,7 @@
 --
 -- * @/@: 'actionFileBrowserBeginSearch'
 -- * @Enter@: 'actionFileBrowserSelectEnter'
--- * @Space@: 'actionFileBrowserSelectCurrent'
+-- * @Space@: 'actionFileBrowserToggleCurrent'
 -- * @g@: 'actionFileBrowserListTop'
 -- * @G@: 'actionFileBrowserListBottom'
 -- * @j@: 'actionFileBrowserListNext'
@@ -625,6 +626,10 @@
 actionFileBrowserSelectCurrent =
     selectCurrentEntry
 
+actionFileBrowserToggleCurrent :: EventM n (FileBrowser n) ()
+actionFileBrowserToggleCurrent =
+    toggleCurrentEntrySelected
+
 actionFileBrowserListPageUp :: Ord n => EventM n (FileBrowser n) ()
 actionFileBrowserListPageUp =
     zoom fileBrowserEntriesL listMovePageUp
@@ -697,8 +702,8 @@
             -- Select file or enter directory
             actionFileBrowserSelectEnter
         Vty.EvKey (Vty.KChar ' ') [] ->
-            -- Select entry
-            actionFileBrowserSelectCurrent
+            -- Toggle selected status of current entry
+            actionFileBrowserToggleCurrent
         _ ->
             handleFileBrowserEventCommon e
 
@@ -730,12 +735,27 @@
 
 toggleSelected :: FileInfo -> EventM n (FileBrowser n) ()
 toggleSelected e = do
+    sel <- fileBrowserIsSelected e
+    if sel
+       then fileBrowserRemoveSelected e
+       else fileBrowserAddSelected e
+
+fileBrowserIsSelected :: FileInfo -> EventM n (FileBrowser n) Bool
+fileBrowserIsSelected e = do
     fs <- use fileBrowserSelectedFilesL
     let fName = fileInfoFilename e
-    if Set.member fName fs
-       then fileBrowserSelectedFilesL %= Set.delete fName
-       else fileBrowserSelectedFilesL %= Set.insert fName
+    return $ Set.member fName fs
 
+fileBrowserAddSelected :: FileInfo -> EventM n (FileBrowser n) ()
+fileBrowserAddSelected e = do
+    let fName = fileInfoFilename e
+    fileBrowserSelectedFilesL %= Set.insert fName
+
+fileBrowserRemoveSelected :: FileInfo -> EventM n (FileBrowser n) ()
+fileBrowserRemoveSelected e = do
+    let fName = fileInfoFilename e
+    fileBrowserSelectedFilesL %= Set.delete fName
+
 -- | If the browser's current entry is selectable according to
 -- @fileBrowserSelectable@, add it to the selection set and return.
 -- If not, and if the entry is a directory or a symlink targeting a
@@ -747,12 +767,19 @@
     b <- get
     for_ (fileBrowserCursor b) $ \entry ->
         if fileBrowserSelectable b entry
-        then toggleSelected entry
+        then fileBrowserAddSelected entry
         else when (selectDirectories entry) $
             put =<< liftIO (setWorkingDirectory (fileInfoFilePath entry) b)
 
 selectCurrentEntry :: EventM n (FileBrowser n) ()
 selectCurrentEntry = do
+    b <- get
+    for_ (fileBrowserCursor b) $ \entry ->
+        when (fileBrowserSelectable b entry) $
+            fileBrowserAddSelected entry
+
+toggleCurrentEntrySelected :: EventM n (FileBrowser n) ()
+toggleCurrentEntrySelected = do
     b <- get
     for_ (fileBrowserCursor b) $ \entry ->
         when (fileBrowserSelectable b entry) $
