Improve representation of timed-out values (improve #257)

Change-Id: I2179b58ee62debcc541a80e5eac3443ad9ff11b9
diff --git a/Changes b/Changes
index fc562ce..3478da4 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.60 2025-06-11
+0.60 2025-07-04
         - Tour stops gracefully if there are no results (closes #189; hebasta)
         - Create top navbar and modify sidebar. (uyen-nhu)
         - Improve appearance of title-addon on logo. (uyen-nhu)
@@ -16,6 +16,7 @@
         - Fix test that wrongly required SSL support. (diewald)
         - URLs for plugins are mandatory (closes #233; hebasta)
         - Support non-indexed annotations in match tables (diewald)
+        - Improve explanation of timed-out match counts (diewald)
 
 0.59 2025-03-28
         - Docker only release (diewald)
diff --git a/kalamar.dict b/kalamar.dict
index 0c7349f..847b9f8 100644
--- a/kalamar.dict
+++ b/kalamar.dict
@@ -60,6 +60,10 @@
     pubOn => 'veröffentlicht am',
     matchCount => 'Treffer',
     noMatches => 'Es wurden keine Treffer für <%== loc("searchjob") %> gefunden.',
+    moreMatches => {
+      -short => 'mehr als',
+      long => 'Dieser Wert gibt die Mindestanzahl an Treffern wieder. Die tatsächliche Trefferanzahl kann aufgrund von Sucheinschränkungen nicht angezeigt werden.',
+    },
     notFound => '404 - Seite nicht gefunden',
     notIssued => 'Die Aktion konnte nicht durchgeführt werden.',
     backendNotAvailable => 'Das Backend ist nicht verfügbar unter <code><%= app->korap->api =></code>!',
@@ -181,6 +185,11 @@
     pubOn => 'published on',
     matchCount => '<%= quant($found, "match", "matches") %>',
     noMatches => 'There were no matches found for <%== loc("searchjob") %>.',
+    moreMatches => {
+      -short => 'more than',
+      long => 'This value represents the minimum number of matches in the database. The exact number cannot be displayed due to search restrictions.',
+    },
+
     notFound => '404 - Page not found',
     notIssued => 'Unable to perform the action.',
     backendNotAvailable => 'The backend is not available at <code><%= app->korap->api %></code>!',
diff --git a/t/query.t b/t/query.t
index 924cd73..0d909f4 100644
--- a/t/query.t
+++ b/t/query.t
@@ -286,7 +286,8 @@
 $t->get_ok('/?q=timeout')
   ->status_is(200)
   ->text_like('#notifications div.notify-warn', qr!Response time exceeded!)
-  ->text_is('#total-results', '> 4,274,841');
+  ->text_is('#total-results', ' 4,274,841')
+  ->text_is('#total-results span[title]', 'more than');
 ;
 
 # Query with error
@@ -301,7 +302,8 @@
   # ->text_like('#notifications div.notify-warning', qr!Response time exceeded!)
   ->element_exists("input#cq")
   ->element_exists_not("input#cq[value]")
-  ->text_is('#total-results', '> 4,274,841');
+  ->text_is('#total-results', ' 4,274,841')
+  ->text_is('#total-results span[title]', 'more than');
   ;
 
 $t->app->defaults(no_cache => 1);
diff --git a/templates/search.html.ep b/templates/search.html.ep
index 58a8f38..d912abe 100644
--- a/templates/search.html.ep
+++ b/templates/search.html.ep
@@ -14,9 +14,10 @@
 % if ($found != -1) {
 %   my $found_text = loc('numf', number => $found);
 %   if (stash('time_exceeded')) {
-%     $found_text = '> ' . $found_text;
+%     $found_text = '<span title="' . $c->loc('moreMatches_long') . '">' .
+%     $c->loc('moreMatches') . '</span> ' . $found_text;
 %   };
-<span id="total-results"><%= $found_text %></span> <%= loc('matchCount', found => $found) %>\
+<span id="total-results"><%== $found_text %></span> <%= loc('matchCount', found => $found) %>\
 %# <% if (stash('benchmark')) { %> (~ <%= stash('benchmark') %>)<% } %>
 % } elsif (stash('start_index') == 0 && stash('results')->size == 0) {
 <span id="total-results">0</span> <%= loc('matchCount', found => $found) %>\