feat(area): add hint when goal list is truncated

Amolith created

When any area has more than 3 goals, the table shows (+N). Users may not
realize they can dig deeper. Now a conditional hint appears below the
table:

(+N) = more goals; run 'lune goal list -a AREA' to see all

Only shown when truncation occurs, keeping the common case clean.

Also documents in AGENTS.md that dim text (ANSI 8) should be avoided for
accessibility—it's unreadable in many terminal color schemes.

Assisted-by: Claude Opus 4.5 via Crush

Change summary

AGENTS.md             |  3 +++
cmd/area/list.go      | 19 ++++++++++++++-----
internal/ui/styles.go |  1 +
3 files changed, 18 insertions(+), 5 deletions(-)

Detailed changes

AGENTS.md 🔗

@@ -209,6 +209,9 @@ Use `cmd.OutOrStdout()` and `cmd.ErrOrStderr()` for testability. Styles are in
 `internal/ui/styles.go`—use `ui.Success`, `ui.Error`, etc. rather than inline
 colors.
 
+**Accessibility**: Avoid dim text (ANSI color 8)—it's unreadable in many terminal
+color schemes. Use italic or other formatting for de-emphasized text instead.
+
 ## Testing
 
 Table-driven tests with `t.Parallel()`. Use `_test` package suffix for black-box

cmd/area/list.go 🔗

@@ -63,9 +63,14 @@ func outputJSON(cmd *cobra.Command, areas []config.Area) error {
 
 func outputTable(cmd *cobra.Command, areas []config.Area) error {
 	rows := make([][]string, 0, len(areas))
+	truncated := false
 
 	for _, area := range areas {
-		goals := formatGoals(area.Goals)
+		goals, wasTruncated := formatGoals(area.Goals)
+		if wasTruncated {
+			truncated = true
+		}
+
 		rows = append(rows, []string{area.Key, area.Name, goals})
 	}
 
@@ -83,12 +88,16 @@ func outputTable(cmd *cobra.Command, areas []config.Area) error {
 
 	fmt.Fprintln(cmd.OutOrStdout(), tbl.Render())
 
+	if truncated {
+		fmt.Fprintln(cmd.OutOrStdout(), ui.Hint.Render("(+N) = more goals; run 'lune goal list -a AREA' to see all"))
+	}
+
 	return nil
 }
 
-func formatGoals(goals []config.Goal) string {
+func formatGoals(goals []config.Goal) (string, bool) {
 	if len(goals) == 0 {
-		return "-"
+		return "-", false
 	}
 
 	keys := make([]string, len(goals))
@@ -97,10 +106,10 @@ func formatGoals(goals []config.Goal) string {
 	}
 
 	if len(keys) <= 3 {
-		return joinKeys(keys)
+		return joinKeys(keys), false
 	}
 
-	return joinKeys(keys[:3]) + fmt.Sprintf(" (+%d)", len(keys)-3)
+	return joinKeys(keys[:3]) + fmt.Sprintf(" (+%d)", len(keys)-3), true
 }
 
 func joinKeys(keys []string) string {

internal/ui/styles.go 🔗

@@ -42,6 +42,7 @@ var (
 	Warning = Style{lipgloss.NewStyle().Foreground(lipgloss.Color("3"))} // yellow
 	Error   = Style{lipgloss.NewStyle().Foreground(lipgloss.Color("1"))} // red
 	Bold    = Style{lipgloss.NewStyle().Bold(true)}
+	Hint    = Style{lipgloss.NewStyle().Italic(true)}
 )
 
 // Heading styles with backgrounds for contrast on any theme.