diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## 0.3.1.1 — 2026-06-06
+
+* Fix selector clicks landing on the wrong column. A regex/substring selector resolved to its matching line's first non-blank column instead of the actual match position, so clicking centred text (e.g. a label behind a box border) hit the line's left edge and missed. `regexOrigins` now reports the match's start column via new origin-returning matchers `regexLikeMatchOrigin`/`wildcardContainsOrigin`, in terms of which the boolean `regexLikeMatch`/`wildcardContains` are now defined (so match and origin can't diverge).
+
 ## 0.3.1.0 — 2026-06-06
 
 * Add mouse click simulation. DSL: `click`/`clickWith` (0-based coordinate) and `clickSelector`/`clickSelectorWith` (Playwright-style, resolves a selector to its match origin and honors `ambiguityMode`). New `MouseButton`, `MouseEncoding`, and `ClickOptions`/`defaultClickOptions` types. JSON-RPC: a `click` method accepting either `{col,row}` (1-based) or `{selector}`, with optional `button` and `encoding`. Clicks emit a press + release; SGR encoding is the default (what `vty`/Brick enable), with an `x10` override.
diff --git a/SKILL.md b/SKILL.md
--- a/SKILL.md
+++ b/SKILL.md
@@ -112,6 +112,12 @@
   ignored. Throws `ChoiceSelectionError` on failure.
 - `artifactRoot tui`, `artifactFile tui rel`, `writeArtifactFile tui rel txt`
   — locate and write into the per-test artifact directory.
+- `click tui col row` / `clickSelector tui selector` — simulate a mouse click
+  at a 0-based coordinate or on the element a selector matches (Playwright
+  style; honors `ambiguityMode`). Use `clickWith` / `clickSelectorWith` with
+  `ClickOptions` to choose the button or the legacy X10 encoding. The target
+  app must have mouse tracking enabled (`vty`/Brick apps do once mouse mode is
+  on); the default SGR encoding suits any modern TUI.
 - `currentViewRect tui rect` — return the viewport text cropped to a region.
 - `dumpFailureBundle` / `withFailureBundle` — capture diagnostic state on
   failure (snapshot + viewport + action log + warnings + exit status).
diff --git a/src/TuiSpec/Internal.hs b/src/TuiSpec/Internal.hs
--- a/src/TuiSpec/Internal.hs
+++ b/src/TuiSpec/Internal.hs
@@ -19,8 +19,10 @@
 
     -- * Pattern matching
     regexLikeMatch,
+    regexLikeMatchOrigin,
     cleanPattern,
     wildcardContains,
+    wildcardContainsOrigin,
 
     -- * Theme helpers
     resolveAutoSnapshotTheme,
@@ -33,6 +35,7 @@
 import Control.Exception (SomeException, catch)
 import Data.Char (isAlphaNum, toLower)
 import Data.List (isSuffixOf)
+import Data.Maybe (isJust)
 import Data.Text (Text)
 import Data.Text qualified as T
 import Text.Read (readMaybe)
@@ -79,7 +82,18 @@
 -}
 regexLikeMatch :: Text -> Text -> Bool
 regexLikeMatch patternText haystack =
-    any (`wildcardContains` haystack) alternatives
+    isJust (regexLikeMatchOrigin patternText haystack)
+
+{- | Like 'regexLikeMatch', but returns the 0-based column where the match
+begins — the start of the first literal segment of the earliest-matching
+alternative. This is the position a user sees and would click, so selector
+clicks must target it rather than, say, the line's first non-blank column.
+-}
+regexLikeMatchOrigin :: Text -> Text -> Maybe Int
+regexLikeMatchOrigin patternText haystack =
+    case [col | alt <- alternatives, Just col <- [wildcardContainsOrigin alt haystack]] of
+        [] -> Nothing
+        cols -> Just (minimum cols)
   where
     alternatives =
         filter (not . T.null) $
@@ -92,7 +106,23 @@
 -- | Check whether a @.*@-delimited pattern matches within a haystack.
 wildcardContains :: Text -> Text -> Bool
 wildcardContains patternText haystack =
-    checkSegments 0 segments
+    isJust (wildcardContainsOrigin patternText haystack)
+
+{- | Like 'wildcardContains', but returns the 0-based start column of the match
+— the position of the first literal (non-@.*@) segment — or 'Nothing'. A
+pattern that is empty or all wildcards matches at column 0.
+-}
+wildcardContainsOrigin :: Text -> Text -> Maybe Int
+wildcardContainsOrigin patternText haystack =
+    case segments of
+        [] -> Just 0
+        (firstSeg : rest) ->
+            let (prefix, suffix) = T.breakOn firstSeg haystack
+                firstCol = T.length prefix
+             in if not (T.null suffix)
+                    && checkSegments (firstCol + T.length firstSeg) rest
+                    then Just firstCol
+                    else Nothing
   where
     segments = filter (not . T.null) (T.splitOn ".*" patternText)
 
diff --git a/src/TuiSpec/Runner.hs b/src/TuiSpec/Runner.hs
--- a/src/TuiSpec/Runner.hs
+++ b/src/TuiSpec/Runner.hs
@@ -91,7 +91,7 @@
 import Test.Tasty (TestTree)
 import Test.Tasty.HUnit (assertFailure, testCase)
 import Text.Read (readMaybe)
-import TuiSpec.Internal (cleanPattern, ignoreIOError, regexLikeMatch, resolveAutoSnapshotTheme, safeFileStem, safeIndex, snapshotMetadataPath, wildcardContains)
+import TuiSpec.Internal (cleanPattern, ignoreIOError, regexLikeMatch, regexLikeMatchOrigin, resolveAutoSnapshotTheme, safeFileStem, safeIndex, snapshotMetadataPath, wildcardContains)
 import TuiSpec.ProjectRoot (resolveProjectRoot)
 import TuiSpec.Replay (RecordingDirection (DirectionFrame), RecordingEvent (..))
 import TuiSpec.Types
@@ -1972,13 +1972,14 @@
             listToMaybe (regexOrigins patternText (viewportText viewport))
 
 {- | All 0-based @(col, row)@ origins of a lightweight regex pattern, one per
-matching line, taken at the line's first non-blank column.
+matching line, at the column where the pattern's first literal segment matches
+(so a selector click lands on the matched text, not the line's left edge).
 -}
 regexOrigins :: Text -> Text -> [(Int, Int)]
 regexOrigins patternText textValue =
-    [ (T.length (T.takeWhile (== ' ') line), rowIdx)
+    [ (col, rowIdx)
     | (rowIdx, line) <- zip [0 ..] (T.lines textValue)
-    , regexLikeMatch patternText line
+    , Just col <- [regexLikeMatchOrigin patternText line]
     ]
 
 -- | All 0-based @(col, row)@ origins of a literal substring within viewport text.
diff --git a/src/TuiSpec/Types.hs b/src/TuiSpec/Types.hs
--- a/src/TuiSpec/Types.hs
+++ b/src/TuiSpec/Types.hs
@@ -168,7 +168,7 @@
 
 -- | The tuispec library/protocol version.
 tuispecVersion :: String
-tuispecVersion = "0.3.1.0"
+tuispecVersion = "0.3.1.1"
 
 -- | Key modifiers for combo key presses.
 data Modifier
diff --git a/tuispec.cabal b/tuispec.cabal
--- a/tuispec.cabal
+++ b/tuispec.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.8
 name: tuispec
-version: 0.3.1.0
+version: 0.3.1.1
 build-type: Simple
 license: MIT
 license-file: LICENSE
