texlive[61778] Master/texmf-dist: zref-clever (28jan22)

commits+karl at tug.org commits+karl at tug.org
Fri Jan 28 23:24:51 CET 2022


Revision: 61778
          http://tug.org/svn/texlive?view=revision&revision=61778
Author:   karl
Date:     2022-01-28 23:24:51 +0100 (Fri, 28 Jan 2022)
Log Message:
-----------
zref-clever (28jan22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
    trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
    trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-dutch.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.lang
    trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty

Modified: trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/CHANGELOG.md	2022-01-28 22:24:51 UTC (rev 61778)
@@ -1,7 +1,29 @@
 # Changelog
 
-## [Unreleased](https://github.com/gusbrs/zref-clever/compare/v0.1.2-alpha...HEAD)
+## [Unreleased](https://github.com/gusbrs/zref-clever/compare/v0.2.0-alpha...HEAD)
 
+## [v0.2.0-alpha](https://github.com/gusbrs/zref-clever/compare/v0.1.2-alpha...v0.2.0-alpha) (2022-01-28)
+
+### Added
+- The reference block formatting has been generalized to allow for more
+  flexibility in setting the reference structure, with the new option
+  `refbounds`.
+
+### Fixed
+- Fixed handling of type names defined to be empty.
+- Fixed distinction of `lastsep` and `pairsep` in cases where the type-block
+  starts or ends with a range.
+
+### Changed
+- The `namefont` and `reffont` options can now be set also in
+  `\zcRefTypeSetup` and `\zcLanguageSetup`.
+- (Internal) Moved from property lists to individually named macros to store
+  and retrieve options.
+
+### Deprecated
+- Options `preposinlink`, `preref`, and `postref` have been deprecated and
+  replaced by new option `refbounds`.
+
 ## [v0.1.2-alpha](https://github.com/gusbrs/zref-clever/compare/v0.1.1-alpha...v0.1.2-alpha) (2022-01-10)
 
 ### Added
@@ -34,7 +56,7 @@
 ### Removed
 - Dropped the `subappendix` reference type.
 
-## [v0.1.0-alpha](https://github.com/gusbrs/zref-clever/releases/tag/v0.1.0-alpha) (2021-00-24)
+## [v0.1.0-alpha](https://github.com/gusbrs/zref-clever/releases/tag/v0.1.0-alpha) (2021-11-24)
 
 ### Added
 - Initial release.

Modified: trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/MANIFEST.md	2022-01-28 22:24:51 UTC (rev 61778)
@@ -65,7 +65,9 @@
 different engines (pdfTeX, XeTeX, LuaTeX, etc.).
 
 * zc-LanguageSetup01.lvt 
+* zc-LanguageSetup02.lvt 
 * zc-RefTypeSetup01.lvt 
+* zc-RefTypeSetup02.lvt 
 * zc-class-article01.lvt 
 * zc-class-book01.lvt 
 * zc-class-memoir01.lvt 
@@ -83,6 +85,7 @@
 * zc-compat-memoir01.lvt 
 * zc-compat-subcaption01.lvt 
 * zc-compat-subfig01.lvt 
+* zc-fallback01.lvt 
 * zc-howto-amsmath01.lvt 
 * zc-howto-enumitem01.lvt 
 * zc-howto-listings01.lvt 
@@ -97,8 +100,12 @@
 * zc-howto-newtheorem04.lvt 
 * zc-howto-zref-xr01.lvt 
 * zc-label-options01.lvt 
-* zc-langfiles01.lvt 
-* zc-langfiles02.lvt 
+* zc-langfile-dutch01.lvt 
+* zc-langfile-english01.lvt 
+* zc-langfile-french01.lvt 
+* zc-langfile-german01.lvt 
+* zc-langfile-portuguese01.lvt 
+* zc-langfile-spanish01.lvt 
 * zc-languages01.lvt 
 * zc-opt-check01.lvt 
 * zc-opt-d01.lvt 
@@ -125,16 +132,27 @@
 * zc-typeset01.lvt 
 * zc-workaround-breqn01.lvt 
 * zc-zcref-options01.lvt 
+* zc-zcref-options02.lvt 
 * zc-LanguageSetup01.luatex.tlg 
 * zc-LanguageSetup01.luatexdev.tlg 
 * zc-LanguageSetup01.tlg 
 * zc-LanguageSetup01.xetex.tlg 
 * zc-LanguageSetup01.xetexdev.tlg 
+* zc-LanguageSetup02.luatex.tlg 
+* zc-LanguageSetup02.luatexdev.tlg 
+* zc-LanguageSetup02.tlg 
+* zc-LanguageSetup02.xetex.tlg 
+* zc-LanguageSetup02.xetexdev.tlg 
 * zc-RefTypeSetup01.luatex.tlg 
 * zc-RefTypeSetup01.luatexdev.tlg 
 * zc-RefTypeSetup01.tlg 
 * zc-RefTypeSetup01.xetex.tlg 
 * zc-RefTypeSetup01.xetexdev.tlg 
+* zc-RefTypeSetup02.luatex.tlg 
+* zc-RefTypeSetup02.luatexdev.tlg 
+* zc-RefTypeSetup02.tlg 
+* zc-RefTypeSetup02.xetex.tlg 
+* zc-RefTypeSetup02.xetexdev.tlg 
 * zc-class-article01.luatex.tlg 
 * zc-class-article01.luatexdev.tlg 
 * zc-class-article01.tlg 
@@ -220,6 +238,11 @@
 * zc-compat-subfig01.tlg 
 * zc-compat-subfig01.xetex.tlg 
 * zc-compat-subfig01.xetexdev.tlg 
+* zc-fallback01.luatex.tlg 
+* zc-fallback01.luatexdev.tlg 
+* zc-fallback01.tlg 
+* zc-fallback01.xetex.tlg 
+* zc-fallback01.xetexdev.tlg 
 * zc-howto-amsmath01.luatex.tlg 
 * zc-howto-amsmath01.luatexdev.tlg 
 * zc-howto-amsmath01.tlg 
@@ -288,12 +311,16 @@
 * zc-label-options01.luatex.tlg 
 * zc-label-options01.luatexdev.tlg 
 * zc-label-options01.tlg 
-* zc-langfiles01.tlg 
-* zc-langfiles02.luatex.tlg 
-* zc-langfiles02.luatexdev.tlg 
-* zc-langfiles02.tlg 
-* zc-langfiles02.xetex.tlg 
-* zc-langfiles02.xetexdev.tlg 
+* zc-langfile-dutch01.tlg 
+* zc-langfile-english01.tlg 
+* zc-langfile-french01.tlg 
+* zc-langfile-german01.tlg 
+* zc-langfile-portuguese01.luatex.tlg 
+* zc-langfile-portuguese01.luatexdev.tlg 
+* zc-langfile-portuguese01.tlg 
+* zc-langfile-portuguese01.xetex.tlg 
+* zc-langfile-portuguese01.xetexdev.tlg 
+* zc-langfile-spanish01.tlg 
 * zc-languages01.tlg 
 * zc-opt-check01.luatex.tlg 
 * zc-opt-check01.luatexdev.tlg 
@@ -402,6 +429,11 @@
 * zc-zcref-options01.tlg 
 * zc-zcref-options01.xetex.tlg 
 * zc-zcref-options01.xetexdev.tlg 
+* zc-zcref-options02.luatex.tlg 
+* zc-zcref-options02.luatexdev.tlg 
+* zc-zcref-options02.tlg 
+* zc-zcref-options02.xetex.tlg 
+* zc-zcref-options02.xetexdev.tlg 
 
 
 ## TDS manifest

Modified: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/doc/latex/zref-clever/zref-clever.tex	2022-01-28 22:24:51 UTC (rev 61778)
@@ -591,13 +591,6 @@
 \texttt{nameinlink=tsingle}, and the option given without a value is
 equivalent to \texttt{nameinlink=true}.
 
-\DescribeOption{preposinlink} %
-The \opt{preposinlink} option controls whether the \opt{preref} and
-\opt{postref} reference format options (see \zcref{sec:reference-format}) are
-included in the reference hyperlink or not.  It is a boolean option.  The
-package's default is \texttt{preposinlink=false}, and the option given without
-a value is equivalent to \texttt{preposinlink=true}.
-
 \DescribeOption{lang} %
 The \opt{lang} option controls the language used by \cs{zcref} when looking
 for language-specific reference format options (see
@@ -932,8 +925,7 @@
     type-specific)   & listsep    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                      & lastsep    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
                      & rangesep   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
-                     & preref     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
-                     & postref    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+                     & refbounds  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
 
     \addlinespace
     Typesetting      & Name-sg    &           & $\bullet$ & $\bullet$ &           \\
@@ -946,8 +938,8 @@
                      & name-pl-ab &           & $\bullet$ & $\bullet$ &           \\
 
     \addlinespace
-    Font             & namefont   & $\bullet$ & $\bullet$ &           &           \\
-                     & reffont    & $\bullet$ & $\bullet$ &           &           \\
+    Font             & namefont   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+                     & reffont    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
 
     \addlinespace
     Other            & cap        & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
@@ -967,15 +959,28 @@
 
 \begin{refformat}
 \item \reffmt{ref-block} \(\equiv\)
-\item \reffmt{preref} \reffmt{ref} \reffmt{postref}
+\item \reffmt{preref*}
+  \raisebox{-\baselineskip}{\makebox[0pt]{\^{}}}%
+  \raisebox{-1.2\baselineskip}{\makebox[0pt]{\footnotesize{}hyperlink start}}
+  \reffmt{preref} \reffmt{ref} \reffmt{postref}
+  \raisebox{-\baselineskip}{\makebox[0pt]{\^{}}}%
+  \raisebox{-1.2\baselineskip}{\makebox[0pt]{\footnotesize{}hyperlink end}}
+ \reffmt{postref*}
 \end{refformat}
 
-A \texttt{ref-block} is built for \emph{each} label given as argument to
-\cs{zcref}.  When the \meta{labels} argument is comprised of multiple labels,
-each ``reference type group'', or \texttt{type-group} is potentially made from
-the combination of single reference blocks, ``reference block pairs'',
-``reference block lists'', or ``reference block ranges'', where each is
-respectively built as:
+Where the \opt{refbounds} option, which receives as value a comma separated
+list of four items in the form \texttt{\{preref*,preref,postref,postref*\}},
+sets the surrounding elements to \texttt{ref}.\footnote{As usual, if each of
+  the items contains start or end spaces, or commas anywhere, they must be
+  protected by a pair of braces.  However, care is taken that empty items
+  don't need such protection.  So you can set, for example, something like
+  \texttt{refbounds=\{(,{},{},)\}} to get parentheses around your references,
+  outside the hyperlink.}  A \texttt{ref-block} is built for \emph{each} label
+given as argument to \cs{zcref}.  When the \meta{labels} argument is comprised
+of multiple labels, each ``reference type group'', or \texttt{type-group} is
+potentially made from the combination of single reference blocks, ``reference
+block pairs'', ``reference block lists'', or ``reference block ranges'', where
+each is respectively built as:
 
 \begin{refformat}
 \item \reffmt{type-group} is a combination of:
@@ -1061,8 +1066,7 @@
 language that \pkg{zref-clever} does not know and has no language file for, it
 cannot guess what language that is, and thus has to provide some reasonable
 ``language agnostic'' default, at least for the options for which this makes
-sense (all the ``typesetting'' options, except for the \texttt{[Nn]ame-}
-ones).  Users do not need to have access to this scope, since they know the
+sense.  Users do not need to have access to this scope, since they know the
 language of their document, or know the values they want for those options,
 and can set them as general options, type-specific options, or language
 options through the user interface provided for the purpose.  But the
@@ -1081,11 +1085,90 @@
 listsep  = {,`\textvisiblespace{}'} ,
 lastsep  = {,`\textvisiblespace{}'} ,
 rangesep = {\textendash} ,
-preref   = {} ,
-postref  = {} ,
 \end{zcexample}
 
 
+\subsection{Advanced reference formatting}
+
+The reference format options discussed above and presented in
+\zcref{tab:reference-format} should suffice for most needs.  However, if more
+fine-grained control of the reference format is needed, this can be achieved
+through a more detailed specification of \opt{refbounds} for the different
+cases in which they may occur when a reference is processed.  The options
+available for this purpose are presented in
+\zcref{tab:advanced-reference-format}.
+
+\begin{table}
+  \centering
+  \DeleteShortVerb \|
+  \begin{tabular}{l>{\ttfamily}lcccc}
+    \toprule
+             &          & General   & Type      & \multicolumn{2}{c}{Language} \\
+                                                  \cmidrule(lr){5-6}
+             &          &           &           & Type      & Default   \\
+             &          & (i)       & (ii)      & (iii)     & (iv)      \\
+
+    \midrule
+    Base     & refbounds-first     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+    options  & refbounds-first-sg  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-first-pb  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-first-rb  & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-mid       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-mid-rb    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-mid-re    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-last      & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-last-pe   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & refbounds-last-re   & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+
+    \addlinespace
+    Derived  & +refbounds-first    & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+    options  & +refbounds-mid      & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+    (groups) & +refbounds-last     & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & +refbounds-rb       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & +refbounds-re       & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+             & +refbounds          & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ \\
+    \bottomrule
+  \end{tabular}
+  \caption{Advanced reference format options and their scopes}
+  \zlabel{tab:advanced-reference-format}
+\end{table}
+
+The ``base'' options are the actually operative ones, while the ``derived''
+options are convenience aliases to set multiple base options in one go.  In
+the naming scheme of these options, as is easy to presume, ``\texttt{first}''
+refers to the first reference of a type-block, ``\texttt{mid}'' to the middle
+ones, and ``\texttt{last}'' to the last reference of the type-block.  Less
+obviously, but hopefully still mnemonic enough, ``\texttt{sg}'' stands for
+``single'', ``\texttt{pb}'' and ``\texttt{pe}'' for ``pair begin'' and ``pair
+end'', and finally ``\texttt{rb}'' and ``\texttt{re}'' for ``range begin'' and
+``range end''.  Each of them which receives as value a comma separated list of
+four items in the form \texttt{\{preref*,preref,postref,postref*\}}, just like
+\opt{refbounds}.
+
+The base options are mutually exclusive, which means, for example, that it is
+not sufficient to set \opt{refbounds-first} to define the behavior of all
+first references of a type block.  \opt{refbounds-first} is the value used for
+the first reference when not single, not the beginning of a pair, and not the
+beginning of a range.  Setting a group of them is the purpose of the derived
+options.  Each of these sets all options under it.  Some examples.
+\opt{+refbounds-first} sets \opt{refbounds-first}, \opt{refbounds-first-sg},
+\opt{refbounds-first-pb}, and \opt{refbounds-first-rg}.  In turn,
+\opt{+refbounds-first-rb} sets \opt{refbounds-first-rb} and
+\opt{refbounds-first-rb}.  And quite conveniently, \opt{+refbounds} sets
+\opt{+refbounds-first}, \opt{+refbounds-mid}, and \opt{+refbounds-last}, it is
+hence sufficient to set it to define the behavior of what is typeset around
+all references for the whole type-block.  As you probably guessed by now, the
+\opt{refbounds} option presented in \zcref{tab:reference-format} is an alias
+of \opt{+refbounds}.
+
+Given that base and derived options are actually setting the same group of
+underlying options (the base ones), the order in which they are given is
+relevant: the last one prevails.  The idea here is to use first the derived
+options to set some general defaults, and then change one or another base
+option to handle exceptions as needed.  Of course, how best to use them
+depends on the case.
+
+
 \section{Internationalization}
 \zlabel{sec:internationalization}
 
@@ -1111,7 +1194,7 @@
   will note that \zcref{tab:languages-and-aliases} contains only \pkg{babel}
   language names.}  Users can also set \opt{lang} to a specific language
 directly, in which case \pkg{babel} and \pkg{polyglossia} are disregarded.
-\pkg{zref-clever} provides a number of built-in ``language file'', for the
+\pkg{zref-clever} provides a number of built-in ``language files'', for the
 languages listed in \zcref{tab:languages-and-aliases}, which also includes the
 declared aliases to those languages.
 
@@ -2190,11 +2273,13 @@
   % 2021-08-20: https://tex.stackexchange.com/q/611424/105447 (comments)
   % 2021-09-06: https://github.com/ho-tex/zref/issues/13
   % 2021-10-26: https://github.com/latex3/latex2e/issues/687
+  % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129233#60129233
   Phelype Oleinik,
   % 2021-08-20: https://tex.stackexchange.com/q/611370 (comments)
   % 2021-09-09: https://tex.stackexchange.com/a/614704
   % 2021-10-06: https://tex.stackexchange.com/a/617998
   % 2021-10-21: https://github.com/latex3/latex2e/pull/699
+  % 2022-01-12: https://tex.stackexchange.com/questions/629946/#comment1571118_629946
   Enrico Gregorio,
   % 2021-08-20: https://tex.stackexchange.com/a/611385
   % 2021-08-20: https://tex.stackexchange.com/q/611370/#comment1529282_611385
@@ -2205,6 +2290,8 @@
   % 2021-09-09: https://github.com/latex3/latex3/pull/988
   David Carlisle,
   % 2021-10-10: https://tex.stackexchange.com/questions/618434/#comment1544401_618439
+  % 2022-01-12: https://chat.stackexchange.com/transcript/message/60129096#60129096
+  %             and following discussion.
   Frank Mittelbach,
   % 2021-10-14: https://github.com/latex3/latex2e/issues/687
   `\texttt{samcarter}',

Modified: trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/source/latex/zref-clever/zref-clever.dtx	2022-01-28 22:24:51 UTC (rev 61778)
@@ -162,7 +162,7 @@
 %
 % Identify the package.
 %    \begin{macrocode}
-\ProvidesExplPackage {zref-clever} {2022-01-10} {0.1.2-alpha}
+\ProvidesExplPackage {zref-clever} {2022-01-28} {0.2.0-alpha}
   {Clever LaTeX cross-references based on zref}
 %    \end{macrocode}
 %
@@ -398,7 +398,7 @@
   {
     \bool_if:nTF
       { \prop_if_in_p:Nn \l_@@_counter_resetby_prop {#1} }
-      { \prop_item:Nn  \l_@@_counter_resetby_prop {#1} }
+      { \prop_item:Nn \l_@@_counter_resetby_prop {#1} }
       {
         \seq_map_tokens:Nn \l_@@_counter_resetters_seq
           { \@@_counter_reset_by_aux:nn {#1} }
@@ -523,11 +523,6 @@
   }
 \msg_new:nnn { zref-clever } { key-requires-value }
   { The~'#1'~key~'#2'~requires~a~value~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { key-boolean-or-empty }
-  {
-    The~key~'#1'~only~accepts~the~values~'true',~'false'~
-    or~an~empty~value~\msg_line_context:.
-  }
 \msg_new:nnn { zref-clever } { language-declared }
   { Language~'#1'~is~already~declared~\msg_line_context:.~Nothing~to~do. }
 \msg_new:nnn { zref-clever } { unknown-language-alias }
@@ -544,7 +539,7 @@
   }
 \msg_new:nnn { zref-clever } { unknown-language-opt }
   {
-    Language~'#1'~is~unknown~\msg_line_context:.~Using~default.~
+    Language~'#1'~is~unknown~\msg_line_context:.~
     See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
     '\iow_char:N\\zcDeclareLanguageAlias'.
   }
@@ -607,15 +602,6 @@
   { Option~'#1'~is~only~available~after~\iow_char:N\\begin\{document\}. }
 \msg_new:nnn { zref-clever } { langfile-loaded }
   { Loaded~'#1'~language~file. }
-\msg_new:nnn { zref-clever } { langfile-not-available }
-  { Language~file~for~'#1'~not~available~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { unknown-language-load }
-  {
-    Language~'#1'~is~unknown~\msg_line_context:.~
-    Unable~to~load~language~file.~See~documentation~for~
-    '\iow_char:N\\zcDeclareLanguage'~and~
-    '\iow_char:N\\zcDeclareLanguageAlias'.
-  }
 \msg_new:nnn { zref-clever } { zref-property-undefined }
   {
     Option~'ref=#1'~requested~\msg_line_context:.~
@@ -641,6 +627,12 @@
     Unknown~compatibility~module~'#1'~given~to~option~'nocompat'.~
     Nothing~to~do.
   }
+\msg_new:nnn { zref-clever } { refbounds-must-be-four }
+  {
+    The~value~of~option~'#1'~must~be~a~comma~sepatared~list~
+    of~four~items.~We~received~'#2'~items~\msg_line_context:.~
+    Option~not~set.
+  }
 \msg_new:nnn { zref-clever } { missing-zref-check }
   {
     Option~'check'~requested~\msg_line_context:.~
@@ -652,11 +644,6 @@
   { Reference~property~'#1'~undefined~for~label~'#2'~\msg_line_context:. }
 \msg_new:nnn { zref-clever } { missing-name }
   { Reference~format~option~'#1'~undefined~for~type~'#2'~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { missing-string }
-  {
-    We~couldn't~find~a~value~for~reference~option~'#1'~\msg_line_context:.~
-    But~we~should~have:~throw~a~rock~at~the~maintainer.
-  }
 \msg_new:nnn { zref-clever } { single-element-range }
   { Range~for~type~'#1'~resulted~in~single~element~\msg_line_context:. }
 \msg_new:nnn { zref-clever } { compat-package }
@@ -724,21 +711,414 @@
 % \end{macro}
 %
 %
+% \subsection{Option infra}
+%
+% This section provides the functions in which the variables naming scheme of
+% the package options is embodied, and some basic general functions to query
+% these option variables.
+%
+% I had originally implemented the option handling of the package based on
+% property lists, which are definitely very convenient.  But as the number of
+% options grew, I started to get concerned about the performance implications.
+% That there was a toll was noticeable, even when we could live with it, of
+% course.  Indeed, at the time of writing, the typesetting of a reference
+% queries about 24 different option values, most of them once per type-block,
+% each of these queries can be potentially made in up to 5 option scope
+% levels.  Considering the size of the built-in language files is running at
+% the hundreds, the package does have a lot of work to do in querying option
+% values alone, and thus it is best to smooth things in this area as much as
+% possible.  This also gives me some peace of mind that the package will scale
+% well in the long term.  For some interesting discussion about alternative
+% methods and their performance implications, see
+% \url{https://tex.stackexchange.com/q/147966}.  \contributor{Phelype Oleinik}
+% also offered some insight on the matter at
+% \url{https://tex.stackexchange.com/questions/629946/#comment1571118_629946}.
+% The only real downside of this change is that we can no longer list the
+% whole set of options in place at a given moment, which was useful for the
+% purposes of regression testing, since we don't know what the whole set of
+% active options is.
+%
+%
+% \begin{macro}[EXP]{\@@_opt_varname_general:nn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the general \meta{option}.  The data type of the variable must be
+%   specified (\texttt{tl}, \texttt{seq}, \texttt{bool}, etc.).
+%   \begin{syntax}
+%     \cs{@@_opt_varname_general:nn} \Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_general:nn #1#2
+  { l_@@_opt_general_ #1 _ #2 }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_opt_varname_type:nnn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the type-specific \meta{option} for \meta{ref type}.
+%   \begin{syntax}
+%     \cs{@@_opt_varname_type:nnn} \Arg{ref type} \Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_type:nnn #1#2#3
+  { l_@@_opt_type_ #1 _ #2 _ #3 }
+\cs_generate_variant:Nn \@@_opt_varname_type:nnn { enn , een }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_opt_varname_language:nnn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the language \meta{option} for \meta{lang} (for general language
+%   options, those set with \cs{zcDeclareLanguage}).  The
+%   ``\texttt{lang_unknown}'' branch should be guarded against, such as we
+%   normally should not get there, but this function \emph{must} return some
+%   valid csname.  The random part is there so that, in the circumstance this
+%   could not be avoided, we (hopefully) don't retrieve the value for an
+%   ``unknown language'' inadvertently.
+%   \begin{syntax}
+%     \cs{@@_opt_varname_language:nnn} \Arg{lang} \Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_language:nnn #1#2#3
+  {
+    \@@_language_if_declared:nTF {#1}
+      {
+        g_@@_opt_language_
+        \tl_use:c { \@@_language_varname:n {#1} }
+        _ #2 _ #3
+      }
+      { g_@@_opt_lang_unknown_ \int_rand:n { 1000000 } _ #3 }
+  }
+\cs_generate_variant:Nn \@@_opt_varname_language:nnn { enn }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_opt_varname_lang_default:nnn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the language-specific default reference format \meta{option} for
+%   \meta{lang}.
+%   \begin{syntax}
+%     \cs{@@_opt_varname_lang_default:nnn} \Arg{lang} \Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_lang_default:nnn #1#2#3
+  {
+    \@@_language_if_declared:nTF {#1}
+      {
+        g_@@_opt_lang_
+        \tl_use:c { \@@_language_varname:n {#1} }
+        _default_ #2 _ #3
+      }
+      { g_@@_opt_lang_unknown_ \int_rand:n { 1000000 } _ #3 }
+  }
+\cs_generate_variant:Nn \@@_opt_varname_lang_default:nnn { enn }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_opt_varname_lang_type:nnnn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the language- and type-specific reference format \meta{option}
+%   for \meta{lang} and \meta{ref type}.
+%   \begin{syntax}
+%     \cs{@@_opt_varname_lang_type:nnnn} \Arg{lang} \Arg{ref type}
+%     ~~\Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_lang_type:nnnn #1#2#3#4
+  {
+    \@@_language_if_declared:nTF {#1}
+      {
+        g_@@_opt_lang_
+        \tl_use:c { \@@_language_varname:n {#1} }
+        _type_ #2 _ #3 _ #4
+      }
+      { g_@@_opt_lang_unknown_ \int_rand:n { 1000000 } _ #4 }
+  }
+\cs_generate_variant:Nn
+  \@@_opt_varname_lang_type:nnnn { eenn , eeen }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_opt_varname_fallback:nn}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the fallback \meta{option}.
+%   \begin{syntax}
+%     \cs{@@_opt_varname_fallback:nn} \Arg{option} \Arg{data type}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_opt_varname_fallback:nn #1#2
+  { c_@@_opt_fallback_ #1 _ #2 }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}
+%   {
+%     \@@_opt_tl_unset:N ,
+%     \@@_opt_tl_gunset:N ,
+%   }
+%   Unset \meta{option tl}.  These functions \emph{define} what means to be
+%   unset for an option token list, and it must match what the conditional
+%   \cs{@@_opt_tl_if_set:N} tests for.
+%   \begin{syntax}
+%     \cs{@@_opt_tl_unset:N} \Arg{option tl}
+%     \cs{@@_opt_tl_gunset:N} \Arg{option tl}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_opt_tl_unset:N #1
+  { \tl_set_eq:NN #1 \c_novalue_tl }
+\cs_new_protected:Npn \@@_opt_tl_gunset:N #1
+  { \tl_gset_eq:NN #1 \c_novalue_tl }
+\cs_generate_variant:Nn \@@_opt_tl_unset:N { c }
+\cs_generate_variant:Nn \@@_opt_tl_gunset:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,TF]{\@@_opt_tl_if_set:N}
+%   \begin{syntax}
+%     \cs{@@_opt_tl_if_set:N(TF)} \Arg{option tl} \Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_opt_tl_if_set:N #1 { F , TF }
+  {
+    \bool_lazy_and:nnTF
+      { \tl_if_exist_p:N #1 }
+      { ! \tl_if_novalue_p:n {#1} }
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_opt_tl_gset_if_new:Nn}
+%   \begin{syntax}
+%     \cs{@@_opt_tl_gset_if_new:Nn} \Arg{option tl} \Arg{value}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_opt_tl_gset_if_new:Nn #1#2
+  {
+    \@@_opt_tl_if_set:NF #1
+      { \tl_gset:Nn #1 {#2} }
+  }
+\cs_generate_variant:Nn \@@_opt_tl_gset_if_new:Nn { cn }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_opt_tl_get:NN}
+%   \begin{syntax}
+%     \cs{@@_opt_tl_get:NN(TF)} \Arg{option tl to get} \Arg{tl var to set}
+%     ~~\Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_opt_tl_get:NN #1#2 { F }
+  {
+    \@@_opt_tl_if_set:NTF #1
+      {
+        \tl_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_tl_get:NN { cN } { F }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}
+%   {
+%     \@@_opt_seq_set_clist_split:Nn ,
+%     \@@_opt_seq_gset_clist_split:Nn ,
+%   }
+%   \begin{syntax}
+%     \cs{@@_opt_seq_set_clist_split:Nn} \Arg{option seq} \Arg{value}
+%     \cs{@@_opt_seq_gset_clist_split:Nn} \Arg{option seq} \Arg{value}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_opt_seq_set_clist_split:Nn #1#2
+  { \seq_set_split:Nnn #1 { , } {#2} }
+\cs_new_protected:Npn \@@_opt_seq_gset_clist_split:Nn #1#2
+  { \seq_gset_split:Nnn #1 { , } {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_opt_seq_unset:N ,
+%     \@@_opt_seq_gunset:N ,
+%   }
+%   Unset \meta{option seq}.  These functions \emph{define} what means to be
+%   unset for an option sequence, and it must match what the conditional
+%   \cs{@@_opt_seq_if_set:N} tests for.
+%   \begin{syntax}
+%     \cs{@@_opt_seq_unset:N} \Arg{option seq}
+%     \cs{@@_opt_seq_gunset:N} \Arg{option seq}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_opt_seq_unset:N #1
+  { \cs_set_eq:NN #1 \scan_stop: }
+\cs_new_protected:Npn \@@_opt_seq_gunset:N #1
+  { \cs_gset_eq:NN #1 \scan_stop: }
+\cs_generate_variant:Nn \@@_opt_seq_unset:N { c }
+\cs_generate_variant:Nn \@@_opt_seq_gunset:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,TF]{\@@_opt_seq_if_set:N}
+%   \begin{syntax}
+%     \cs{@@_opt_seq_if_set:N(TF)} \Arg{option seq} \Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_opt_seq_if_set:N #1 { F , TF }
+  { \seq_if_exist:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_seq_if_set:N { c } { F , TF }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\@@_opt_seq_get:NN}
+%   \begin{syntax}
+%     \cs{@@_opt_seq_get:NN(TF)} \Arg{option seq to get} \Arg{seq var to set}
+%     ~~\Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_opt_seq_get:NN #1#2 { F }
+  {
+    \@@_opt_seq_if_set:NTF #1
+      {
+        \seq_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_seq_get:NN { cN } { F }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}
+%   {
+%     \@@_opt_bool_unset:N ,
+%     \@@_opt_bool_gunset:N ,
+%   }
+%   Unset \meta{option bool}.  These functions \emph{define} what means to be
+%   unset for an option boolean, and it must match what the conditional
+%   \cs{@@_opt_bool_if_set:N} tests for.  The particular definition we are
+%   employing here has some relevant implications.  Setting the boolean
+%   variable to \cs{scan_stop:} (aka, \cs{relax}) means we can \emph{never}
+%   test the variable without first testing if it is \emph{set}.
+%   \cs{@@_opt_bool_if:N} does this conveniently.
+%   \begin{syntax}
+%     \cs{@@_opt_bool_unset:N} \Arg{option bool}
+%     \cs{@@_opt_bool_gunset:N} \Arg{option bool}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_opt_bool_unset:N #1
+  { \cs_set_eq:NN #1 \scan_stop: }
+\cs_new_protected:Npn \@@_opt_bool_gunset:N #1
+  { \cs_gset_eq:NN #1 \scan_stop: }
+\cs_generate_variant:Nn \@@_opt_bool_unset:N { c }
+\cs_generate_variant:Nn \@@_opt_bool_gunset:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,TF]{\@@_opt_bool_if_set:N}
+%   \begin{syntax}
+%     \cs{@@_opt_bool_if_set:N(TF)} \Arg{option bool} \Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_opt_bool_if_set:N #1 { F , TF }
+  { \bool_if_exist:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_bool_if_set:N { c } { F , TF }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[TF]{\@@_opt_bool_get:NN}
+%   \begin{syntax}
+%     \cs{@@_opt_bool_get:NN(TF)} \Arg{option bool to get} \Arg{bool var to set}
+%     ~~\Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_opt_bool_get:NN #1#2 { F }
+  {
+    \@@_opt_bool_if_set:NTF #1
+      {
+        \bool_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_bool_get:NN { cN } { F }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,TF]{\@@_opt_bool_if:N}
+%   \begin{syntax}
+%     \cs{@@_opt_bool_if:N(TF)} \Arg{option bool} \Arg{true} \Arg{false}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_opt_bool_if:N #1 { T , F , TF }
+  {
+    \@@_opt_bool_if_set:NTF #1
+      { \bool_if:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \@@_opt_bool_if:N { c } { T , F , TF }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
 % \subsection{Reference format}
 %
 % For a general discussion on the precedence rules for reference format
 % options, see Section ``Reference format'' in the User manual.  Internally,
-% these precedence rules are handled / enforced in
-% \cs{@@_get_ref_opt_typeset:nN}, \cs{@@_get_ref_opt_font:nN}, and
+% these precedence rules are handled / enforced in \cs{@@_get_rf_opt_tl:nnnN},
+% \cs{@@_get_rf_opt_seq:nnnN}, \cs{@@_get_rf_opt_bool:nnnnN}, and
 % \cs{@@_type_name_setup:} which are the basic functions to retrieve proper
-% values for reference format settings.  The ``fallback'' settings are stored
-% in \cs{g_@@_fallback_unknown_lang_prop}.
+% values for reference format settings.
 %
+% The fact that we have multiple scopes to set reference format options has
+% some implications for how we handle these options, and for the resulting UI.
+% Since there is a clear precedence rule between the different levels, setting
+% an option at a high priority level shadows everything below it.  Hence, it
+% may be relevant to be able to ``unset'' these options too, so as to be able
+% go back to the lower precedence level of the language-specific options at
+% any given point.  However, since many of these options are token lists, or
+% clists, for which ``empty'' is a legitimate value, we cannot rely on
+% emptiness to distinguish that particular intention.  How to deal with it,
+% depends on the kind of option (its data type, to be precise).  For token
+% lists and clists/sequences, we leverage the distinction of an ``empty valued
+% key'' (\texttt{key=} or \texttt{key=\{\}}) from a ``key with no value''
+% (\texttt{key}).  This distinction is captured internally by the lower-level
+% key parsing, but must be made explicit in \cs{keys_define:nn} by means of
+% the \texttt{.default:x} property of the key.  For the technique, by
+% \contributor{Jonathan P.\ Spratte}, aka `Skillmon', and some discussion
+% about it, including further insights by \contributor{Phelype Oleinik}, see
+% \url{https://tex.stackexchange.com/q/614690} and
+% \url{https://github.com/latex3/latex3/pull/988}.  For booleans, the
+% situation is different, since they cannot meaningfully receive an empty
+% value and the ``key with no value'' is a handy and expected shorthand for
+% \texttt{key=true}.  Therefore, for reference format option booleans, we use
+% a third value ``\texttt{unset}'' for this purpose.  In the language files
+% the ``unsetting'' behavior is less meaningful, since they only change any
+% variable if it is unset to start with, so that unsetting an unset variable
+% would be redundant.  However, for UI symmetry also in the language files
+% keys with no value should not be considered ``empty'' and boolean
+% \texttt{unset} values should exist.  They are just no-op.
 %
+%
 % \begin{macro}
 %   {
 %     \l_@@_setup_type_tl ,
-%     \l_@@_base_language_tl ,
+%     \l_@@_setup_language_tl ,
 %     \l_@@_lang_decl_case_tl ,
 %     \l_@@_lang_declension_seq ,
 %     \l_@@_lang_gender_seq ,
@@ -746,11 +1126,10 @@
 %   Store ``current'' type, language, and declension cases in different places
 %   for type-specific and language-specific options handling, notably in
 %   \cs{@@_provide_langfile:n}, \cs{zcRefTypeSetup}, and
-%   \cs{zcLanguageSetup}.  But also for language options retrieval, in
-%   \cs{@@_get_lang_opt_type:nnnN} and \cs{@@_get_lang_opt_default:nnN}.
+%   \cs{zcLanguageSetup}, but also for language specific options retrieval.
 %    \begin{macrocode}
 \tl_new:N \l_@@_setup_type_tl
-\tl_new:N \l_@@_base_language_tl
+\tl_new:N \l_@@_setup_language_tl
 \tl_new:N \l_@@_lang_decl_case_tl
 \seq_new:N \l_@@_lang_declension_seq
 \seq_new:N \l_@@_lang_gender_seq
@@ -760,20 +1139,22 @@
 %
 % \begin{macro}
 %   {
-%     \c_@@_ref_options_necessarily_not_type_specific_seq ,
-%     \c_@@_ref_options_possibly_type_specific_seq ,
-%     \c_@@_ref_options_type_names_seq ,
-%     \c_@@_ref_options_font_seq ,
-%     \c_@@_ref_options_typesetup_seq ,
-%     \c_@@_ref_options_reference_seq ,
+%     \c_@@_rf_opts_tl_not_type_specific_seq ,
+%     \c_@@_rf_opts_tl_maybe_type_specific_seq ,
+%     \c_@@_rf_opts_seq_refbounds_seq ,
+%     \c_@@_rf_opts_bool_maybe_type_specific_seq ,
+%     \c_@@_rf_opts_tl_type_names_seq ,
+%     \c_@@_rf_opts_tl_font_seq ,
+%     \c_@@_rf_opts_tl_typesetup_seq ,
+%     \c_@@_rf_opts_tl_reference_seq ,
 %   }
-%     Lists of reference format related options in ``categories''.  Since
-%     these options are set in different scopes, and at different places,
-%     storing the actual lists in centralized variables makes the job not only
-%     easier later on, but also keeps things consistent.
+%     Lists of reference format options in ``categories''.  Since these
+%     options are set in different scopes, and at different places, storing
+%     the actual lists in centralized variables makes the job not only easier
+%     later on, but also keeps things consistent.
 %    \begin{macrocode}
 \seq_const_from_clist:Nn
-  \c_@@_ref_options_necessarily_not_type_specific_seq
+  \c_@@_rf_opts_tl_not_type_specific_seq
   {
     tpairsep ,
     tlistsep ,
@@ -781,7 +1162,7 @@
     notesep ,
   }
 \seq_const_from_clist:Nn
-  \c_@@_ref_options_possibly_type_specific_seq
+  \c_@@_rf_opts_tl_maybe_type_specific_seq
   {
     namesep ,
     pairsep ,
@@ -788,17 +1169,37 @@
     listsep ,
     lastsep ,
     rangesep ,
-    preref ,
-    postref ,
+    namefont ,
+    reffont ,
   }
+\seq_const_from_clist:Nn
+  \c_@@_rf_opts_seq_refbounds_seq
+  {
+    refbounds-first ,
+    refbounds-first-sg ,
+    refbounds-first-pb ,
+    refbounds-first-rb ,
+    refbounds-mid ,
+    refbounds-mid-rb ,
+    refbounds-mid-re ,
+    refbounds-last ,
+    refbounds-last-pe ,
+    refbounds-last-re ,
+  }
+\seq_const_from_clist:Nn
+  \c_@@_rf_opts_bool_maybe_type_specific_seq
+  {
+    cap ,
+    abbrev ,
+  }
 %    \end{macrocode}
 % Only ``type names'' are ``necessarily type-specific'', which makes them
 % somewhat special on the retrieval side of things.  In short, they don't have
-% their values queried by \cs{@@_get_ref_opt_typeset:nN}, but by
+% their values queried by \cs{@@_get_rf_opt_tl:nnnN}, but by
 % \cs{@@_type_name_setup:}.
 %    \begin{macrocode}
 \seq_const_from_clist:Nn
-  \c_@@_ref_options_type_names_seq
+  \c_@@_rf_opts_tl_type_names_seq
   {
     Name-sg ,
     name-sg ,
@@ -810,71 +1211,156 @@
     name-pl-ab ,
   }
 %    \end{macrocode}
-% \cs{c_@@_ref_options_font_seq} are technically ``possibly type-specific'',
-% but are not ``language-specific'', so we separate them.
+% And, finally, some combined groups of the above variables, for convenience.
 %    \begin{macrocode}
-\seq_const_from_clist:Nn
-  \c_@@_ref_options_font_seq
+\seq_new:N \c_@@_rf_opts_tl_typesetup_seq
+\seq_gconcat:NNN \c_@@_rf_opts_tl_typesetup_seq
+  \c_@@_rf_opts_tl_maybe_type_specific_seq
+  \c_@@_rf_opts_tl_type_names_seq
+\seq_new:N \c_@@_rf_opts_tl_reference_seq
+\seq_gconcat:NNN \c_@@_rf_opts_tl_reference_seq
+  \c_@@_rf_opts_tl_not_type_specific_seq
+  \c_@@_rf_opts_tl_maybe_type_specific_seq
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% We set here also the ``derived'' \texttt{refbounds} options, which are the
+% same for every option scope.
+%
+%    \begin{macrocode}
+\clist_map_inline:nn
   {
-    namefont ,
-    reffont ,
+    reference ,
+    typesetup ,
+    langsetup ,
+    langfile ,
   }
+  {
+    \keys_define:nn { zref-clever/ #1 }
+      {
+        +refbounds-first .meta:n =
+          {
+            refbounds-first = {##1} ,
+            refbounds-first-sg = {##1} ,
+            refbounds-first-pb = {##1} ,
+            refbounds-first-rb = {##1} ,
+          } ,
+        +refbounds-first .default:x = \c_novalue_tl ,
+        +refbounds-mid .meta:n =
+          {
+            refbounds-mid = {##1} ,
+            refbounds-mid-rb = {##1} ,
+            refbounds-mid-re = {##1} ,
+          } ,
+        +refbounds-mid .default:x = \c_novalue_tl ,
+        +refbounds-last .meta:n =
+          {
+            refbounds-last = {##1} ,
+            refbounds-last-pe = {##1} ,
+            refbounds-last-re = {##1} ,
+          } ,
+        +refbounds-last .default:x = \c_novalue_tl ,
+        +refbounds-rb .meta:n =
+          {
+            refbounds-first-rb = {##1} ,
+            refbounds-mid-rb = {##1} ,
+          } ,
+        +refbounds-rb .default:x = \c_novalue_tl ,
+        +refbounds-re .meta:n =
+          {
+            refbounds-mid-re = {##1} ,
+            refbounds-last-re = {##1} ,
+          } ,
+        +refbounds-re .default:x = \c_novalue_tl ,
+        +refbounds .meta:n =
+          {
+            +refbounds-first = {##1} ,
+            +refbounds-mid = {##1} ,
+            +refbounds-last = {##1} ,
+          } ,
+        +refbounds .default:x = \c_novalue_tl ,
+        refbounds .meta:n = { +refbounds = {##1} } ,
+        refbounds .default:x = \c_novalue_tl ,
+      }
+  }
 %    \end{macrocode}
-% And, finally, some combined groups of the above variables, for convenience.
+%
+%
+% \subsection{Languages}
+%
+%
+% \begin{macro}[EXP]{\@@_language_varname:n}
+%   Defines, and leaves in the input stream, the csname of the variable used
+%   to store the \meta{base language} (as the value of this variable) for
+%   a \meta{language} declared for \pkg{zref-clever}.
+%   \begin{syntax}
+%     \cs{@@_language_varname:n} \Arg{language}
+%   \end{syntax}
 %    \begin{macrocode}
-\seq_new:N \c_@@_ref_options_typesetup_seq
-\seq_gconcat:NNN \c_@@_ref_options_typesetup_seq
-  \c_@@_ref_options_possibly_type_specific_seq
-  \c_@@_ref_options_type_names_seq
-\seq_gconcat:NNN \c_@@_ref_options_typesetup_seq
-  \c_@@_ref_options_typesetup_seq
-  \c_@@_ref_options_font_seq
-\seq_new:N \c_@@_ref_options_reference_seq
-\seq_gconcat:NNN \c_@@_ref_options_reference_seq
-  \c_@@_ref_options_necessarily_not_type_specific_seq
-  \c_@@_ref_options_possibly_type_specific_seq
-\seq_gconcat:NNN \c_@@_ref_options_reference_seq
-  \c_@@_ref_options_reference_seq
-  \c_@@_ref_options_font_seq
+\cs_new:Npn \@@_language_varname:n #1
+  { g_@@_declared_language_ #1 _tl }
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\zrefclever_language_varname:n}
+%   A public version of \cs{@@_language_varname:n} for use in
+%   \pkg{zref-vario}.
+%    \begin{macrocode}
+\cs_set_eq:NN \zrefclever_language_varname:n
+  \@@_language_varname:n
+%    \end{macrocode}
+% \end{macro}
 %
+% \begin{macro}[EXP,TF]{\@@_language_if_declared:n}
+%   A language is considered to be declared for \pkg{zref-clever} if it passes
+%   this conditional, which requires that a variable with
+%   \cs{@@_language_varname:n}\texttt{\{\meta{language}\}} exists.
+%   \begin{syntax}
+%     \cs{@@_language_if_declared:n(TF)} \Arg{language}
+%   \end{syntax}
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_language_if_declared:n #1 { T , F , TF }
+  {
+    \tl_if_exist:cTF { \@@_language_varname:n {#1} }
+     { \prg_return_true:  }
+     { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \@@_language_if_declared:n { x } { T , F , TF }
+%    \end{macrocode}
+% \end{macro}
 %
-% \subsection{Languages}
-%
-% \begin{macro}{\g_@@_languages_prop}
-%   Stores the names of known languages and the mapping from ``language name''
-%   to ``base language name''.  Whether or not a language or alias is known to
-%   \pkg{zref-clever} is decided by its presence in this property list.  A
-%   ``base language'' (loose concept here, meaning just ``the name we gave for
-%   the language file in that particular language'') is just like any other
-%   one, the only difference is that the ``language name'' happens to be the
-%   same as the ``base language name'', in other words, it is an ``alias to
-%   itself''.
+% \begin{macro}[EXP,TF]{\zrefclever_language_if_declared:n}
+%   A public version of \cs{@@_language_if_declared:n} for use in
+%   \pkg{zref-vario}.
 %    \begin{macrocode}
-\prop_new:N \g_@@_languages_prop
+\prg_set_eq_conditional:NNn \zrefclever_language_if_declared:n
+  \@@_language_if_declared:n { TF }
 %    \end{macrocode}
 % \end{macro}
 %
 %
 % \begin{macro}[int]{\zcDeclareLanguage}
-%   Declare a new language for use with \pkg{zref-clever}.  \meta{language} is
-%   taken to be both the ``language name'' and the ``base language name''.
-%   \oarg{options} receive a \texttt{k=v} set of options, with three valid
-%   options.  The first, \opt{declension}, takes the noun declension cases
-%   prefixes for \meta{language} as a comma separated list, whose first
-%   element is taken to be the default case.  The second, \opt{gender},
-%   receives the genders for \meta{language} as comma separated list.  The
-%   third, \opt{allcaps}, receives no value, and indicates that for
-%   \meta{language} all nouns must be capitalized for grammatical reasons, in
-%   which case, the \opt{cap} option is disregarded for \meta{language}.  If
-%   \meta{language} is already known, just warn.  This implies a particular
-%   restriction regarding \oarg{options}, namely that these options, when
-%   defined by the package, cannot be redefined by the user.  This is
-%   deliberate, otherwise the built-in language files would become much too
-%   sensitive to this particular user input, and unnecessarily so.
-%   \cs{zcDeclareLanguage} is preamble only.
+% Declare a new language for use with \pkg{zref-clever}.  \meta{language} is
+% taken to be both the ``language name'' and the ``base language name''.  A
+% ``base language'' (loose concept here, meaning just ``the name we gave for
+% the language file in that particular language'') is just like any other one,
+% the only difference is that the ``language name'' happens to be the same as
+% the ``base language name'', in other words, it is an ``alias to itself''.
+% \oarg{options} receive a \texttt{k=v} set of options, with three valid
+% options.  The first, \opt{declension}, takes the noun declension cases
+% prefixes for \meta{language} as a comma separated list, whose first element
+% is taken to be the default case.  The second, \opt{gender}, receives the
+% genders for \meta{language} as comma separated list.  The third,
+% \opt{allcaps}, is a boolean, and indicates that for \meta{language} all
+% nouns must be capitalized for grammatical reasons, in which case, the
+% \opt{cap} option is disregarded for \meta{language}.  If \meta{language} is
+% already known, just warn.  This implies a particular restriction regarding
+% \oarg{options}, namely that these options, when defined by the package,
+% cannot be redefined by the user.  This is deliberate, otherwise the built-in
+% language files would become much too sensitive to this particular user
+% input, and unnecessarily so.  \cs{zcDeclareLanguage} is preamble only.
 %   \begin{syntax}
 %     \cs{zcDeclareLanguage} \oarg{options} \marg{language}
 %   \end{syntax}
@@ -884,13 +1370,13 @@
     \group_begin:
     \tl_if_empty:nF {#2}
       {
-        \prop_if_in:NnTF \g_@@_languages_prop {#2}
+        \@@_language_if_declared:nTF {#2}
           { \msg_warning:nnn { zref-clever } { language-declared } {#2} }
           {
-            \prop_gput:Nnn \g_@@_languages_prop {#2} {#2}
-            \prop_new:c { g_@@_lang_ #2 _prop }
-            \tl_set:Nn \l_@@_base_language_tl {#2}
-            \keys_set:nn { zref-clever / declarelang } {#1}
+            \tl_new:c { \@@_language_varname:n {#2} }
+            \tl_gset:cn { \@@_language_varname:n {#2} } {#2}
+            \tl_set:Nn \l_@@_setup_language_tl {#2}
+            \keys_set:nn { zref-clever/declarelang } {#1}
           }
       }
     \group_end:
@@ -903,7 +1389,7 @@
 % \begin{macro}[int]{\zcDeclareLanguageAlias}
 %   Declare \meta{language alias} to be an alias of \meta{aliased language}
 %   (or ``base language'').  \meta{aliased language} must be already known to
-%   \pkg{zref-clever}, as stored in \cs{g_@@_languages_prop}.
+%   \pkg{zref-clever}.
 %   \cs{zcDeclareLanguageAlias} is preamble only.
 %   \begin{syntax}
 %     \cs{zcDeclareLanguageAlias} \marg{language alias} \marg{aliased language}
@@ -913,11 +1399,10 @@
   {
     \tl_if_empty:nF {#1}
       {
-        \prop_if_in:NnTF \g_@@_languages_prop {#2}
+        \@@_language_if_declared:nTF {#2}
           {
-            \exp_args:NNnx
-              \prop_gput:Nnn \g_@@_languages_prop {#1}
-                { \prop_item:Nn \g_@@_languages_prop {#2} }
+            \tl_gset:cx { \@@_language_varname:n {#1} }
+              { \tl_use:c { \@@_language_varname:n {#2} } }
           }
           { \msg_warning:nnn { zref-clever } { unknown-language-alias } {#2} }
       }
@@ -929,50 +1414,60 @@
 %
 %
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / declarelang }
+\keys_define:nn { zref-clever/declarelang }
   {
     declension .code:n =
       {
-        \prop_gput:cnn
-          { g_@@_lang_ \l_@@_base_language_tl _prop }
-          { declension } {#1}
+        \seq_gset_from_clist:cn
+          {
+            \@@_opt_varname_language:enn
+              { \l_@@_setup_language_tl } { declension } { seq }
+          }
+          {#1}
       } ,
     declension .value_required:n = true ,
     gender .code:n =
       {
-        \prop_gput:cnn
-          { g_@@_lang_ \l_@@_base_language_tl _prop }
-          { gender } {#1}
+        \seq_gset_from_clist:cn
+          {
+            \@@_opt_varname_language:enn
+              { \l_@@_setup_language_tl } { gender } { seq }
+          }
+          {#1}
       } ,
     gender .value_required:n = true ,
-    allcaps .code:n =
+    allcaps .choices:nn =
+      { true , false }
       {
-        \prop_gput:cnn
-          { g_@@_lang_ \l_@@_base_language_tl _prop }
-          { allcaps } { true }
+        \use:c { bool_gset_ \l_keys_choice_tl :c }
+          {
+            \@@_opt_varname_language:enn
+              { \l_@@_setup_language_tl } { allcaps } { bool }
+          }
       } ,
-    allcaps .value_forbidden:n = true ,
+    allcaps .default:n = true ,
   }
 %    \end{macrocode}
 %
 %
 %
-% \begin{macro}{\@@_process_language_options:}
+% \begin{macro}{\@@_process_language_settings:}
 %   Auxiliary function for \cs{@@_zcref:nnn}, responsible for processing
-%   options from \cs{zcDeclareLanguage}.  It is necessary to separate them
-%   from the reference options machinery because their behavior is language
-%   dependent, but the language itself can also be set as an option
-%   (\opt{lang}, value stored in \cs{l_@@_ref_language_tl}).  Hence, we must
-%   validate these options after the reference options have been set.  It is
-%   expected to be called right (or soon) after \cs{keys_set:nn} in
-%   \cs{@@_zcref:nnn}, where current values for \cs{l_@@_ref_language_tl} and
-%   \cs{l_@@_ref_decl_case_tl} are in place.
+%   language related settings.  It is necessary to separate them from the
+%   reference options machinery for two reasons.  First, because their
+%   behavior is language dependent, but the language itself can also be set as
+%   an option (\opt{lang}, value stored in \cs{l_@@_ref_language_tl}).
+%   Second, some of its tasks must be done regardless of any option being
+%   given (e.g. the default declension case, the \opt{allcaps} option).
+%   Hence, we must validate the language settings after the reference options
+%   have been set.  It is expected to be called right (or soon) after
+%   \cs{keys_set:nn} in \cs{@@_zcref:nnn}, where current values for
+%   \cs{l_@@_ref_language_tl} and \cs{l_@@_ref_decl_case_tl} are in place.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_process_language_options:
+\cs_new_protected:Npn \@@_process_language_settings:
   {
-    \exp_args:NNx \prop_get:NnNTF \g_@@_languages_prop
+    \@@_language_if_declared:xTF
       { \l_@@_ref_language_tl }
-      \l_@@_base_language_tl
       {
 %    \end{macrocode}
 % Validate the declension case (\opt{d}) option against the declared cases for
@@ -982,16 +1477,13 @@
 % clearing the variable, depending on the language setup.  And also issues a
 % warning about it.
 %    \begin{macrocode}
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l_@@_lang_declension_seq
+        \@@_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g_@@_lang_
-                \l_@@_base_language_tl _prop
-              }
-              { declension }
+            \@@_opt_varname_language:enn
+              { \l_@@_ref_language_tl } { declension } { seq }
           }
+          \l_@@_lang_declension_seq
+          { \seq_clear:N \l_@@_lang_declension_seq }
         \seq_if_empty:NTF \l_@@_lang_declension_seq
           {
             \tl_if_empty:NF \l_@@_ref_decl_case_tl
@@ -1027,16 +1519,13 @@
 % reference language.  If the user value for the latter does not match the
 % genders declared for the former, clear \cs{l_@@_ref_gender_tl} and warn.
 %    \begin{macrocode}
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l_@@_lang_gender_seq
+        \@@_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g_@@_lang_
-                \l_@@_base_language_tl _prop
-              }
-              { gender }
+            \@@_opt_varname_language:enn
+              { \l_@@_ref_language_tl } { gender } { seq }
           }
+          \l_@@_lang_gender_seq
+          { \seq_clear:N \l_@@_lang_gender_seq }
         \seq_if_empty:NTF \l_@@_lang_gender_seq
           {
             \tl_if_empty:NF \l_@@_ref_gender_tl
@@ -1064,20 +1553,15 @@
               }
           }
 %    \end{macrocode}
-% Ensure the \opt{cap} in \cs{l_@@_ref_options_prop} is set to \texttt{true}
-% when the language was declared with \opt{allcaps} option.
+% Ensure the general \opt{cap} is set to \texttt{true} when the language was
+% declared with \opt{allcaps} option.
 %    \begin{macrocode}
-        \str_if_eq:eeT
+        \@@_opt_bool_if:cT
           {
-            \prop_item:cn
-              {
-                g_@@_lang_
-                \l_@@_base_language_tl _prop
-              }
-              { allcaps }
+            \@@_opt_varname_language:enn
+              { \l_@@_ref_language_tl } { allcaps } { bool }
           }
-          { true }
-          { \prop_put:Nnn \l_@@_ref_options_prop { cap } { true } }
+          { \keys_set:nn { zref-clever/reference } { cap = true } }
       }
       {
 %    \end{macrocode}
@@ -1154,13 +1638,11 @@
 % \cs{@@_provide_langfile:n} is only meant to load the built-in language
 % files.  For languages declared by the user, or for any settings to a known
 % language made with \cs{zcLanguageSetup}, values are populated directly to a
-% variable \cs{g_@@_lang_\meta{language}_prop}.  Hence, there is no need to
-% ``load'' anything in this case: definitions and assignments made by the user
-% are performed immediately.
+% corresponding variables.  Hence, there is no need to ``load'' anything in
+% this case: definitions and assignments made by the user are performed
+% immediately.
 %
 %
-% \subsubsection*{Provide}
-%
 % \begin{macro}{\g_@@_loaded_langfiles_seq}
 %   Used to keep track of whether a language file has already been loaded or
 %   not.
@@ -1169,15 +1651,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\l_@@_load_langfile_verbose_bool}
-%   Controls whether \cs{@@_provide_langfile:n} fails silently or verbosely
-%   in case of unknown languages or not found language files.
-%    \begin{macrocode}
-\bool_new:N \l_@@_load_langfile_verbose_bool
-%    \end{macrocode}
-% \end{macro}
 %
-%
 % \begin{macro}{\@@_provide_langfile:n}
 %   Load language file for known \meta{language} if it is available and if it
 %   has not already been loaded.
@@ -1189,29 +1663,30 @@
   {
     \group_begin:
     \@bsphack
-    \prop_get:NnNTF \g_@@_languages_prop {#1}
-      \l_@@_base_language_tl
+    \@@_language_if_declared:nT {#1}
       {
-        \seq_if_in:NVF
+        \seq_if_in:NxF
           \g_@@_loaded_langfiles_seq
-          \l_@@_base_language_tl
+          { \tl_use:c { \@@_language_varname:n {#1} } }
           {
             \exp_args:Nx \file_get:nnNTF
-              { zref-clever- \l_@@_base_language_tl .lang }
+              {
+                zref-clever-
+                \tl_use:c { \@@_language_varname:n {#1} }
+                .lang
+              }
               { \ExplSyntaxOn }
               \l_tmpa_tl
               {
+                \tl_set:Nn \l_@@_setup_language_tl {#1}
                 \tl_clear:N \l_@@_setup_type_tl
-                \exp_args:NNx \seq_set_from_clist:Nn
-                  \l_@@_lang_declension_seq
+                \@@_opt_seq_get:cNF
                   {
-                    \prop_item:cn
-                      {
-                        g_@@_lang_
-                        \l_@@_base_language_tl _prop
-                      }
-                      { declension }
+                    \@@_opt_varname_language:nnn
+                      {#1} { declension } { seq }
                   }
+                  \l_@@_lang_declension_seq
+                  { \seq_clear:N \l_@@_lang_declension_seq }
                 \seq_if_empty:NTF \l_@@_lang_declension_seq
                   { \tl_clear:N \l_@@_lang_decl_case_tl }
                   {
@@ -1218,48 +1693,31 @@
                     \seq_get_left:NN \l_@@_lang_declension_seq
                       \l_@@_lang_decl_case_tl
                   }
-                \exp_args:NNx \seq_set_from_clist:Nn
-                  \l_@@_lang_gender_seq
+                \@@_opt_seq_get:cNF
                   {
-                    \prop_item:cn
-                      {
-                        g_@@_lang_
-                        \l_@@_base_language_tl _prop
-                      }
-                      { gender }
+                    \@@_opt_varname_language:nnn
+                      {#1} { gender } { seq }
                   }
-                \keys_set:nV { zref-clever / langfile } \l_tmpa_tl
-                \seq_gput_right:NV \g_@@_loaded_langfiles_seq
-                  \l_@@_base_language_tl
-                \msg_note:nnx { zref-clever } { langfile-loaded }
-                  { \l_@@_base_language_tl }
+                  \l_@@_lang_gender_seq
+                  { \seq_clear:N \l_@@_lang_gender_seq }
+                \keys_set:nV { zref-clever/langfile } \l_tmpa_tl
+                \seq_gput_right:Nx \g_@@_loaded_langfiles_seq
+                  { \tl_use:c { \@@_language_varname:n {#1} } }
+                \msg_info:nnx { zref-clever } { langfile-loaded }
+                  { \tl_use:c { \@@_language_varname:n {#1} } }
               }
               {
-                \bool_if:NT \l_@@_load_langfile_verbose_bool
-                  {
-                    \msg_warning:nnx { zref-clever } { langfile-not-available }
-                      { \l_@@_base_language_tl }
-                  }
 %    \end{macrocode}
 % Even if we don't have the actual language file, we register it as
 % ``loaded''.  At this point, it is a known language, properly declared.
-% There is no point in trying to load it multiple times, because users cannot
-% really provide the language files (well, technically they could, but we are
-% working so they don't need to, and have better ways to do what they want).
-% And if the users had provided some language-specific options themselves, by
-% means of \cs{zcLanguageSetup}, everything would be in place, and they could
-% use the \opt{lang} option multiple times, and the
-% \texttt{langfile-not-available} warning would never go away.
+% There is no point in trying to load it multiple times, if it was not found
+% the first time, it won't be the next.
 %    \begin{macrocode}
-                \seq_gput_right:NV \g_@@_loaded_langfiles_seq
-                  \l_@@_base_language_tl
+                \seq_gput_right:Nx \g_@@_loaded_langfiles_seq
+                  { \tl_use:c { \@@_language_varname:n {#1} } }
               }
           }
       }
-      {
-        \bool_if:NT \l_@@_load_langfile_verbose_bool
-          { \msg_warning:nnn { zref-clever } { unknown-language-load } {#1} }
-      }
     \@esphack
     \group_end:
   }
@@ -1268,61 +1726,7 @@
 % \end{macro}
 %
 %
-% \begin{macro}{\@@_provide_langfile_verbose:n}
-%   Does the same as \cs{@@_provide_langfile:n}, but warns if the loading of
-%   the language file has failed.
-%   \begin{syntax}
-%     \cs{@@_provide_langfile_verbose:n} \Arg{language}
-%   \end{syntax}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_provide_langfile_verbose:n #1
-  {
-    \group_begin:
-    \bool_set_true:N \l_@@_load_langfile_verbose_bool
-    \@@_provide_langfile:n {#1}
-    \group_end:
-  }
-\cs_generate_variant:Nn \@@_provide_langfile_verbose:n { x }
-%    \end{macrocode}
-% \end{macro}
 %
-%
-% \begin{macro}
-%   {
-%     \@@_provide_lang_opt_type:nn ,
-%     \@@_provide_lang_opt_default:nn ,
-%   }
-%   A couple of auxiliary functions for the of
-%   \texttt{{zref-clever/langfile}} keys set in
-%   \cs{@@_provide_langfile:n}.  They respectively ``provide'' (i.e.  set if
-%   it value does not exist, do nothing if it already does) ``type-specific''
-%   and ``default'' language options.  Both receive \meta{key} and
-%   \meta{value} as arguments, but \cs{@@_provide_lang_opt_type:nn}
-%   relies on the current value of \cs{l_@@_setup_type_tl}, as set by the
-%   \texttt{type} key.
-%   \begin{syntax}
-%     \cs{@@_provide_lang_opt_type:nn} \Arg{key} \Arg{value}
-%     \cs{@@_provide_lang_opt_default:nn} \Arg{key} \Arg{value}
-%   \end{syntax}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_provide_lang_opt_type:nn #1#2
-  {
-    \exp_args:Nnx \prop_gput_if_new:cnn
-      { g_@@_lang_ \l_@@_base_language_tl _prop }
-      { type- \l_@@_setup_type_tl - #1 } {#2}
-  }
-\cs_generate_variant:Nn \@@_provide_lang_opt_type:nn { nV }
-\cs_new_protected:Npn \@@_provide_lang_opt_default:nn #1#2
-  {
-    \prop_gput_if_new:cnn
-      { g_@@_lang_ \l_@@_base_language_tl _prop }
-      { default- #1 } {#2}
-  }
-\cs_generate_variant:Nn \@@_provide_lang_opt_default:nn { nV }
-%    \end{macrocode}
-% \end{macro}
-%
-%
 % The set of keys for \texttt{{zref-clever/langfile}}, which is used to
 % process the language files in \cs{@@_provide_langfile:n}.  The no-op cases
 % for each category have their messages sent to ``info''.  These messages
@@ -1330,7 +1734,7 @@
 % placed there nevertheless, and can be leveraged in regression tests.
 %
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / langfile }
+\keys_define:nn { zref-clever/langfile }
   {
     type .code:n =
       {
@@ -1344,7 +1748,7 @@
         \seq_if_empty:NTF \l_@@_lang_declension_seq
           {
             \msg_info:nnxx { zref-clever } { language-no-decl-setup }
-              { \l_@@_base_language_tl } {#1}
+              { \l_@@_setup_language_tl } {#1}
           }
           {
             \seq_if_in:NnTF \l_@@_lang_declension_seq {#1}
@@ -1351,7 +1755,7 @@
               { \tl_set:Nn \l_@@_lang_decl_case_tl {#1} }
               {
                 \msg_info:nnxx { zref-clever } { unknown-decl-case }
-                  {#1} { \l_@@_base_language_tl }
+                  {#1} { \l_@@_setup_language_tl }
                 \seq_get_left:NN \l_@@_lang_declension_seq
                   \l_@@_lang_decl_case_tl
               }
@@ -1359,12 +1763,13 @@
       } ,
     case .value_required:n = true ,
 
+    gender .default:x = \c_novalue_tl ,
     gender .code:n =
       {
         \seq_if_empty:NTF \l_@@_lang_gender_seq
           {
             \msg_info:nnxxx { zref-clever } { language-no-gender }
-              { \l_@@_base_language_tl } { gender } {#1}
+              { \l_@@_setup_language_tl } { gender } {#1}
           }
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
@@ -1373,72 +1778,65 @@
                   { option-only-type-specific } { gender }
               }
               {
-                \clist_clear:N \l_tmpa_clist
-                \clist_map_inline:nn {#1}
+                \tl_if_novalue:nF {#1}
                   {
-                    \seq_if_in:NnTF \l_@@_lang_gender_seq {##1}
-                      { \clist_put_right:Nn \l_tmpa_clist {##1} }
+                    \seq_clear:N \l_tmpa_seq
+                    \clist_map_inline:nn {#1}
                       {
-                        \msg_info:nnxx { zref-clever }
-                          { gender-not-declared }
-                          { \l_@@_base_language_tl } {##1}
+                        \seq_if_in:NnTF \l_@@_lang_gender_seq {##1}
+                          { \seq_put_right:Nn \l_tmpa_seq {##1} }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { gender-not-declared }
+                              { \l_@@_setup_language_tl } {##1}
+                          }
                       }
+                    \@@_opt_seq_if_set:cF
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          { gender }
+                          { seq }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \@@_opt_varname_lang_type:eenn
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl }
+                              { gender }
+                              { seq }
+                          }
+                          \l_tmpa_seq
+                      }
                   }
-                \clist_if_empty:NF \l_tmpa_clist
-                  {
-                    \exp_args:Nnx \@@_provide_lang_opt_type:nn
-                      { gender } { \clist_use:Nn \l_tmpa_clist { , } }
-                  }
               }
           }
       } ,
-    gender .value_required:n = true ,
-
-    cap .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l_@@_setup_type_tl
-          {
-            \@@_provide_lang_opt_default:nV
-              { cap } \l_keys_choice_tl
-          }
-          {
-            \@@_provide_lang_opt_type:nV
-              { cap } \l_keys_choice_tl
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l_@@_setup_type_tl
-          {
-            \@@_provide_lang_opt_default:nV
-              { abbrev } \l_keys_choice_tl
-          }
-          {
-            \@@_provide_lang_opt_type:nV
-              { abbrev } \l_keys_choice_tl
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_necessarily_not_type_specific_seq
+  \c_@@_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
-              { \@@_provide_lang_opt_default:nn {#1} {##1} }
               {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \@@_opt_tl_gset_if_new:cn
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
+              {
                 \msg_info:nnn { zref-clever }
                   { option-not-type-specific } {#1}
               }
@@ -1446,25 +1844,48 @@
       }
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_possibly_type_specific_seq
+  \c_@@_rf_opts_tl_maybe_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
-              { \@@_provide_lang_opt_default:nn {#1} {##1} }
-              { \@@_provide_lang_opt_type:nn {#1} {##1} }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \@@_opt_tl_gset_if_new:cn
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \@@_opt_tl_gset_if_new:cn
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
           } ,
       }
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_type_names_seq
+  \c_@@_rf_opts_tl_type_names_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
@@ -1474,38 +1895,231 @@
               }
               {
                 \tl_if_empty:NTF \l_@@_lang_decl_case_tl
-                  { \@@_provide_lang_opt_type:nn {#1} {##1} }
                   {
-                    \@@_provide_lang_opt_type:nn
-                      { \l_@@_lang_decl_case_tl - #1 } {##1}
+                    \tl_if_novalue:nF {##1}
+                      {
+                        \@@_opt_tl_gset_if_new:cn
+                          {
+                            \@@_opt_varname_lang_type:eenn
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl }
+                              {#1} { tl }
+                          }
+                          {##1}
+                      }
                   }
+                  {
+                    \tl_if_novalue:nF {##1}
+                      {
+                        \@@_opt_tl_gset_if_new:cn
+                          {
+                            \@@_opt_varname_lang_type:eeen
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl }
+                              { \l_@@_lang_decl_case_tl - #1 } { tl }
+                          }
+                          {##1}
+                      }
+                  }
               }
           } ,
       }
   }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/langfile }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \@@_opt_seq_if_set:cF
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl } {#1} { seq }
+                      }
+                      {
+                        \seq_gclear:N \g_tmpa_seq
+                        \@@_opt_seq_gset_clist_split:Nn
+                          \g_tmpa_seq {##1}
+                        \bool_lazy_or:nnTF
+                          { \tl_if_empty_p:n {##1} }
+                          {
+                            \int_compare_p:nNn
+                              { \seq_count:N \g_tmpa_seq } = { 4 }
+                          }
+                          {
+                            \seq_gset_eq:cN
+                              {
+                                \@@_opt_varname_lang_default:enn
+                                  { \l_@@_setup_language_tl }
+                                  {#1} { seq }
+                              }
+                              \g_tmpa_seq
+                          }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { refbounds-must-be-four }
+                              {#1} { \seq_count:N \g_tmpa_seq }
+                          }
+                      }
+                  }
+              }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \@@_opt_seq_if_set:cF
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl } {#1} { seq }
+                      }
+                      {
+                        \seq_gclear:N \g_tmpa_seq
+                        \@@_opt_seq_gset_clist_split:Nn
+                          \g_tmpa_seq {##1}
+                        \bool_lazy_or:nnTF
+                          { \tl_if_empty_p:n {##1} }
+                          {
+                            \int_compare_p:nNn
+                              { \seq_count:N \g_tmpa_seq } = { 4 }
+                          }
+                          {
+                            \seq_gset_eq:cN
+                              {
+                                \@@_opt_varname_lang_type:eenn
+                                  { \l_@@_setup_language_tl }
+                                  { \l_@@_setup_type_tl }
+                                  {#1} { seq }
+                              }
+                              \g_tmpa_seq
+                          }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { refbounds-must-be-four }
+                              {#1} { \seq_count:N \g_tmpa_seq }
+                          }
+                      }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/langfile }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \@@_opt_bool_if_set:cF
+                  {
+                    \@@_opt_varname_lang_default:enn
+                      { \l_@@_setup_language_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_true:c
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+              {
+                \@@_opt_bool_if_set:cF
+                  {
+                    \@@_opt_varname_lang_type:eenn
+                      { \l_@@_setup_language_tl }
+                      { \l_@@_setup_type_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_true:c
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \@@_opt_bool_if_set:cF
+                  {
+                    \@@_opt_varname_lang_default:enn
+                      { \l_@@_setup_language_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_false:c
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+              {
+                \@@_opt_bool_if_set:cF
+                  {
+                    \@@_opt_varname_lang_type:eenn
+                      { \l_@@_setup_language_tl }
+                      { \l_@@_setup_type_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_false:c
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+          } ,
+        #1 / unset .code:n = { } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 %    \end{macrocode}
 %
 %
 %
-% \subsubsection*{Fallback}
+% It is convenient for a number of language typesetting options (some basic
+% separators) to have some ``fallback'' value available in case \pkg{babel} or
+% \pkg{polyglossia} is loaded and sets a language which \pkg{zref-clever} does
+% not know.  On the other hand, ``type names'' are not looked for in
+% ``fallback'', since it is indeed impossible to provide any reasonable value
+% for them for a ``specified but unknown language''.  Other typesetting
+% options, for which it is not a problem being empty, need not be catered for
+% with a fallback value.
 %
-% All ``strings'' queried with \cs{@@_get_ref_opt_typeset:nN} -- in practice,
-% those in either \cs{c_@@_ref_options_necessarily_not_type_specific_seq} or
-% \cs{c_@@_ref_options_possibly_type_specific_seq} -- must have their values
-% set for ``fallback'', even if to empty ones, since this is what will be
-% retrieved in the absence of a proper language-specific option, which will be
-% the case if \pkg{babel} or \pkg{polyglossia} is loaded and sets a language
-% which \pkg{zref-clever} does not know.  On the other hand, ``type names''
-% are not looked for in ``fallback'', since it is indeed impossible to provide
-% any reasonable value for them for a ``specified but unknown language''.
-% Also ``font'' options -- those in \cs{c_@@_ref_options_font_seq}, and
-% queried with \cs{@@_get_ref_opt_font:nN} -- do not need to be provided here,
-% since the later function sets an empty value if the option is not found.
-%
 %    \begin{macrocode}
-\prop_new:N \g_@@_fallback_unknown_lang_prop
-\prop_gset_from_keyval:Nn \g_@@_fallback_unknown_lang_prop
+\cs_new_protected:Npn \@@_opt_tl_cset_fallback:nn #1#2
   {
+    \tl_const:cn
+      { \@@_opt_varname_fallback:nn {#1} { tl } } {#2}
+  }
+\keyval_parse:nnn
+  { }
+  { \@@_opt_tl_cset_fallback:nn }
+  {
     tpairsep  = {,~} ,
     tlistsep  = {,~} ,
     tlastsep  = {,~} ,
@@ -1515,99 +2129,11 @@
     listsep   = {,~} ,
     lastsep   = {,~} ,
     rangesep  = {\textendash} ,
-    preref    = {} ,
-    postref   = {} ,
   }
 %    \end{macrocode}
 %
 %
 %
-% \subsubsection*{Get language options}
-%
-% \begin{macro}{\@@_get_lang_opt_type:nnnNF}
-%   Get type-specific language option of \meta{key} for \meta{type} and
-%   \meta{language}, and store it in \meta{tl variable} if found.  If not
-%   found, leave the \meta{false code} on the stream, in which case the value
-%   of \meta{tl variable} should not be relied upon.
-%   \begin{syntax}
-%     \cs{@@_get_lang_opt_type:nnnNF} \Arg{language} \Arg{type} \Arg{key}
-%     ~~\meta{tl variable} \Arg{false code}
-%   \end{syntax}
-%    \begin{macrocode}
-\prg_new_protected_conditional:Npnn
-  \@@_get_lang_opt_type:nnnN #1#2#3#4 { F }
-  {
-    \prop_get:NnNTF \g_@@_languages_prop {#1}
-      \l_@@_base_language_tl
-      {
-        \prop_get:cnNTF
-          { g_@@_lang_ \l_@@_base_language_tl _prop }
-          { type- #2 - #3 } #4
-          { \prg_return_true:  }
-          { \prg_return_false: }
-      }
-      { \prg_return_false: }
-  }
-\prg_generate_conditional_variant:Nnn
-  \@@_get_lang_opt_type:nnnN { xxxN , xxnN } { F }
-%    \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_get_lang_opt_default:nnNF}
-%   Get default language option of \meta{key} for \meta{language}, and store
-%   it in \meta{tl variable} if found.  If not found, leave the \meta{false
-%   code} on the stream, in which case the value of \meta{tl variable} should
-%   not be relied upon.
-%   \begin{syntax}
-%     \cs{@@_get_lang_opt_default:nnNF} \Arg{language} \Arg{key}
-%     ~~\meta{tl variable} \Arg{false code}
-%   \end{syntax}
-%    \begin{macrocode}
-\prg_new_protected_conditional:Npnn
-  \@@_get_lang_opt_default:nnN #1#2#3 { F }
-  {
-    \prop_get:NnNTF \g_@@_languages_prop {#1}
-      \l_@@_base_language_tl
-      {
-        \prop_get:cnNTF
-          { g_@@_lang_ \l_@@_base_language_tl _prop }
-          { default- #2 } #3
-          { \prg_return_true:  }
-          { \prg_return_false: }
-      }
-      { \prg_return_false: }
-  }
-\prg_generate_conditional_variant:Nnn
-  \@@_get_lang_opt_default:nnN { xnN } { F }
-%    \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_get_fallback_unknown_lang_opt:nNF}
-%   Get fallback language option of \meta{key}, and store it in \meta{tl
-%   variable} if found.  If not found, leave the \meta{false code} on the
-%   stream, in which case the value of \meta{tl variable} should not be relied
-%   upon.
-%   \begin{syntax}
-%     \cs{@@_get_fallback_unknown_lang_opt:nNF} \Arg{key}
-%     ~~\meta{tl variable} \Arg{false code}
-%   \end{syntax}
-%    \begin{macrocode}
-% {<key>}<tl var to set>
-\prg_new_protected_conditional:Npnn
-  \@@_get_fallback_unknown_lang_opt:nN #1#2 { F }
-  {
-    \prop_get:NnNTF \g_@@_fallback_unknown_lang_prop
-      { #1 } #2
-      { \prg_return_true:  }
-      { \prg_return_false: }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
-%
-%
 % \subsection{Options}
 %
 %
@@ -1646,7 +2172,7 @@
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_ref_property_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     ref .code:n =
       {
@@ -1671,7 +2197,7 @@
 %    \begin{macrocode}
 \bool_new:N \l_@@_typeset_ref_bool
 \bool_new:N \l_@@_typeset_name_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     typeset .choice: ,
     typeset / both .code:n =
@@ -1705,7 +2231,7 @@
 %
 %    \begin{macrocode}
 \bool_new:N \l_@@_typeset_sort_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     sort .bool_set:N = \l_@@_typeset_sort_bool ,
     sort .initial:n = true ,
@@ -1726,7 +2252,7 @@
 %
 %    \begin{macrocode}
 \seq_new:N \l_@@_typesort_seq
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     typesort .code:n =
       {
@@ -1748,7 +2274,7 @@
 %
 %    \begin{macrocode}
 \bool_new:N \l_@@_typeset_compress_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     comp .bool_set:N = \l_@@_typeset_compress_bool ,
     comp .initial:n = true ,
@@ -1764,7 +2290,7 @@
 %
 %    \begin{macrocode}
 \bool_new:N \l_@@_typeset_range_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     range .bool_set:N = \l_@@_typeset_range_bool ,
     range .initial:n = false ,
@@ -1776,30 +2302,14 @@
 %
 % \subsubsection*{\opt{cap} and \opt{capfirst} options}
 %
+% The \opt{cap} option is currently being handled with other reference format
+% option booleans at \cs{c_@@_rf_opts_bool_maybe_type_specific_seq}.
+%
 %    \begin{macrocode}
-\bool_new:N \l_@@_capitalize_first_bool
-\keys_define:nn { zref-clever / reference }
+\bool_new:N \l_@@_capfirst_bool
+\keys_define:nn { zref-clever/reference }
   {
-    cap .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          { \prop_remove:Nn \l_@@_ref_options_prop { cap } }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              { \prop_put:Nnn \l_@@_ref_options_prop { cap } {#1} }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    capfirst .bool_set:N = \l_@@_capitalize_first_bool ,
+    capfirst .bool_set:N = \l_@@_capfirst_bool ,
     capfirst .initial:n = false ,
     capfirst .default:n = true ,
   }
@@ -1808,29 +2318,13 @@
 %
 % \subsubsection*{\opt{abbrev} and \opt{noabbrevfirst} options}
 %
+% The \opt{abbrev} option is currently being handled with other reference
+% format option booleans at \cs{c_@@_rf_opts_bool_maybe_type_specific_seq}.
+%
 %    \begin{macrocode}
 \bool_new:N \l_@@_noabbrev_first_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
-    abbrev .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          { \prop_remove:Nn \l_@@_ref_options_prop { abbrev } }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              { \prop_put:Nnn \l_@@_ref_options_prop { abbrev } {#1} }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
-
     noabbrevfirst .bool_set:N = \l_@@_noabbrev_first_bool ,
     noabbrevfirst .initial:n = false ,
     noabbrevfirst .default:n = true ,
@@ -1842,11 +2336,11 @@
 % \subsubsection*{\opt{S} option}
 %
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     S .meta:n =
-      { capfirst = true , noabbrevfirst = true },
-    S .value_forbidden:n = true ,
+      { capfirst = {#1} , noabbrevfirst = {#1} },
+    S .default:n = true ,
   }
 %    \end{macrocode}
 %
@@ -1854,28 +2348,38 @@
 % \subsubsection*{\opt{hyperref} option}
 %
 %    \begin{macrocode}
-\bool_new:N \l_@@_use_hyperref_bool
-\bool_new:N \l_@@_warn_hyperref_bool
-\keys_define:nn { zref-clever / reference }
+\bool_new:N \l_@@_hyperlink_bool
+\bool_new:N \l_@@_hyperref_warn_bool
+\keys_define:nn { zref-clever/reference }
   {
     hyperref .choice: ,
     hyperref / auto .code:n =
       {
-        \bool_set_true:N \l_@@_use_hyperref_bool
-        \bool_set_false:N \l_@@_warn_hyperref_bool
+        \bool_set_true:N \l_@@_hyperlink_bool
+        \bool_set_false:N \l_@@_hyperref_warn_bool
       } ,
     hyperref / true .code:n =
       {
-        \bool_set_true:N \l_@@_use_hyperref_bool
-        \bool_set_true:N \l_@@_warn_hyperref_bool
+        \bool_set_true:N \l_@@_hyperlink_bool
+        \bool_set_true:N \l_@@_hyperref_warn_bool
       } ,
     hyperref / false .code:n =
       {
-        \bool_set_false:N \l_@@_use_hyperref_bool
-        \bool_set_false:N \l_@@_warn_hyperref_bool
+        \bool_set_false:N \l_@@_hyperlink_bool
+        \bool_set_false:N \l_@@_hyperref_warn_bool
       } ,
     hyperref .initial:n = auto ,
-    hyperref .default:n = auto
+    hyperref .default:n = true ,
+%    \end{macrocode}
+% \opt{nohyperref} is provided mainly as a means to inhibit hyperlinking
+% locally in \pkg{zref-vario}'s commands without the need to be setting
+% \pkg{zref-clever}'s internal variables directly.  What limits setting
+% \opt{hyperref} out of the preamble is that enabling hyperlinks requires
+% loading packages.  But \opt{nohyperref} can only disable them, so we can use
+% it in the document body too.
+%    \begin{macrocode}
+    nohyperref .meta:n = { hyperref = false } ,
+    nohyperref .value_forbidden:n = true ,
   }
 %    \end{macrocode}
 %
@@ -1884,18 +2388,20 @@
   {
     \@@_if_package_loaded:nTF { hyperref }
       {
-        \bool_if:NT \l_@@_use_hyperref_bool
+        \bool_if:NT \l_@@_hyperlink_bool
           { \RequirePackage { zref-hyperref } }
       }
       {
-        \bool_if:NT \l_@@_warn_hyperref_bool
+        \bool_if:NT \l_@@_hyperref_warn_bool
           { \msg_warning:nn { zref-clever } { missing-hyperref } }
-        \bool_set_false:N \l_@@_use_hyperref_bool
+        \bool_set_false:N \l_@@_hyperlink_bool
       }
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         hyperref .code:n =
-          { \msg_warning:nn { zref-clever } { hyperref-preamble-only } }
+          { \msg_warning:nn { zref-clever } { hyperref-preamble-only } } ,
+        nohyperref .code:n =
+          { \bool_set_false:N \l_@@_hyperlink_bool } ,
       }
   }
 %    \end{macrocode}
@@ -1906,7 +2412,7 @@
 %
 %    \begin{macrocode}
 \str_new:N \l_@@_nameinlink_str
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nameinlink .choice: ,
     nameinlink / true .code:n =
@@ -1923,15 +2429,17 @@
 %    \end{macrocode}
 %
 %
-% \subsubsection*{\opt{preposinlink} option}
+% \subsubsection*{\opt{preposinlink} option (deprecated)}
 %
 %    \begin{macrocode}
-\bool_new:N \l_@@_preposinlink_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
-    preposinlink .bool_set:N =  \l_@@_preposinlink_bool ,
-    preposinlink .initial:n = false ,
-    preposinlink .default:n = true ,
+    preposinlink .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-12 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preposinlink } { refbounds }
+      } ,
   }
 %    \end{macrocode}
 %
@@ -1996,22 +2504,18 @@
             \tl_set:Nn \l_@@_main_language_tl { english }
           }
       }
+  }
 %    \end{macrocode}
-% Provide default value for \cs{l_@@_ref_language_tl} corresponding to option
-% \opt{current}, but do so outside of the \pkg{l3keys} machinery (that is,
-% instead of using \texttt{.initial:n}), so that we are able to distinguish
-% when the user actually gave the option, in which case the language file
-% loading is done verbosely, from when we are setting the default value
-% (here), in which case the language file loading is done silently.
+%
+% \begin{macro}{\l_zrefclever_ref_language_tl}
+%   A public version of \cs{l_@@_ref_language_tl} for use in \pkg{zref-vario}.
 %    \begin{macrocode}
-    \tl_set:Nn \l_@@_ref_language_tl
-      { \l_@@_current_language_tl }
-  }
+\tl_set:Nn  \l_zrefclever_ref_language_tl { \l_@@_ref_language_tl }
 %    \end{macrocode}
+% \end{macro}
 %
-%
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     lang .code:n =
       {
@@ -2023,8 +2527,6 @@
                 {
                   \tl_set:Nn \l_@@_ref_language_tl
                     { \l_@@_current_language_tl }
-                  \@@_provide_langfile_verbose:x
-                    { \l_@@_ref_language_tl }
                 }
 
                 { main }
@@ -2031,24 +2533,21 @@
                 {
                   \tl_set:Nn \l_@@_ref_language_tl
                     { \l_@@_main_language_tl }
-                  \@@_provide_langfile_verbose:x
-                    { \l_@@_ref_language_tl }
                 }
               }
               {
-                \prop_if_in:NnTF \g_@@_languages_prop {#1}
-                  { \tl_set:Nn \l_@@_ref_language_tl {#1} }
+                \tl_set:Nn \l_@@_ref_language_tl {#1}
+                \@@_language_if_declared:nF {#1}
                   {
                     \msg_warning:nnn { zref-clever }
                       { unknown-language-opt } {#1}
-                    \tl_set:Nn \l_@@_ref_language_tl
-                      { \l_@@_current_language_tl }
                   }
-                \@@_provide_langfile_verbose:x
-                  { \l_@@_ref_language_tl }
               }
+            \@@_provide_langfile:x
+              { \l_@@_ref_language_tl }
           }
       } ,
+    lang .initial:n = current ,
     lang .value_required:n = true ,
   }
 %    \end{macrocode}
@@ -2060,18 +2559,11 @@
     \AddToHook { begindocument }
       {
 %    \end{macrocode}
-% If any \opt{lang} option has been given by the user, the corresponding
-% language is already loaded, otherwise, ensure the default one
-% (\texttt{current}) gets loaded early, but not verbosely.
-%    \begin{macrocode}
-        \@@_provide_langfile:x { \l_@@_ref_language_tl }
-%    \end{macrocode}
 % Redefinition of the \texttt{lang} key option for the document body.  Also,
-% drop the verbose language file loading in the document body, as it can
-% become intrusive depending on the use case, and does not provide much
-% ``juice'' anyway: in \cs{zcref} missing names warnings will already ensue.
+% drop the language file loading in the document body, it is somewhat
+% redundant, since \cs{@@_zcref:nnn} already ensures it.
 %    \begin{macrocode}
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             lang .code:n =
               {
@@ -2081,8 +2573,6 @@
                     {
                       \tl_set:Nn \l_@@_ref_language_tl
                         { \l_@@_current_language_tl }
-                      \@@_provide_langfile:x
-                        { \l_@@_ref_language_tl }
                     }
 
                     { main }
@@ -2089,24 +2579,17 @@
                     {
                       \tl_set:Nn \l_@@_ref_language_tl
                         { \l_@@_main_language_tl }
-                      \@@_provide_langfile:x
-                        { \l_@@_ref_language_tl }
                     }
                   }
                   {
-                    \prop_if_in:NnTF \g_@@_languages_prop {#1}
-                      { \tl_set:Nn \l_@@_ref_language_tl {#1} }
+                    \tl_set:Nn \l_@@_ref_language_tl {#1}
+                    \@@_language_if_declared:nF {#1}
                       {
                         \msg_warning:nnn { zref-clever }
                           { unknown-language-opt } {#1}
-                        \tl_set:Nn \l_@@_ref_language_tl
-                          { \l_@@_current_language_tl }
                       }
-                    \@@_provide_langfile:x
-                      { \l_@@_ref_language_tl }
                   }
               } ,
-            lang .value_required:n = true ,
           }
       }
   }
@@ -2128,7 +2611,7 @@
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_ref_decl_case_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     d .code:n =
       { \msg_warning:nnn { zref-clever } { option-document-only } { d } } ,
@@ -2135,11 +2618,11 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
 %    \end{macrocode}
 % We just store the value at this point, which is validated by
-% \cs{@@_process_language_options:} after \cs{keys_set:nn}.
+% \cs{@@_process_language_settings:} after \cs{keys_set:nn}.
 %    \begin{macrocode}
         d .tl_set:N = \l_@@_ref_decl_case_tl ,
         d .value_required:n = true ,
@@ -2158,7 +2641,7 @@
 \bool_new:N \l_@@_nudge_singular_bool
 \bool_new:N \l_@@_nudge_gender_bool
 \tl_new:N \l_@@_ref_gender_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nudge .choice: ,
     nudge / true .code:n =
@@ -2219,11 +2702,11 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
 %    \end{macrocode}
 % We just store the value at this point, which is validated by
-% \cs{@@_process_language_options:} after \cs{keys_set:nn}.
+% \cs{@@_process_language_settings:} after \cs{keys_set:nn}.
 %    \begin{macrocode}
         g .tl_set:N = \l_@@_ref_gender_tl ,
         g .value_required:n = true ,
@@ -2245,7 +2728,7 @@
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_ref_typeset_font_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   { font .tl_set:N = \l_@@_ref_typeset_font_tl }
 %    \end{macrocode}
 %
@@ -2254,7 +2737,7 @@
 % \subsubsection*{\opt{titleref} option}
 %
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     titleref .code:n = { \RequirePackage { zref-titleref } } ,
     titleref .value_forbidden:n = true ,
@@ -2261,7 +2744,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         titleref .code:n =
           { \msg_warning:nn { zref-clever } { titleref-preamble-only } }
@@ -2274,7 +2757,7 @@
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_zcref_note_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     note .tl_set:N = \l_@@_zcref_note_tl ,
     note .value_required:n = true ,
@@ -2289,7 +2772,7 @@
 %    \begin{macrocode}
 \bool_new:N \l_@@_zrefcheck_available_bool
 \bool_new:N \l_@@_zcref_with_check_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     check .code:n = { \RequirePackage { zref-check } } ,
     check .value_forbidden:n = true ,
@@ -2299,7 +2782,7 @@
     \@@_if_package_loaded:nTF { zref-check }
       {
         \bool_set_true:N \l_@@_zrefcheck_available_bool
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             check .code:n =
               {
@@ -2311,7 +2794,7 @@
       }
       {
         \bool_set_false:N \l_@@_zrefcheck_available_bool
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             check .value_forbidden:n = false ,
             check .code:n =
@@ -2332,7 +2815,7 @@
 %
 %    \begin{macrocode}
 \prop_new:N \l_@@_counter_type_prop
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     countertype .code:n =
       {
@@ -2396,7 +2879,7 @@
 %
 %    \begin{macrocode}
 \seq_new:N \l_@@_counter_resetters_seq
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     counterresetters .code:n =
       {
@@ -2435,7 +2918,7 @@
 %
 %    \begin{macrocode}
 \prop_new:N \l_@@_counter_resetby_prop
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     counterresetby .code:n =
       {
@@ -2476,7 +2959,7 @@
 %
 %    \begin{macrocode}
 \tl_new:N \l_@@_current_counter_tl
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     currentcounter .tl_set:N = \l_@@_current_counter_tl ,
     currentcounter .value_required:n = true ,
@@ -2491,7 +2974,7 @@
 %    \begin{macrocode}
 \bool_new:N \g_@@_nocompat_bool
 \seq_new:N \g_@@_nocompat_modules_seq
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nocompat .code:n =
       {
@@ -2511,7 +2994,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         nocompat .code:n =
           {
@@ -2566,53 +3049,121 @@
 % This is a set of options related to reference typesetting which receive
 % equal treatment and, hence, are handled in batch.  Since we are dealing with
 % options to be passed to \cs{zcref} or to \cs{zcsetup} or at load time, only
-% ``not necessarily type-specific'' options are pertinent here.  However, they
-% \emph{may} either be type-specific or language-specific, and thus must be
-% stored in a property list, \cs{l_@@_ref_options_prop}, in order to be
-% retrieved from the option \emph{name} by \cs{@@_get_ref_opt_typeset:nN} and
-% \cs{@@_get_ref_opt_font:nN} according to context and precedence rules.
+% ``not necessarily type-specific'' options are pertinent here.
 %
-% The keys are set so that any value, including an empty one, is added to
-% \cs{l_@@_ref_options_prop}, while a key with \emph{no value} removes the
-% property from the list, so that these options can then fall back to lower
-% precedence levels settings.  For discussion about the used technique, see
-% \zcref{sec:zcreftypesetup}.
 %
 %    \begin{macrocode}
-\prop_new:N \l_@@_ref_options_prop
 \seq_map_inline:Nn
-  \c_@@_ref_options_reference_seq
+  \c_@@_rf_opts_tl_reference_seq
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
-        #1 .default:V = \c_novalue_tl ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_novalue:nTF {##1}
-              { \prop_remove:Nn \l_@@_ref_options_prop {#1} }
-              { \prop_put:Nnn \l_@@_ref_options_prop {#1} {##1} }
+              {
+                \@@_opt_tl_unset:c
+                  { \@@_opt_varname_general:nn {#1} { tl } }
+              }
+              {
+                \tl_set:cn
+                  { \@@_opt_varname_general:nn {#1} { tl } }
+                  {##1}
+              }
           } ,
       }
   }
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
+    preref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/reference }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_novalue:nTF {##1}
+              {
+                \@@_opt_seq_unset:c
+                  { \@@_opt_varname_general:nn {#1} { seq } }
+              }
+              {
+                \seq_clear:N \l_tmpa_seq
+                \@@_opt_seq_set_clist_split:Nn
+                  \l_tmpa_seq {##1}
+                \bool_lazy_or:nnTF
+                  { \tl_if_empty_p:n {##1} }
+                  { \int_compare_p:nNn { \seq_count:N \l_tmpa_seq } = { 4 } }
+                  {
+                    \seq_set_eq:cN
+                      { \@@_opt_varname_general:nn {#1} { seq } }
+                      \l_tmpa_seq
+                  }
+                  {
+                    \msg_warning:nnxx { zref-clever }
+                      { refbounds-must-be-four }
+                      {#1} { \seq_count:N \l_tmpa_seq }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/reference }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \bool_set_true:c
+              { \@@_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 / false .code:n =
+          {
+            \bool_set_false:c
+              { \@@_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 / unset .code:n =
+          {
+            \@@_opt_bool_unset:c
+              { \@@_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 %    \end{macrocode}
 %
 %
-%
 % \subsubsection*{Package options}
 %
 % The options have been separated in two different groups, so that we can
@@ -2625,10 +3176,10 @@
 %    \begin{macrocode}
 \keys_define:nn { }
   {
-    zref-clever / zcsetup .inherit:n =
+    zref-clever/zcsetup .inherit:n =
       {
-        zref-clever / label ,
-        zref-clever / reference ,
+        zref-clever/label ,
+        zref-clever/reference ,
       }
   }
 %    \end{macrocode}
@@ -2637,7 +3188,7 @@
 % Process load-time package options
 % (\url{https://tex.stackexchange.com/a/15840}).
 %    \begin{macrocode}
-\ProcessKeysOptions { zref-clever / zcsetup }
+\ProcessKeysOptions { zref-clever/zcsetup }
 %    \end{macrocode}
 %
 %
@@ -2665,7 +3216,7 @@
 %   \end{syntax}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_zcsetup:n #1
-  { \keys_set:nn { zref-clever / zcsetup } {#1} }
+  { \keys_set:nn { zref-clever/zcsetup } {#1} }
 \cs_generate_variant:Nn \@@_zcsetup:n { x }
 %    \end{macrocode}
 % \end{macro}
@@ -2691,114 +3242,19 @@
 %    \begin{macrocode}
 \NewDocumentCommand \zcRefTypeSetup { m m }
   {
-    \prop_if_exist:cF { l_@@_type_ #1 _options_prop }
-      { \prop_new:c { l_@@_type_ #1 _options_prop } }
     \tl_set:Nn \l_@@_setup_type_tl {#1}
-    \keys_set:nn { zref-clever / typesetup } {#2}
+    \keys_set:nn { zref-clever/typesetup } {#2}
   }
 %    \end{macrocode}
 % \end{macro}
 %
 %
-% Inside \cs{zcRefTypeSetup} any of the options \emph{can} receive empty
-% values, and those values, if they exist in the property list, will override
-% language-specific options, regardless of their emptiness.  In principle, we
-% could live with the situation of, once a setting has been made in
-% \cs{l_@@_type_<type>_options_prop} or in \cs{l_@@_ref_options_prop} it stays
-% there forever, and can only be overridden by a new value at the same
-% precedence level or a higher one.  But it would be nice if an user can
-% ``unset'' an option at either of those scopes to go back to the lower
-% precedence level of the language-specific options at any given point.  So
-% both in \cs{zcRefTypeSetup} and in setting reference options (see
-% \zcref{sec:reference-options}), we leverage the distinction of an ``empty
-% valued key'' (\texttt{key=} or \texttt{key=\{\}}) from a ``key with no
-% value'' (\texttt{key}).  This distinction is captured internally by the
-% lower-level key parsing, but must be made explicit at \cs{keys_set:nn} by
-% means of the \texttt{.default:V} property of the key in \cs{keys_define:nn}.
-% For the technique, by \contributor{Jonathan P.\ Spratte}, aka `Skillmon',
-% and some discussion about it, including further insights by
-% \contributor{Phelype Oleinik}, see
-% \url{https://tex.stackexchange.com/q/614690} and
-% \url{https://github.com/latex3/latex3/pull/988}.
 %
-%
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / typesetup }
-  {
-    cap .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          {
-            \prop_remove:cn
-              {
-                l_@@_type_
-                \l_@@_setup_type_tl _options_prop
-              }
-              { cap }
-          }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              {
-                \prop_put:cnn
-                  {
-                    l_@@_type_
-                    \l_@@_setup_type_tl _options_prop
-                  }
-                  { cap } {#1}
-              }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          {
-            \prop_remove:cn
-              {
-                l_@@_type_
-                \l_@@_setup_type_tl _options_prop
-              }
-              { abbrev }
-          }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              {
-                \prop_put:cnn
-                  {
-                    l_@@_type_
-                    \l_@@_setup_type_tl _options_prop
-                  }
-                  { abbrev } {#1}
-              }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
-  }
-%    \end{macrocode}
-%
-%
-%    \begin{macrocode}
 \seq_map_inline:Nn
-  \c_@@_ref_options_necessarily_not_type_specific_seq
+  \c_@@_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / typesetup }
+    \keys_define:nn { zref-clever/typesetup }
       {
         #1 .code:n =
           {
@@ -2807,57 +3263,141 @@
           } ,
       }
   }
-%    \end{macrocode}
-%
-%
-%    \begin{macrocode}
 \seq_map_inline:Nn
-  \c_@@_ref_options_typesetup_seq
+  \c_@@_rf_opts_tl_typesetup_seq
   {
-    \keys_define:nn { zref-clever / typesetup }
+    \keys_define:nn { zref-clever/typesetup }
       {
-        #1 .default:V = \c_novalue_tl ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_novalue:nTF {##1}
               {
-                \prop_remove:cn
+                \@@_opt_tl_unset:c
                   {
-                    l_@@_type_
-                    \l_@@_setup_type_tl _options_prop
+                    \@@_opt_varname_type:enn
+                      { \l_@@_setup_type_tl } {#1} { tl }
                   }
-                  {#1}
               }
               {
-                \prop_put:cnn
+                \tl_set:cn
                   {
-                    l_@@_type_
-                    \l_@@_setup_type_tl _options_prop
+                    \@@_opt_varname_type:enn
+                      { \l_@@_setup_type_tl } {#1} { tl }
                   }
-                  {#1} {##1}
+                  {##1}
               }
           } ,
       }
   }
-\keys_define:nn { zref-clever / typesetup }
+\keys_define:nn { zref-clever/typesetup }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
+    preref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/typesetup }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_novalue:nTF {##1}
+              {
+                \@@_opt_seq_unset:c
+                  {
+                    \@@_opt_varname_type:enn
+                      { \l_@@_setup_type_tl } {#1} { seq }
+                  }
+              }
+              {
+                \seq_clear:N \l_tmpa_seq
+                \@@_opt_seq_set_clist_split:Nn
+                  \l_tmpa_seq {##1}
+                \bool_lazy_or:nnTF
+                  { \tl_if_empty_p:n {##1} }
+                  { \int_compare_p:nNn { \seq_count:N \l_tmpa_seq } = { 4 } }
+                  {
+                    \seq_set_eq:cN
+                      {
+                        \@@_opt_varname_type:enn
+                          { \l_@@_setup_type_tl } {#1} { seq }
+                      }
+                      \l_tmpa_seq
+                  }
+                  {
+                    \msg_warning:nnxx { zref-clever }
+                      { refbounds-must-be-four }
+                      {#1} { \seq_count:N \l_tmpa_seq }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/typesetup }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \bool_set_true:c
+              {
+                \@@_opt_varname_type:enn
+                  { \l_@@_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \bool_set_false:c
+              {
+                \@@_opt_varname_type:enn
+                  { \l_@@_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 / unset .code:n =
+          {
+            \@@_opt_bool_unset:c
+              {
+                \@@_opt_varname_type:enn
+                  { \l_@@_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 %    \end{macrocode}
 %
 %
-%
 % \subsection{\cs{zcLanguageSetup}}
 %
 % \cs{zcLanguageSetup} is the main user interface for ``language-specific''
@@ -2879,20 +3419,17 @@
 \NewDocumentCommand \zcLanguageSetup { m m }
   {
     \group_begin:
-    \prop_get:NnNTF \g_@@_languages_prop {#1}
-      \l_@@_base_language_tl
+    \@@_language_if_declared:nTF {#1}
       {
         \tl_clear:N \l_@@_setup_type_tl
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l_@@_lang_declension_seq
+        \tl_set:Nn \l_@@_setup_language_tl {#1}
+        \@@_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g_@@_lang_
-                \l_@@_base_language_tl _prop
-              }
-              { declension }
+            \@@_opt_varname_language:nnn
+              {#1} { declension } { seq }
           }
+          \l_@@_lang_declension_seq
+          { \seq_clear:N \l_@@_lang_declension_seq }
         \seq_if_empty:NTF \l_@@_lang_declension_seq
           { \tl_clear:N \l_@@_lang_decl_case_tl }
           {
@@ -2899,17 +3436,14 @@
             \seq_get_left:NN \l_@@_lang_declension_seq
               \l_@@_lang_decl_case_tl
           }
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l_@@_lang_gender_seq
+        \@@_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g_@@_lang_
-                \l_@@_base_language_tl _prop
-              }
-              { gender }
+            \@@_opt_varname_language:nnn
+              {#1} { gender } { seq }
           }
-        \keys_set:nn { zref-clever / langsetup } {#2}
+          \l_@@_lang_gender_seq
+          { \seq_clear:N \l_@@_lang_gender_seq }
+        \keys_set:nn { zref-clever/langsetup } {#2}
       }
       { \msg_warning:nnn { zref-clever } { unknown-language-setup } {#1} }
     \group_end:
@@ -2919,44 +3453,12 @@
 % \end{macro}
 %
 %
-% \begin{macro}
-%   {
-%     \@@_declare_lang_opt_type:nnnn ,
-%     \@@_declare_lang_opt_default:nnn ,
-%   }
-%   A couple of auxiliary functions for the of
-%   \texttt{{zref-clever/langsetup}} keys set in \cs{zcLanguageSetup}.  They
-%   respectively declare (unconditionally set) ``type-specific'' and
-%   ``default'' language-specific options.
-%   \begin{syntax}
-%     \cs{@@_declare_lang_opt_type:nnnn} \Arg{language} \Arg{type}
-%     ~~\Arg{key} \Arg{value}
-%     \cs{@@_declare_lang_opt_default:nnn} \Arg{language}
-%     ~~\Arg{key} \Arg{value}
-%   \end{syntax}
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_lang_opt_type:nnnn #1#2#3#4
-  {
-    \prop_gput:cnn { g_@@_lang_ #1 _prop }
-      { type- #2 - #3 } {#4}
-  }
-\cs_generate_variant:Nn
-  \@@_declare_lang_opt_type:nnnn { VVnn , VVxn , VVnx , VVnV }
-\cs_new_protected:Npn \@@_declare_lang_opt_default:nnn #1#2#3
-  {
-    \prop_gput:cnn { g_@@_lang_ #1 _prop }
-      { default- #2 } {#3}
-  }
-\cs_generate_variant:Nn \@@_declare_lang_opt_default:nnn { Vnn , VnV }
-%    \end{macrocode}
-% \end{macro}
 %
-%
 % The set of keys for \texttt{{zref-clever/langsetup}}, which is used to set
 % language-specific options in \cs{zcLanguageSetup}.
 %
 %    \begin{macrocode}
-\keys_define:nn { zref-clever / langsetup }
+\keys_define:nn { zref-clever/langsetup }
   {
     type .code:n =
       {
@@ -2970,7 +3472,7 @@
         \seq_if_empty:NTF \l_@@_lang_declension_seq
           {
             \msg_warning:nnxx { zref-clever } { language-no-decl-setup }
-              { \l_@@_base_language_tl } {#1}
+              { \l_@@_setup_language_tl } {#1}
           }
           {
             \seq_if_in:NnTF \l_@@_lang_declension_seq {#1}
@@ -2977,7 +3479,7 @@
               { \tl_set:Nn \l_@@_lang_decl_case_tl {#1} }
               {
                 \msg_warning:nnxx { zref-clever } { unknown-decl-case }
-                  {#1} { \l_@@_base_language_tl }
+                  {#1} { \l_@@_setup_language_tl }
                 \seq_get_left:NN \l_@@_lang_declension_seq
                   \l_@@_lang_decl_case_tl
               }
@@ -2985,12 +3487,13 @@
       } ,
     case .value_required:n = true ,
 
+    gender .default:x = \c_novalue_tl ,
     gender .code:n =
       {
         \seq_if_empty:NTF \l_@@_lang_gender_seq
           {
             \msg_warning:nnxxx { zref-clever } { language-no-gender }
-              { \l_@@_base_language_tl } { gender } {#1}
+              { \l_@@_setup_language_tl } { gender } {#1}
           }
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
@@ -2999,82 +3502,69 @@
                   { option-only-type-specific } { gender }
               }
               {
-                \clist_clear:N \l_tmpa_clist
-                \clist_map_inline:nn {#1}
+                \tl_if_novalue:nTF {#1}
                   {
-                    \seq_if_in:NnTF \l_@@_lang_gender_seq {##1}
-                      { \clist_put_right:Nn \l_tmpa_clist {##1} }
+                    \@@_opt_seq_gunset:c
                       {
-                        \msg_warning:nnxx { zref-clever }
-                          { gender-not-declared }
-                          { \l_@@_base_language_tl } {##1}
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          { gender }
+                          { seq }
                       }
                   }
-                \clist_if_empty:NF \l_tmpa_clist
                   {
-                    \@@_declare_lang_opt_type:VVnx
-                      \l_@@_base_language_tl
-                      \l_@@_setup_type_tl
-                      { gender } { \clist_use:Nn \l_tmpa_clist { , } }
+                    \seq_clear:N \l_tmpa_seq
+                    \clist_map_inline:nn {#1}
+                      {
+                        \seq_if_in:NnTF \l_@@_lang_gender_seq {##1}
+                          { \seq_put_right:Nn \l_tmpa_seq {##1} }
+                          {
+                            \msg_warning:nnxx { zref-clever }
+                              { gender-not-declared }
+                              { \l_@@_setup_language_tl } {##1}
+                          }
+                      }
+                    \seq_gset_eq:cN
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          { gender }
+                          { seq }
+                      }
+                      \l_tmpa_seq
                   }
               }
           }
       } ,
-    gender .value_required:n = true ,
-
-    cap .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l_@@_setup_type_tl
-          {
-            \@@_declare_lang_opt_default:VnV
-              \l_@@_base_language_tl
-              { cap } \l_keys_choice_tl
-          }
-          {
-            \@@_declare_lang_opt_type:VVnV
-              \l_@@_base_language_tl
-              \l_@@_setup_type_tl
-              { cap } \l_keys_choice_tl
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l_@@_setup_type_tl
-          {
-            \@@_declare_lang_opt_default:VnV
-              \l_@@_base_language_tl
-              { abbrev } \l_keys_choice_tl
-          }
-          {
-            \@@_declare_lang_opt_type:VVnV
-              \l_@@_base_language_tl
-              \l_@@_setup_type_tl
-              { abbrev } \l_keys_choice_tl
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_necessarily_not_type_specific_seq
+  \c_@@_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
               {
-                \@@_declare_lang_opt_default:Vnn
-                  \l_@@_base_language_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \@@_opt_tl_gunset:c
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl } {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl } {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
               {
                 \msg_warning:nnn { zref-clever }
@@ -3084,9 +3574,9 @@
       }
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_possibly_type_specific_seq
+  \c_@@_rf_opts_tl_maybe_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
         #1 .value_required:n = true ,
         #1 .code:n =
@@ -3093,38 +3583,79 @@
           {
             \tl_if_empty:NTF \l_@@_setup_type_tl
               {
-                \@@_declare_lang_opt_default:Vnn
-                  \l_@@_base_language_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \@@_opt_tl_gunset:c
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl } {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl } {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
               {
-                \@@_declare_lang_opt_type:VVnn
-                  \l_@@_base_language_tl
-                  \l_@@_setup_type_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \@@_opt_tl_gunset:c
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
           } ,
       }
   }
-\keys_define:nn { zref-clever / langsetup }
+\keys_define:nn { zref-clever/langsetup }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
+    preref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
 \seq_map_inline:Nn
-  \c_@@_ref_options_type_names_seq
+  \c_@@_rf_opts_tl_type_names_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
         #1 .value_required:n = true ,
         #1 .code:n =
@@ -3135,27 +3666,205 @@
                   { option-only-type-specific } {#1}
               }
               {
-                \tl_if_empty:NTF \l_@@_lang_decl_case_tl
+                \tl_if_novalue:nTF {##1}
                   {
-                    \@@_declare_lang_opt_type:VVnn
-                      \l_@@_base_language_tl
-                      \l_@@_setup_type_tl
-                      {#1} {##1}
+                    \@@_opt_tl_gunset:c
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl }
+                          {#1} { tl }
+                      }
                   }
                   {
-                    \@@_declare_lang_opt_type:VVxn
-                      \l_@@_base_language_tl
-                      \l_@@_setup_type_tl
-                      { \l_@@_lang_decl_case_tl - #1 } {##1}
+                    \tl_if_empty:NTF \l_@@_lang_decl_case_tl
+                      {
+                        \tl_gset:cn
+                          {
+                            \@@_opt_varname_lang_type:eenn
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl }
+                              {#1} { tl }
+                          }
+                          {##1}
+                      }
+                      {
+                        \tl_gset:cn
+                          {
+                            \@@_opt_varname_lang_type:eeen
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl }
+                              { \l_@@_lang_decl_case_tl - #1 }
+                              { tl }
+                          }
+                          {##1}
+                      }
                   }
               }
           } ,
       }
   }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/langsetup }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \@@_opt_seq_gunset:c
+                      {
+                        \@@_opt_varname_lang_default:enn
+                          { \l_@@_setup_language_tl }
+                          {#1} { seq }
+                      }
+                  }
+                  {
+                    \seq_gclear:N \g_tmpa_seq
+                    \@@_opt_seq_gset_clist_split:Nn
+                      \g_tmpa_seq {##1}
+                    \bool_lazy_or:nnTF
+                      { \tl_if_empty_p:n {##1} }
+                      {
+                        \int_compare_p:nNn
+                          { \seq_count:N \g_tmpa_seq } = { 4 }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \@@_opt_varname_lang_default:enn
+                              { \l_@@_setup_language_tl }
+                              {#1} { seq }
+                          }
+                          \g_tmpa_seq
+                      }
+                      {
+                        \msg_warning:nnxx { zref-clever }
+                          { refbounds-must-be-four }
+                          {#1} { \seq_count:N \g_tmpa_seq }
+                      }
+                  }
+              }
+              {
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \@@_opt_seq_gunset:c
+                      {
+                        \@@_opt_varname_lang_type:eenn
+                          { \l_@@_setup_language_tl }
+                          { \l_@@_setup_type_tl } {#1} { seq }
+                      }
+                  }
+                  {
+                    \seq_gclear:N \g_tmpa_seq
+                    \@@_opt_seq_gset_clist_split:Nn
+                      \g_tmpa_seq {##1}
+                    \bool_lazy_or:nnTF
+                      { \tl_if_empty_p:n {##1} }
+                      {
+                        \int_compare_p:nNn
+                          { \seq_count:N \g_tmpa_seq } = { 4 }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \@@_opt_varname_lang_type:eenn
+                              { \l_@@_setup_language_tl }
+                              { \l_@@_setup_type_tl } {#1} { seq }
+                          }
+                          \g_tmpa_seq
+                      }
+                      {
+                        \msg_warning:nnxx { zref-clever }
+                          { refbounds-must-be-four }
+                          {#1} { \seq_count:N \g_tmpa_seq }
+                      }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c_@@_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/langsetup }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \bool_gset_true:c
+                  {
+                    \@@_opt_varname_lang_default:enn
+                      { \l_@@_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \bool_gset_true:c
+                  {
+                    \@@_opt_varname_lang_type:eenn
+                      { \l_@@_setup_language_tl }
+                      { \l_@@_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \bool_gset_false:c
+                  {
+                    \@@_opt_varname_lang_default:enn
+                      { \l_@@_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \bool_gset_false:c
+                  {
+                    \@@_opt_varname_lang_type:eenn
+                      { \l_@@_setup_language_tl }
+                      { \l_@@_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 / unset .code:n =
+          {
+            \tl_if_empty:NTF \l_@@_setup_type_tl
+              {
+                \@@_opt_bool_gunset:c
+                  {
+                    \@@_opt_varname_lang_default:enn
+                      { \l_@@_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \@@_opt_bool_gunset:c
+                  {
+                    \@@_opt_varname_lang_type:eenn
+                      { \l_@@_setup_language_tl }
+                      { \l_@@_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 %    \end{macrocode}
 %
 %
-%
 % \section{User interface}
 %
 % \subsection{\cs{zcref}}
@@ -3187,7 +3896,7 @@
 %    \end{macrocode}
 % Set options.
 %    \begin{macrocode}
-      \keys_set:nn { zref-clever / reference } {#3}
+      \keys_set:nn { zref-clever/reference } {#3}
 %    \end{macrocode}
 % Store arguments values.
 %    \begin{macrocode}
@@ -3202,9 +3911,9 @@
 %    \begin{macrocode}
       \@@_provide_langfile:x { \l_@@_ref_language_tl }
 %    \end{macrocode}
-% Process \cs{zcDeclareLanguage} options.
+% Process language settings.
 %    \begin{macrocode}
-      \@@_process_language_options:
+      \@@_process_language_settings:
 %    \end{macrocode}
 % Integration with \pkg{zref-check}.
 %    \begin{macrocode}
@@ -3232,7 +3941,10 @@
 %    \begin{macrocode}
       \tl_if_empty:NF \l_@@_zcref_note_tl
         {
-          \@@_get_ref_opt_typeset:nN { notesep } \l_tmpa_tl
+          \@@_get_rf_opt_tl:nxxN { notesep }
+            { \l_@@_label_type_a_tl }
+            { \l_@@_ref_language_tl }
+            \l_tmpa_tl
           \l_tmpa_tl
           \l_@@_zcref_note_tl
         }
@@ -3280,9 +3992,11 @@
 %    \begin{macrocode}
 \NewDocumentCommand \zcpageref { s O { } m }
   {
-    \IfBooleanTF {#1}
-      { \zcref*[#2, ref = page] {#3} }
-      { \zcref [#2, ref = page] {#3} }
+    \group_begin:
+    \IfBooleanT {#1}
+      { \bool_set_false:N \l_@@_hyperlink_bool }
+    \zcref [#2, ref = page] {#3}
+    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
@@ -3370,7 +4084,7 @@
 % Store label types sequence.
 %    \begin{macrocode}
     \seq_clear:N \l_@@_label_types_seq
-    \tl_if_eq:NnF \l_@@_ref_property_tl { page }
+    \tl_if_eq:NnF \l_@@_ref_propserty_tl { page }
       {
         \seq_map_function:NN \l_@@_zcref_labels_seq
           \@@_label_type_put_new_right:n
@@ -3432,7 +4146,7 @@
 \cs_new_protected:Npn \@@_label_type_put_new_right:n #1
   {
     \@@_extract_default:Nnnn
-      \l_@@_label_type_a_tl {#1} { zc at type } { \c_empty_tl }
+      \l_@@_label_type_a_tl {#1} { zc at type } { }
     \seq_if_in:NVF \l_@@_label_types_seq
       \l_@@_label_type_a_tl
       {
@@ -3480,15 +4194,15 @@
 \cs_new_protected:Npn \@@_sort_default_same_type:nn #1#2
   {
     \@@_extract_default:Nnnn \l_@@_label_enclval_a_tl
-      {#1} { zc at enclval } { \c_empty_tl }
+      {#1} { zc at enclval } { }
     \tl_reverse:N \l_@@_label_enclval_a_tl
     \@@_extract_default:Nnnn \l_@@_label_enclval_b_tl
-      {#2} { zc at enclval } { \c_empty_tl }
+      {#2} { zc at enclval } { }
     \tl_reverse:N \l_@@_label_enclval_b_tl
     \@@_extract_default:Nnnn \l_@@_label_extdoc_a_tl
-      {#1} { externaldocument } { \c_empty_tl }
+      {#1} { externaldocument } { }
     \@@_extract_default:Nnnn \l_@@_label_extdoc_b_tl
-      {#2} { externaldocument } { \c_empty_tl }
+      {#2} { externaldocument } { }
 
     \bool_set_false:N \l_@@_sort_decided_bool
 
@@ -3819,11 +4533,13 @@
 %   {
 %     \l_@@_type_count_int ,
 %     \l_@@_label_count_int ,
+%     \l_@@_ref_count_int ,
 %   }
 %   Auxiliary variables for \cs{@@_typeset_refs:} main counters.
 %    \begin{macrocode}
 \int_new:N \l_@@_type_count_int
 \int_new:N \l_@@_label_count_int
+\int_new:N \l_@@_ref_count_int
 %    \end{macrocode}
 % \end{macro}
 %
@@ -3852,17 +4568,19 @@
 %   {
 %     \l_@@_type_name_tl ,
 %     \l_@@_name_in_link_bool ,
+%     \l_@@_type_name_missing_bool ,
 %     \l_@@_name_format_tl ,
 %     \l_@@_name_format_fallback_tl ,
-%     \l_@@_type_name_gender_tl ,
+%     \l_@@_type_name_gender_seq ,
 %   }
 %   Auxiliary variables for \cs{@@_typeset_refs:} type name handling.
 %    \begin{macrocode}
 \tl_new:N \l_@@_type_name_tl
 \bool_new:N \l_@@_name_in_link_bool
+\bool_new:N \l_@@_type_name_missing_bool
 \tl_new:N \l_@@_name_format_tl
 \tl_new:N \l_@@_name_format_fallback_tl
-\tl_new:N \l_@@_type_name_gender_tl
+\seq_new:N \l_@@_type_name_gender_seq
 %    \end{macrocode}
 % \end{macro}
 %
@@ -3894,15 +4612,13 @@
 %     \l_@@_listsep_tl ,
 %     \l_@@_lastsep_tl ,
 %     \l_@@_rangesep_tl ,
-%     \l_@@_preref_tl ,
-%     \l_@@_postref_tl ,
 %     \l_@@_namefont_tl ,
 %     \l_@@_reffont_tl ,
-%     \l_@@_capitalize_bool ,
+%     \l_@@_cap_bool ,
 %     \l_@@_abbrev_bool ,
 %   }
-%   Auxiliary variables for \cs{@@_typeset_refs:} separators, pre-/postref and
-%   font and other options.
+%     Auxiliary variables for \cs{@@_typeset_refs:} separators, and font and
+%     other options.
 %    \begin{macrocode}
 \tl_new:N \l_@@_tpairsep_tl
 \tl_new:N \l_@@_tlistsep_tl
@@ -3912,15 +4628,45 @@
 \tl_new:N \l_@@_listsep_tl
 \tl_new:N \l_@@_lastsep_tl
 \tl_new:N \l_@@_rangesep_tl
-\tl_new:N \l_@@_preref_tl
-\tl_new:N \l_@@_postref_tl
 \tl_new:N \l_@@_namefont_tl
 \tl_new:N \l_@@_reffont_tl
-\bool_new:N \l_@@_capitalize_bool
+\bool_new:N \l_@@_cap_bool
 \bool_new:N \l_@@_abbrev_bool
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}
+%   {
+%     \l_@@_refbounds_first_seq ,
+%     \l_@@_refbounds_first_sg_seq ,
+%     \l_@@_refbounds_first_pb_seq ,
+%     \l_@@_refbounds_first_rb_seq ,
+%     \l_@@_refbounds_mid_seq ,
+%     \l_@@_refbounds_mid_rb_seq ,
+%     \l_@@_refbounds_mid_re_seq ,
+%     \l_@@_refbounds_last_seq ,
+%     \l_@@_refbounds_last_pe_seq ,
+%     \l_@@_refbounds_last_re_seq ,
+%     \l_@@_type_first_refbounds_seq ,
+%     \l_@@_type_first_refbounds_set_bool ,
+%   }
+%   Auxiliary variables for \cs{@@_typeset_refs:}: advanced reference format
+%   options.
+%    \begin{macrocode}
+\seq_new:N \l_@@_refbounds_first_seq
+\seq_new:N \l_@@_refbounds_first_sg_seq
+\seq_new:N \l_@@_refbounds_first_pb_seq
+\seq_new:N \l_@@_refbounds_first_rb_seq
+\seq_new:N \l_@@_refbounds_mid_seq
+\seq_new:N \l_@@_refbounds_mid_rb_seq
+\seq_new:N \l_@@_refbounds_mid_re_seq
+\seq_new:N \l_@@_refbounds_last_seq
+\seq_new:N \l_@@_refbounds_last_pe_seq
+\seq_new:N \l_@@_refbounds_last_re_seq
+\seq_new:N \l_@@_type_first_refbounds_seq
+\bool_new:N \l_@@_type_first_refbounds_set_bool
+%    \end{macrocode}
+% \end{macro}
 %
 % \begin{macro}{\l_@@_verbose_testing_bool}
 %   Internal variable which enables extra log messaging at points of interest
@@ -3948,15 +4694,23 @@
     \tl_clear:N \l_@@_range_beg_label_tl
     \int_zero:N \l_@@_label_count_int
     \int_zero:N \l_@@_type_count_int
+    \int_zero:N \l_@@_ref_count_int
     \int_zero:N \l_@@_range_count_int
     \int_zero:N \l_@@_range_same_count_int
+    \bool_set_false:N \l_@@_type_first_refbounds_set_bool
 
     % Get type block options (not type-specific).
-    \@@_get_ref_opt_typeset:nN { tpairsep }
+    \@@_get_rf_opt_tl:nxxN { tpairsep }
+      { \l_@@_label_type_a_tl }
+      { \l_@@_ref_language_tl }
       \l_@@_tpairsep_tl
-    \@@_get_ref_opt_typeset:nN { tlistsep }
+    \@@_get_rf_opt_tl:nxxN { tlistsep }
+      { \l_@@_label_type_a_tl }
+      { \l_@@_ref_language_tl }
       \l_@@_tlistsep_tl
-    \@@_get_ref_opt_typeset:nN { tlastsep }
+    \@@_get_rf_opt_tl:nxxN { tlastsep }
+      { \l_@@_label_type_a_tl }
+      { \l_@@_ref_language_tl }
       \l_@@_tlastsep_tl
 
     % Process label stack.
@@ -4039,32 +4793,86 @@
               }
           }
 
-        % Get type-specific separators, pre-/postref font and other options,
-        % once per type.
+        % Get possibly type-specific separators, refbounds, font and other
+        % options, once per type.
         \int_compare:nNnT { \l_@@_label_count_int } = { 0 }
           {
-            \@@_get_ref_opt_typeset:nN { namesep  }
+            \@@_get_rf_opt_tl:nxxN { namesep }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_namesep_tl
-            \@@_get_ref_opt_typeset:nN { pairsep  }
+            \@@_get_rf_opt_tl:nxxN { pairsep }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_pairsep_tl
-            \@@_get_ref_opt_typeset:nN { listsep  }
+            \@@_get_rf_opt_tl:nxxN { listsep }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_listsep_tl
-            \@@_get_ref_opt_typeset:nN { lastsep  }
+            \@@_get_rf_opt_tl:nxxN { lastsep }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_lastsep_tl
-            \@@_get_ref_opt_typeset:nN { rangesep }
+            \@@_get_rf_opt_tl:nxxN { rangesep }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_rangesep_tl
-            \@@_get_ref_opt_typeset:nN { preref   }
-              \l_@@_preref_tl
-            \@@_get_ref_opt_typeset:nN { postref  }
-              \l_@@_postref_tl
-            \@@_get_ref_opt_font:nN { namefont }
+            \@@_get_rf_opt_tl:nxxN { namefont }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_namefont_tl
-            \@@_get_ref_opt_font:nN { reffont  }
+            \@@_get_rf_opt_tl:nxxN { reffont }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_reffont_tl
-            \@@_get_ref_opt_bool:nnN { cap    } { false }
-              \l_@@_capitalize_bool
-            \@@_get_ref_opt_bool:nnN { abbrev } { false }
+            \@@_get_rf_opt_bool:nnxxN { cap } { false }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_cap_bool
+            \@@_get_rf_opt_bool:nnxxN { abbrev } { false }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
               \l_@@_abbrev_bool
+            \@@_get_rf_opt_seq:nxxN { refbounds-first }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_first_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-first-sg }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_first_sg_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-first-pb }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_first_pb_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-first-rb }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_first_rb_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-mid }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_mid_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-mid-rb }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_mid_rb_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-mid-re }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_mid_re_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-last }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_last_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-last-pe }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_last_pe_seq
+            \@@_get_rf_opt_seq:nxxN { refbounds-last-re }
+              { \l_@@_label_type_a_tl }
+              { \l_@@_ref_language_tl }
+              \l_@@_refbounds_last_re_seq
           }
 
         % Here we send this to a couple of auxiliary functions.
@@ -4109,6 +4917,9 @@
             \l_@@_label_a_tl
           \tl_set:NV \l_@@_type_first_label_type_tl
             \l_@@_label_type_a_tl
+          \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+            \l_@@_refbounds_first_sg_seq
+          \bool_set_true:N \l_@@_type_first_refbounds_set_bool
         }
 
         % The last is the second: we have a pair (if not repeated).
@@ -4115,13 +4926,22 @@
         % Test: 'zc-typeset01.lvt': "Last of type: pair"
         { 1 }
         {
-          \int_compare:nNnF { \l_@@_range_same_count_int } = { 1 }
+          \int_compare:nNnTF { \l_@@_range_same_count_int } = { 1 }
             {
+              \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                \l_@@_refbounds_first_sg_seq
+              \bool_set_true:N \l_@@_type_first_refbounds_set_bool
+            }
+            {
               \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                 {
                   \exp_not:V \l_@@_pairsep_tl
-                  \@@_get_ref:V \l_@@_label_a_tl
+                  \@@_get_ref:VN \l_@@_label_a_tl
+                    \l_@@_refbounds_last_pe_seq
                 }
+              \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                \l_@@_refbounds_first_pb_seq
+              \bool_set_true:N \l_@@_type_first_refbounds_set_bool
             }
         }
       }
@@ -4134,28 +4954,56 @@
             % Test: 'zc-typeset01.lvt': "Last of type: not range"
             { 0 }
             {
-              \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+              \int_compare:nNnTF { \l_@@_ref_count_int } < { 2 }
                 {
-                  \exp_not:V \l_@@_lastsep_tl
-                  \@@_get_ref:V \l_@@_label_a_tl
+                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l_@@_pairsep_tl
+                      \@@_get_ref:VN \l_@@_label_a_tl
+                        \l_@@_refbounds_last_pe_seq
+                    }
                 }
+                {
+                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l_@@_lastsep_tl
+                      \@@_get_ref:VN \l_@@_label_a_tl
+                        \l_@@_refbounds_last_seq
+                    }
+                }
             }
             % Last in the range is also the second in it.
             % Test: 'zc-typeset01.lvt': "Last of type: pair in sequence"
             { 1 }
             {
-              \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+              \int_compare:nNnTF
+                { \l_@@_range_same_count_int } = { 1 }
                 {
                   % We know `range_beg_label' is not empty, since this is the
                   % second element in the range, but the third or more in the
                   % type list.
-                  \exp_not:V \l_@@_listsep_tl
-                  \@@_get_ref:V \l_@@_range_beg_label_tl
-                  \int_compare:nNnF
-                    { \l_@@_range_same_count_int } = { 1 }
+                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                     {
+                      \exp_not:V \l_@@_pairsep_tl
+                      \@@_get_ref:VN
+                        \l_@@_range_beg_label_tl
+                        \l_@@_refbounds_last_pe_seq
+                    }
+                  \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                    \l_@@_refbounds_first_pb_seq
+                  \bool_set_true:N
+                    \l_@@_type_first_refbounds_set_bool
+                }
+                {
+                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l_@@_listsep_tl
+                      \@@_get_ref:VN
+                        \l_@@_range_beg_label_tl
+                        \l_@@_refbounds_mid_seq
                       \exp_not:V \l_@@_lastsep_tl
-                      \@@_get_ref:V \l_@@_label_a_tl
+                      \@@_get_ref:VN \l_@@_label_a_tl
+                        \l_@@_refbounds_last_seq
                     }
                 }
             }
@@ -4173,32 +5021,71 @@
                 { 0 }
                 {
                   % If `range_beg_label' is empty, it means it was also the
-                  % first of the type, and hence was already handled.
-                  \tl_if_empty:VF \l_@@_range_beg_label_tl
+                  % first of the type, and hence its typesetting was already
+                  % handled, and we just have to set refbounds.
+                  \tl_if_empty:VTF \l_@@_range_beg_label_tl
                     {
-                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                      \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                        \l_@@_refbounds_first_sg_seq
+                      \bool_set_true:N
+                        \l_@@_type_first_refbounds_set_bool
+                    }
+                    {
+                      \int_compare:nNnTF
+                        { \l_@@_ref_count_int } < { 2 }
                         {
-                          \exp_not:V \l_@@_lastsep_tl
-                          \@@_get_ref:V
-                            \l_@@_range_beg_label_tl
+                          \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                            {
+                              \exp_not:V \l_@@_pairsep_tl
+                              \@@_get_ref:VN
+                                \l_@@_range_beg_label_tl
+                                \l_@@_refbounds_last_pe_seq
+                            }
                         }
+                        {
+                          \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                            {
+                              \exp_not:V \l_@@_lastsep_tl
+                              \@@_get_ref:VN
+                                \l_@@_range_beg_label_tl
+                                \l_@@_refbounds_last_seq
+                            }
+                        }
                     }
                 }
-                % A `range', but with no skipped value, treat as list.
+                % A `range', but with no skipped value, treat as pair if range
+                % started with first of type, otherwise as list.
                 % Test: 'zc-typeset01.lvt': "Last of type: range to pair"
                 { 1 }
                 {
-                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                  % Ditto.
+                  \tl_if_empty:VTF \l_@@_range_beg_label_tl
                     {
-                      % Ditto.
-                      \tl_if_empty:VF \l_@@_range_beg_label_tl
+                      \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                        \l_@@_refbounds_first_pb_seq
+                      \bool_set_true:N
+                        \l_@@_type_first_refbounds_set_bool
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                         {
+                          \exp_not:V \l_@@_pairsep_tl
+                          \@@_get_ref:VN \l_@@_label_a_tl
+                            \l_@@_refbounds_last_pe_seq
+                        }
+                    }
+                    {
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                        {
                           \exp_not:V \l_@@_listsep_tl
-                          \@@_get_ref:V
+                          \@@_get_ref:VN
                             \l_@@_range_beg_label_tl
+                            \l_@@_refbounds_mid_seq
                         }
-                      \exp_not:V \l_@@_lastsep_tl
-                      \@@_get_ref:V \l_@@_label_a_tl
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                        {
+                          \exp_not:V \l_@@_lastsep_tl
+                          \@@_get_ref:VN \l_@@_label_a_tl
+                            \l_@@_refbounds_last_seq
+                        }
                     }
                 }
               }
@@ -4205,17 +5092,46 @@
               {
                 % An actual range.
                 % Test: 'zc-typeset01.lvt': "Last of type: range"
-                \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                % Ditto.
+                \tl_if_empty:VTF \l_@@_range_beg_label_tl
                   {
-                    % Ditto.
-                    \tl_if_empty:VF \l_@@_range_beg_label_tl
+                    \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                      \l_@@_refbounds_first_rb_seq
+                    \bool_set_true:N
+                      \l_@@_type_first_refbounds_set_bool
+                  }
+                  {
+                    \int_compare:nNnTF
+                      { \l_@@_ref_count_int } < { 2 }
                       {
-                        \exp_not:V \l_@@_lastsep_tl
-                        \@@_get_ref:V
-                          \l_@@_range_beg_label_tl
+                        \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                          {
+                            \exp_not:V \l_@@_pairsep_tl
+                            \@@_get_ref:VN
+                              \l_@@_range_beg_label_tl
+                              \l_@@_refbounds_mid_rb_seq
+                          }
+                        \seq_set_eq:NN
+                          \l_@@_type_first_refbounds_seq
+                          \l_@@_refbounds_first_pb_seq
+                        \bool_set_true:N
+                          \l_@@_type_first_refbounds_set_bool
                       }
+                      {
+                        \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                          {
+                            \exp_not:V \l_@@_lastsep_tl
+                            \@@_get_ref:VN
+                              \l_@@_range_beg_label_tl
+                              \l_@@_refbounds_mid_rb_seq
+                          }
+                      }
+                  }
+                \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                  {
                     \exp_not:V \l_@@_rangesep_tl
-                    \@@_get_ref:V \l_@@_label_a_tl
+                    \@@_get_ref:VN \l_@@_label_a_tl
+                      \l_@@_refbounds_last_re_seq
                   }
               }
           }
@@ -4247,16 +5163,40 @@
               }
             % Test: 'zc-typeset01.lvt': "Last of type: option range"
             % Test: 'zc-typeset01.lvt': "Last of type: option range to pair"
-            \tl_set:Nx \l_@@_typeset_queue_curr_tl
+            \bool_if:NTF \l_@@_next_maybe_range_bool
               {
-                \bool_if:NTF \l_@@_next_maybe_range_bool
-                  { \exp_not:V \l_@@_pairsep_tl }
-                  { \exp_not:V \l_@@_rangesep_tl }
-                \@@_get_ref:V \l_@@_label_a_tl
+                \tl_set:Nx \l_@@_typeset_queue_curr_tl
+                  {
+                    \exp_not:V \l_@@_pairsep_tl
+                    \@@_get_ref:VN \l_@@_label_a_tl
+                      \l_@@_refbounds_last_pe_seq
+                  }
+                \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                  \l_@@_refbounds_first_pb_seq
+                \bool_set_true:N \l_@@_type_first_refbounds_set_bool
               }
+              {
+                \tl_set:Nx \l_@@_typeset_queue_curr_tl
+                  {
+                    \exp_not:V \l_@@_rangesep_tl
+                    \@@_get_ref:VN \l_@@_label_a_tl
+                      \l_@@_refbounds_last_re_seq
+                  }
+                \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                  \l_@@_refbounds_first_rb_seq
+                \bool_set_true:N \l_@@_type_first_refbounds_set_bool
+              }
           }
       }
 
+    % If none of the special cases for the first of type refbounds have been
+    % set, do it.
+    \bool_if:NF \l_@@_type_first_refbounds_set_bool
+      {
+        \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+          \l_@@_refbounds_first_seq
+      }
+
     % Now that the type block is finished, we can add the name and the first
     % ref to the queue.  Also, if "typeset" option is not "both", handle it
     % here as well.
@@ -4272,7 +5212,10 @@
           {
             % Test: 'zc-typeset01.lvt': "Last of type: option typeset ref"
             \tl_put_left:Nx \l_@@_typeset_queue_curr_tl
-              { \@@_get_ref:V \l_@@_type_first_label_tl }
+              {
+                \@@_get_ref:VN \l_@@_type_first_label_tl
+                  \l_@@_type_first_refbounds_seq
+              }
           }
           {
             \bool_if:NTF \l_@@_typeset_name_bool
@@ -4372,9 +5315,11 @@
         \tl_clear:N \l_@@_type_first_label_type_tl
         \tl_clear:N \l_@@_range_beg_label_tl
         \int_zero:N \l_@@_label_count_int
+        \int_zero:N \l_@@_ref_count_int
         \int_incr:N \l_@@_type_count_int
         \int_zero:N \l_@@_range_count_int
         \int_zero:N \l_@@_range_same_count_int
+        \bool_set_false:N \l_@@_type_first_refbounds_set_bool
       }
   }
 %    \end{macrocode}
@@ -4409,6 +5354,7 @@
           \l_@@_label_a_tl
         \tl_set:NV \l_@@_type_first_label_type_tl
           \l_@@_label_type_a_tl
+        \int_incr:N \l_@@_ref_count_int
 
         % If the next label may be part of a range, we set `range_beg_label'
         % to "empty" (we deal with it as the "first", and must do it there, to
@@ -4453,10 +5399,12 @@
                 % Test: 'zc-typeset01.lvt': "Not last of type: no range"
                 { 0 }
                 {
+                  \int_incr:N \l_@@_ref_count_int
                   \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                     {
                       \exp_not:V \l_@@_listsep_tl
-                      \@@_get_ref:V \l_@@_label_a_tl
+                      \@@_get_ref:VN \l_@@_label_a_tl
+                        \l_@@_refbounds_mid_seq
                     }
                 }
                 % Last is second in the range: if `range_same_count' is also
@@ -4466,20 +5414,33 @@
                 % Test: 'zc-typeset01.lvt': "Not last of type: range pair"
                 { 1 }
                 {
-                  \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                  \tl_if_empty:VTF \l_@@_range_beg_label_tl
                     {
-                      \tl_if_empty:VF \l_@@_range_beg_label_tl
+                      \seq_set_eq:NN \l_@@_type_first_refbounds_seq
+                        \l_@@_refbounds_first_seq
+                      \bool_set_true:N
+                        \l_@@_type_first_refbounds_set_bool
+                    }
+                    {
+                      \int_incr:N \l_@@_ref_count_int
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                         {
                           \exp_not:V \l_@@_listsep_tl
-                          \@@_get_ref:V
+                          \@@_get_ref:VN
                             \l_@@_range_beg_label_tl
+                            \l_@@_refbounds_mid_seq
                         }
-                      \int_compare:nNnF
-                        { \l_@@_range_same_count_int } = { 1 }
+                    }
+                  \int_compare:nNnF
+                    { \l_@@_range_same_count_int } = { 1 }
+                    {
+                      \int_incr:N \l_@@_ref_count_int
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                         {
                           \exp_not:V \l_@@_listsep_tl
-                          \@@_get_ref:V
+                          \@@_get_ref:VN
                             \l_@@_label_a_tl
+                            \l_@@_refbounds_mid_seq
                         }
                     }
                 }
@@ -4498,13 +5459,22 @@
                     % Test: 'zc-typeset01.lvt': "Not last of type: range to one"
                     { 0 }
                     {
-                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                      \tl_if_empty:VTF \l_@@_range_beg_label_tl
                         {
-                          \tl_if_empty:VF \l_@@_range_beg_label_tl
+                          \seq_set_eq:NN
+                            \l_@@_type_first_refbounds_seq
+                            \l_@@_refbounds_first_seq
+                          \bool_set_true:N
+                            \l_@@_type_first_refbounds_set_bool
+                        }
+                        {
+                          \int_incr:N \l_@@_ref_count_int
+                          \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                             {
                               \exp_not:V \l_@@_listsep_tl
-                              \@@_get_ref:V
+                              \@@_get_ref:VN
                                 \l_@@_range_beg_label_tl
+                                \l_@@_refbounds_mid_seq
                             }
                         }
                     }
@@ -4511,31 +5481,63 @@
                     % Test: 'zc-typeset01.lvt': "Not last of type: range to pair"
                     { 1 }
                     {
-                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                      \tl_if_empty:VTF \l_@@_range_beg_label_tl
                         {
-                          \tl_if_empty:VF \l_@@_range_beg_label_tl
+                          \seq_set_eq:NN
+                            \l_@@_type_first_refbounds_seq
+                            \l_@@_refbounds_first_seq
+                          \bool_set_true:N
+                            \l_@@_type_first_refbounds_set_bool
+                        }
+                        {
+                          \int_incr:N \l_@@_ref_count_int
+                          \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                             {
                               \exp_not:V \l_@@_listsep_tl
-                              \@@_get_ref:V
+                              \@@_get_ref:VN
                                 \l_@@_range_beg_label_tl
+                                \l_@@_refbounds_mid_seq
                             }
+                        }
+                      \int_incr:N \l_@@_ref_count_int
+                      \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                        {
                           \exp_not:V \l_@@_listsep_tl
-                          \@@_get_ref:V \l_@@_label_a_tl
+                          \@@_get_ref:VN \l_@@_label_a_tl
+                            \l_@@_refbounds_mid_seq
                         }
                     }
                   }
                   {
                     % Test: 'zc-typeset01.lvt': "Not last of type: range"
-                    \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                    \tl_if_empty:VTF \l_@@_range_beg_label_tl
                       {
-                        \tl_if_empty:VF \l_@@_range_beg_label_tl
+                        \seq_set_eq:NN
+                          \l_@@_type_first_refbounds_seq
+                          \l_@@_refbounds_first_rb_seq
+                        \bool_set_true:N
+                          \l_@@_type_first_refbounds_set_bool
+                      }
+                      {
+                        \int_incr:N \l_@@_ref_count_int
+                        \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
                           {
                             \exp_not:V \l_@@_listsep_tl
-                            \@@_get_ref:V
+                            \@@_get_ref:VN
                               \l_@@_range_beg_label_tl
+                              \l_@@_refbounds_mid_rb_seq
                           }
+                      }
+                    % For the purposes of the serial comma, and thus for the
+                    % distinction of 'lastsep' and 'pairsep', a "range" counts
+                    % as one.  Since 'range_beg' has already been counted
+                    % (here or with the first of type), we refrain from
+                    % incrementing 'ref_count_int'.
+                    \tl_put_right:Nx \l_@@_typeset_queue_curr_tl
+                      {
                         \exp_not:V \l_@@_rangesep_tl
-                        \@@_get_ref:V \l_@@_label_a_tl
+                        \@@_get_ref:VN \l_@@_label_a_tl
+                          \l_@@_refbounds_mid_re_seq
                       }
                   }
               }
@@ -4554,8 +5556,8 @@
 %
 % \subsection*{Auxiliary functions}
 %
-% \cs{@@_get_ref:n} and \cs{@@_get_ref_first:} are the two functions which
-% actually build the reference blocks for typesetting.  \cs{@@_get_ref:n}
+% \cs{@@_get_ref:nN} and \cs{@@_get_ref_first:} are the two functions which
+% actually build the reference blocks for typesetting.  \cs{@@_get_ref:nN}
 % handles all references but the first of its type, and \cs{@@_get_ref_first:}
 % deals with the first reference of a type.  Saying they do ``typesetting'' is
 % imprecise though, they actually prepare material to be accumulated in
@@ -4566,10 +5568,10 @@
 % the queue, we are using a number of variables which are transient to the
 % current label, the label properties among them, but not only.  Hence, these
 % variables \emph{must} be expanded to their current values to be stored in
-% the queue.  Indeed, \cs{@@_get_ref:n} and \cs{@@_get_ref_first:} get called,
-% as they must, in the context of \texttt{x} type expansions.  But we don't
-% want to expand the values of the variables themselves, so we need to get
-% current values, but stop expansion after that.  In particular, reference
+% the queue.  Indeed, \cs{@@_get_ref:nN} and \cs{@@_get_ref_first:} get
+% called, as they must, in the context of \texttt{x} type expansions.  But we
+% don't want to expand the values of the variables themselves, so we need to
+% get current values, but stop expansion after that.  In particular, reference
 % options given by the user should reach the stream for its final typesetting
 % (when the queue itself gets typeset) \emph{unmodified} (``no manipulation'',
 % to use the \texttt{n} signature jargon).  We also need to prevent premature
@@ -4594,58 +5596,55 @@
 % \end{macro}
 %
 %
-% \begin{macro}{\@@_get_ref:n}
+% \begin{macro}{\@@_get_ref:nN}
 %   Handles a complete reference block to be accumulated in the ``queue'',
-%   including ``pre'' and ``pos'' elements, and hyperlinking.  For use with
-%   all labels, except the first of its type, which is done by
-%   \cs{@@_get_ref_first:}.
+%   including refbounds, and hyperlinking.  For use with all labels, except
+%   the first of its type, which is done by \cs{@@_get_ref_first:}.
 %   \begin{syntax}
-%     \cs{@@_get_ref:n} \Arg{label}
+%     \cs{@@_get_ref:nN} \Arg{label} \Arg{refbounds}
 %   \end{syntax}
 %    \begin{macrocode}
-\cs_new:Npn \@@_get_ref:n #1
+\cs_new:Npn \@@_get_ref:nN #1#2
   {
     \zref at ifrefcontainsprop {#1} { \l_@@_ref_property_tl }
       {
         \bool_if:nTF
           {
-            \l_@@_use_hyperref_bool &&
+            \l_@@_hyperlink_bool &&
             ! \l_@@_link_star_bool
           }
           {
-            \bool_if:NF \l_@@_preposinlink_bool
-              { \exp_not:V \l_@@_preref_tl }
+            \exp_not:N \group_begin:
+            \exp_not:V \l_@@_reffont_tl
+            \seq_item:Nn #2 { 1 }
             % It's two `@s', but escaped for DocStrip.
             \exp_not:N \hyper@@@@link
               { \@@_extract_url_unexp:n {#1} }
               { \@@_extract_unexp:nnn {#1} { anchor } { } }
               {
-                \bool_if:NT \l_@@_preposinlink_bool
-                  { \exp_not:V \l_@@_preref_tl }
-                \exp_not:N \group_begin:
-                \exp_not:V \l_@@_reffont_tl
+                \seq_item:Nn #2 { 2 }
                 \@@_extract_unexp:nvn {#1}
                   { l_@@_ref_property_tl } { }
-                \exp_not:N \group_end:
-                \bool_if:NT \l_@@_preposinlink_bool
-                  { \exp_not:V \l_@@_postref_tl }
+                \seq_item:Nn #2 { 3 }
               }
-            \bool_if:NF \l_@@_preposinlink_bool
-              { \exp_not:V \l_@@_postref_tl }
+            \seq_item:Nn #2 { 4 }
+            \exp_not:N \group_end:
           }
           {
-            \exp_not:V \l_@@_preref_tl
             \exp_not:N \group_begin:
             \exp_not:V \l_@@_reffont_tl
+            \seq_item:Nn #2 { 1 }
+            \seq_item:Nn #2 { 2 }
             \@@_extract_unexp:nvn {#1}
               { l_@@_ref_property_tl } { }
+            \seq_item:Nn #2 { 3 }
+            \seq_item:Nn #2 { 4 }
             \exp_not:N \group_end:
-            \exp_not:V \l_@@_postref_tl
           }
       }
       { \@@_ref_default: }
   }
-\cs_generate_variant:Nn \@@_get_ref:n { V }
+\cs_generate_variant:Nn \@@_get_ref:nN { VN }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4671,6 +5670,7 @@
               { \l_@@_type_first_label_tl }
               { \l_@@_ref_property_tl }
               {
+                \exp_not:N \group_begin:
                 % It's two `@s', but escaped for DocStrip.
                 \exp_not:N \hyper@@@@link
                   {
@@ -4687,18 +5687,19 @@
                     \exp_not:V \l_@@_type_name_tl
                     \exp_not:N \group_end:
                     \exp_not:V \l_@@_namesep_tl
-                    \exp_not:V \l_@@_preref_tl
                     \exp_not:N \group_begin:
                     \exp_not:V \l_@@_reffont_tl
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 1 }
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 2 }
                     \@@_extract_unexp:Vvn
                       \l_@@_type_first_label_tl
                       { l_@@_ref_property_tl } { }
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 3 }
                     \exp_not:N \group_end:
-                    \bool_if:NT \l_@@_preposinlink_bool
-                      { \exp_not:V \l_@@_postref_tl }
                   }
-                \bool_if:NF \l_@@_preposinlink_bool
-                  { \exp_not:V \l_@@_postref_tl }
+                \exp_not:V \l_@@_reffont_tl
+                \seq_item:Nn \l_@@_type_first_refbounds_seq { 4 }
+                \exp_not:N \group_end:
               }
               {
                 \exp_not:N \group_begin:
@@ -4710,7 +5711,7 @@
               }
           }
           {
-            \tl_if_empty:NTF \l_@@_type_name_tl
+            \bool_if:nTF \l_@@_type_name_missing_bool
               {
                 \@@_name_default:
                 \exp_not:V \l_@@_namesep_tl
@@ -4720,7 +5721,8 @@
                 \exp_not:V \l_@@_namefont_tl
                 \exp_not:V \l_@@_type_name_tl
                 \exp_not:N \group_end:
-                \exp_not:V \l_@@_namesep_tl
+                \tl_if_empty:NF \l_@@_type_name_tl
+                  { \exp_not:V \l_@@_namesep_tl }
               }
             \zref at ifrefcontainsprop
               { \l_@@_type_first_label_tl }
@@ -4728,12 +5730,14 @@
               {
                 \bool_if:nTF
                   {
-                    \l_@@_use_hyperref_bool &&
+                    \l_@@_hyperlink_bool &&
                     ! \l_@@_link_star_bool
                   }
                   {
-                    \bool_if:NF \l_@@_preposinlink_bool
-                      { \exp_not:V \l_@@_preref_tl }
+                    \exp_not:N \group_begin:
+                    \exp_not:V \l_@@_reffont_tl
+                    \seq_item:Nn
+                      \l_@@_type_first_refbounds_seq { 1 }
                     % It's two '@s', but escaped for DocStrip.
                     \exp_not:N \hyper@@@@link
                       {
@@ -4745,29 +5749,29 @@
                           \l_@@_type_first_label_tl { anchor } { }
                       }
                       {
-                        \bool_if:NT \l_@@_preposinlink_bool
-                          { \exp_not:V \l_@@_preref_tl }
-                        \exp_not:N \group_begin:
-                        \exp_not:V \l_@@_reffont_tl
+                        \seq_item:Nn
+                          \l_@@_type_first_refbounds_seq { 2 }
                         \@@_extract_unexp:Vvn
                           \l_@@_type_first_label_tl
                           { l_@@_ref_property_tl } { }
-                        \exp_not:N \group_end:
-                        \bool_if:NT \l_@@_preposinlink_bool
-                          { \exp_not:V \l_@@_postref_tl }
+                        \seq_item:Nn
+                          \l_@@_type_first_refbounds_seq { 3 }
                       }
-                    \bool_if:NF \l_@@_preposinlink_bool
-                      { \exp_not:V \l_@@_postref_tl }
+                    \seq_item:Nn
+                      \l_@@_type_first_refbounds_seq { 4 }
+                    \exp_not:N \group_end:
                   }
                   {
-                    \exp_not:V \l_@@_preref_tl
                     \exp_not:N \group_begin:
                     \exp_not:V \l_@@_reffont_tl
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 1 }
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 2 }
                     \@@_extract_unexp:Vvn
                       \l_@@_type_first_label_tl
                       { l_@@_ref_property_tl } { }
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 3 }
+                    \seq_item:Nn \l_@@_type_first_refbounds_seq { 4 }
                     \exp_not:N \group_end:
-                    \exp_not:V \l_@@_postref_tl
                   }
               }
               { \@@_ref_default: }
@@ -4794,18 +5798,24 @@
 \cs_new_protected:Npn \@@_type_name_setup:
   {
     \zref at ifrefundefined { \l_@@_type_first_label_tl }
-      { \tl_clear:N \l_@@_type_name_tl }
       {
+        \tl_clear:N \l_@@_type_name_tl
+        \bool_set_true:N \l_@@_type_name_missing_bool
+      }
+      {
         \tl_if_eq:NnTF
           \l_@@_type_first_label_type_tl { zc at missingtype }
-          { \tl_clear:N \l_@@_type_name_tl }
           {
+            \tl_clear:N \l_@@_type_name_tl
+            \bool_set_true:N \l_@@_type_name_missing_bool
+          }
+          {
             % Determine whether we should use capitalization, abbreviation,
             % and plural.
             \bool_lazy_or:nnTF
-              { \l_@@_capitalize_bool }
+              { \l_@@_cap_bool }
               {
-                \l_@@_capitalize_first_bool &&
+                \l_@@_capfirst_bool &&
                 \int_compare_p:nNn { \l_@@_type_count_int } = { 0 }
               }
               { \tl_set:Nn \l_@@_name_format_tl {Name} }
@@ -4860,19 +5870,15 @@
                   { \l_@@_nudge_gender_bool }
                   { ! \tl_if_empty_p:N \l_@@_ref_gender_tl }
                   {
-                    \@@_get_lang_opt_type:xxnNF
+                    \@@_get_rf_opt_seq:nxxN { gender }
+                      { \l_@@_type_first_label_type_tl }
                       { \l_@@_ref_language_tl }
-                      { \l_@@_type_first_label_type_tl }
-                      { gender }
-                      \l_@@_type_name_gender_tl
-                      { \tl_clear:N \l_@@_type_name_gender_tl }
-                    \clist_set:NV \l_tmpa_clist
-                      \l_@@_type_name_gender_tl
-                    \clist_if_in:NVF
-                      \l_tmpa_clist
+                      \l_@@_type_name_gender_seq
+                    \seq_if_in:NVF
+                      \l_@@_type_name_gender_seq
                       \l_@@_ref_gender_tl
                       {
-                        \tl_if_empty:NTF \l_@@_type_name_gender_tl
+                        \seq_if_empty:NTF \l_@@_type_name_gender_seq
                           {
                             \msg_warning:nnxxx { zref-clever }
                               { nudge-gender-not-declared-for-type }
@@ -4885,7 +5891,10 @@
                               { nudge-gender-mismatch }
                               { \l_@@_type_first_label_type_tl }
                               { \l_@@_ref_gender_tl }
-                              { \l_@@_type_name_gender_tl }
+                              {
+                                \seq_use:Nn
+                                  \l_@@_type_name_gender_seq { ,~ }
+                              }
                               { \l_@@_ref_language_tl }
                           }
                       }
@@ -4894,12 +5903,13 @@
 
             \tl_if_empty:NTF \l_@@_name_format_fallback_tl
               {
-                \prop_get:cVNF
+                \@@_opt_tl_get:cNF
                   {
-                    l_@@_type_
-                    \l_@@_type_first_label_type_tl _options_prop
+                    \@@_opt_varname_type:een
+                      { \l_@@_type_first_label_type_tl }
+                      { \l_@@_name_format_tl }
+                      { tl }
                   }
-                  \l_@@_name_format_tl
                   \l_@@_type_name_tl
                   {
                     \tl_if_empty:NF \l_@@_ref_decl_case_tl
@@ -4908,13 +5918,18 @@
                         \tl_put_left:NV \l_@@_name_format_tl
                           \l_@@_ref_decl_case_tl
                       }
-                    \@@_get_lang_opt_type:xxxNF
-                      { \l_@@_ref_language_tl }
-                      { \l_@@_type_first_label_type_tl }
-                      { \l_@@_name_format_tl }
+                    \@@_opt_tl_get:cNF
+                      {
+                        \@@_opt_varname_lang_type:eeen
+                          { \l_@@_ref_language_tl }
+                          { \l_@@_type_first_label_type_tl }
+                          { \l_@@_name_format_tl }
+                          { tl }
+                      }
                       \l_@@_type_name_tl
                       {
                         \tl_clear:N \l_@@_type_name_tl
+                        \bool_set_true:N \l_@@_type_name_missing_bool
                         \msg_warning:nnxx { zref-clever } { missing-name }
                           { \l_@@_name_format_tl }
                           { \l_@@_type_first_label_type_tl }
@@ -4922,20 +5937,22 @@
                   }
               }
               {
-                \prop_get:cVNF
+                \@@_opt_tl_get:cNF
                   {
-                    l_@@_type_
-                    \l_@@_type_first_label_type_tl _options_prop
+                    \@@_opt_varname_type:een
+                      { \l_@@_type_first_label_type_tl }
+                      { \l_@@_name_format_tl }
+                      { tl }
                   }
-                  \l_@@_name_format_tl
                   \l_@@_type_name_tl
                   {
-                    \prop_get:cVNF
+                    \@@_opt_tl_get:cNF
                       {
-                        l_@@_type_
-                        \l_@@_type_first_label_type_tl _options_prop
+                        \@@_opt_varname_type:een
+                          { \l_@@_type_first_label_type_tl }
+                          { \l_@@_name_format_fallback_tl }
+                          { tl }
                       }
-                      \l_@@_name_format_fallback_tl
                       \l_@@_type_name_tl
                       {
                         \tl_if_empty:NF \l_@@_ref_decl_case_tl
@@ -4950,19 +5967,29 @@
                               \l_@@_name_format_fallback_tl
                               \l_@@_ref_decl_case_tl
                           }
-                        \@@_get_lang_opt_type:xxxNF
-                          { \l_@@_ref_language_tl }
-                          { \l_@@_type_first_label_type_tl }
-                          { \l_@@_name_format_tl }
-                          \l_@@_type_name_tl
+                        \@@_opt_tl_get:cNF
                           {
-                            \@@_get_lang_opt_type:xxxNF
+                            \@@_opt_varname_lang_type:eeen
                               { \l_@@_ref_language_tl }
                               { \l_@@_type_first_label_type_tl }
-                              { \l_@@_name_format_fallback_tl }
+                              { \l_@@_name_format_tl }
+                              { tl }
+                          }
+                          \l_@@_type_name_tl
+                          {
+                            \@@_opt_tl_get:cNF
+                              {
+                                \@@_opt_varname_lang_type:eeen
+                                  { \l_@@_ref_language_tl }
+                                  { \l_@@_type_first_label_type_tl }
+                                  { \l_@@_name_format_fallback_tl }
+                                  { tl }
+                              }
                               \l_@@_type_name_tl
                               {
                                 \tl_clear:N \l_@@_type_name_tl
+                                \bool_set_true:N
+                                  \l_@@_type_name_missing_bool
                                 \msg_warning:nnxx { zref-clever }
                                   { missing-name }
                                   { \l_@@_name_format_tl }
@@ -4978,7 +6005,7 @@
     % Signal whether the type name is to be included in the hyperlink or not.
     \bool_lazy_any:nTF
       {
-        { ! \l_@@_use_hyperref_bool }
+        { ! \l_@@_hyperlink_bool }
         { \l_@@_link_star_bool }
         { \tl_if_empty_p:N \l_@@_type_name_tl }
         { \str_if_eq_p:Vn \l_@@_nameinlink_str { false } }
@@ -5017,11 +6044,11 @@
 \cs_new:Npn \@@_extract_url_unexp:n #1
   {
     \zref at ifpropundefined { urluse }
-      { \@@_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+      { \@@_extract_unexp:nnn {#1} { url } { } }
       {
         \zref at ifrefcontainsprop {#1} { urluse }
-          { \@@_extract_unexp:nnn {#1} { urluse } { \c_empty_tl } }
-          { \@@_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+          { \@@_extract_unexp:nnn {#1} { urluse } { } }
+          { \@@_extract_unexp:nnn {#1} { url } { } }
       }
   }
 \cs_generate_variant:Nn \@@_extract_url_unexp:n { V }
@@ -5045,9 +6072,9 @@
 \cs_new_protected:Npn \@@_labels_in_sequence:nn #1#2
   {
     \@@_extract_default:Nnnn \l_@@_label_extdoc_a_tl
-      {#1} { externaldocument } { \c_empty_tl }
+      {#1} { externaldocument } { }
     \@@_extract_default:Nnnn \l_@@_label_extdoc_b_tl
-      {#2} { externaldocument } { \c_empty_tl }
+      {#2} { externaldocument } { }
 
     \tl_if_eq:NNT
       \l_@@_label_extdoc_a_tl
@@ -5124,187 +6151,142 @@
 %
 %
 % Finally, some functions for retrieving reference options values, according
-% to the relevant precedence rules.  They both receive an \meta{option} as
-% argument, and store the retrieved value in an appropriate.  Though these are
-% mostly general functions (for a change\dots{}), they are not completely so,
-% they rely on the current state of \cs{l_@@_label_type_a_tl}, as set during
-% the processing of the label stack.  This could be easily generalized, of
-% course, but I don't think it is worth it, \cs{l_@@_label_type_a_tl} is
-% indeed what we want in all practical cases.  The difference between each of
-% these functions is the kind of option each should be used for.
-% \cs{@@_get_ref_opt_typeset:nN} is meant for the general options, and
-% attempts to find values for them in all precedence levels (four plus
-% ``fallback'').  \cs{@@_get_ref_opt_font:nN} is intended for ``font''
-% options, which cannot be ``language-specific'', thus for these we just
-% search general options and type options.  \cs{@@_get_ref_opt_bool:nN} is
-% intended for boolean options.
+% to the relevant precedence rules.  They receive an \meta{option} as
+% argument, and store the retrieved value in an appropriate \meta{variable}.
+% The difference between each of these functions is the data type of the
+% option each should be used for.
 %
-% \begin{macro}{\@@_get_ref_opt_typeset:nN}
+%
+% \begin{macro}{\@@_get_rf_opt_tl:nnnN}
 %   \begin{syntax}
-%     \cs{@@_get_ref_opt_typeset:nN} \Arg{option} \Arg{tl variable}
+%     \cs{@@_get_rf_opt_tl:nnnN} \Arg{option}
+%     ~~\Arg{ref type} \Arg{language} \Arg{tl variable}
 %   \end{syntax}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_get_ref_opt_typeset:nN #1#2
+\cs_new_protected:Npn \@@_get_rf_opt_tl:nnnN #1#2#3#4
   {
     % First attempt: general options.
-    \prop_get:NnNF \l_@@_ref_options_prop {#1} #2
+    \@@_opt_tl_get:cNF
+      { \@@_opt_varname_general:nn {#1} { tl } }
+      #4
       {
         % If not found, try type specific options.
-        \bool_lazy_and:nnTF
+        \@@_opt_tl_get:cNF
+          { \@@_opt_varname_type:nnn {#2} {#1} { tl } }
+          #4
           {
-            \prop_if_exist_p:c
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-          }
-          {
-            \prop_if_in_p:cn
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-              {#1}
-          }
-          {
-            \prop_get:cnN
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-              {#1} #2
-          }
-          {
             % If not found, try type- and language-specific.
-            \@@_get_lang_opt_type:xxnNF
-              { \l_@@_ref_language_tl }
-              { \l_@@_label_type_a_tl }
-              {#1} #2
+            \@@_opt_tl_get:cNF
+              { \@@_opt_varname_lang_type:nnnn {#3} {#2} {#1} { tl } }
+              #4
               {
                 % If not found, try language-specific default.
-                \@@_get_lang_opt_default:xnNF
-                  { \l_@@_ref_language_tl }
-                  {#1} #2
+                \@@_opt_tl_get:cNF
+                  { \@@_opt_varname_lang_default:nnn {#3} {#1} { tl } }
+                  #4
                   {
                     % If not found, try fallback.
-                    \@@_get_fallback_unknown_lang_opt:nNF {#1} #2
-                      {
-                        \tl_clear:N #2
-                        \msg_warning:nnn { zref-clever }
-                          { missing-string } {#1}
-                      }
+                    \@@_opt_tl_get:cNF
+                      { \@@_opt_varname_fallback:nn {#1} { tl } }
+                      #4
+                      { \tl_clear:N #4 }
                   }
               }
           }
       }
   }
+\cs_generate_variant:Nn \@@_get_rf_opt_tl:nnnN { nxxN }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_get_ref_opt_font:nN}
+%
+% \begin{macro}{\@@_get_rf_opt_seq:nnnN}
 %   \begin{syntax}
-%     \cs{@@_get_ref_opt_font:nN} \Arg{option} \Arg{tl variable}
+%     \cs{@@_get_rf_opt_seq:nnnN} \Arg{option}
+%     ~~\Arg{ref type} \Arg{language} \Arg{seq variable}
 %   \end{syntax}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_get_ref_opt_font:nN #1#2
+\cs_new_protected:Npn \@@_get_rf_opt_seq:nnnN #1#2#3#4
   {
     % First attempt: general options.
-    \prop_get:NnNF \l_@@_ref_options_prop {#1} #2
+    \@@_opt_seq_get:cNF
+      { \@@_opt_varname_general:nn {#1} { seq } }
+      #4
       {
         % If not found, try type specific options.
-        \bool_if:nTF
+        \@@_opt_seq_get:cNF
+          { \@@_opt_varname_type:nnn {#2} {#1} { seq } }
+          #4
           {
-            \prop_if_exist_p:c
+            % If not found, try type- and language-specific.
+            \@@_opt_seq_get:cNF
+              { \@@_opt_varname_lang_type:nnnn {#3} {#2} {#1} { seq } }
+              #4
               {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
+                % If not found, try language-specific default.
+                \@@_opt_seq_get:cNF
+                  { \@@_opt_varname_lang_default:nnn {#3} {#1} { seq } }
+                  #4
+                  {
+                    % If not found, try fallback.
+                    \@@_opt_seq_get:cNF
+                      { \@@_opt_varname_fallback:nn {#1} { seq } }
+                      #4
+                      { \seq_clear:N #4 }
+                  }
               }
           }
-          {
-            \prop_get:cnNF
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-              {#1} #2
-              { \tl_clear:N #2 }
-          }
-          { \tl_clear:N #2 }
       }
   }
+\cs_generate_variant:Nn \@@_get_rf_opt_seq:nnnN { nxxN }
 %    \end{macrocode}
 % \end{macro}
 %
 %
-% \begin{macro}{\@@_get_ref_opt_bool:nnN}
+% \begin{macro}{\@@_get_rf_opt_bool:nnnnN}
 %   \begin{syntax}
-%     \cs{@@_get_ref_opt_bool:nN} \Arg{option}
-%     ~~\Arg{default} \Arg{bool variable}
+%     \cs{@@_get_rf_opt_bool:nN} \Arg{option} \Arg{default}
+%     ~~\Arg{ref type} \Arg{language}  \Arg{bool variable}
 %   \end{syntax}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_get_ref_opt_bool:nnN #1#2#3
+\cs_new_protected:Npn \@@_get_rf_opt_bool:nnnnN #1#2#3#4#5
   {
     % First attempt: general options.
-    \prop_get:NnNF \l_@@_ref_options_prop {#1} \l_tmpa_tl
+    \@@_opt_bool_get:cNF
+      { \@@_opt_varname_general:nn {#1} { bool } }
+      #5
       {
         % If not found, try type specific options.
-        \bool_lazy_and:nnTF
+        \@@_opt_bool_get:cNF
+          { \@@_opt_varname_type:nnn {#3} {#1} { bool } }
+          #5
           {
-            \prop_if_exist_p:c
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-          }
-          {
-            \prop_if_in_p:cn
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-              {#1}
-          }
-          {
-            \prop_get:cnN
-              {
-                l_@@_type_
-                \l_@@_label_type_a_tl _options_prop
-              }
-              {#1} \l_tmpa_tl
-          }
-          {
             % If not found, try type- and language-specific.
-            \@@_get_lang_opt_type:xxnNF
-              { \l_@@_ref_language_tl }
-              { \l_@@_label_type_a_tl }
-              {#1} \l_tmpa_tl
+            \@@_opt_bool_get:cNF
+              { \@@_opt_varname_lang_type:nnnn {#4} {#3} {#1} { bool } }
+              #5
               {
                 % If not found, try language-specific default.
-                \@@_get_lang_opt_default:xnNF
-                  { \l_@@_ref_language_tl }
-                  {#1} \l_tmpa_tl
+                \@@_opt_bool_get:cNF
+                  { \@@_opt_varname_lang_default:nnn {#4} {#1} { bool } }
+                  #5
                   {
-                    % If not found, use default argument.
-                    \bool_lazy_or:nnTF
-                      { \str_if_eq_p:nn {#2} { true  } }
-                      { \str_if_eq_p:nn {#2} { false } }
-                      { \tl_set:Nn \l_tmpa_tl {#2} }
-                      {
-                        % And, if even that fails, presume false.
-                        \tl_set:Nn \l_tmpa_tl { false }
-                      }
+                    % If not found, try fallback.
+                    \@@_opt_bool_get:cNF
+                      { \@@_opt_varname_fallback:nn {#1} { bool } }
+                      #5
+                      { \use:c { bool_set_ #2 :N } #5 }
                   }
               }
           }
       }
-    % Having retrieved the option value, set the boolean.  At this point, we
-    % *know* '\l_tmpa_tl' is either 'true' or 'false'.
-    \use:c { bool_set_ \l_tmpa_tl :N } #3
   }
+\cs_generate_variant:Nn \@@_get_rf_opt_bool:nnnnN { nnxxN }
 %    \end{macrocode}
 % \end{macro}
 %
 %
+%
 % \section{Compatibility}
 %
 % This section is meant to aggregate any ``special handling'' needed for
@@ -5796,11 +6778,7 @@
 % references \cs{textup}.
 %    \begin{macrocode}
         \zcRefTypeSetup { equation }
-          {
-            reffont = \upshape ,
-            preref  = {\textup{(}} ,
-            postref = {\textup{)}} ,
-          }
+          { reffont = \upshape }
         \msg_info:nnn { zref-clever } { compat-package } { amsmath }
       }
   }
@@ -6091,7 +7069,7 @@
 %
 % \section{Language files}
 %
-% Initial values for the English, German, French, Portuguese, and Spanish,
+% Initial values for the English, German, French, Portuguese, and Spanish
 % language files have been provided by the author.  Translations available for
 % document elements' names in other packages have been an useful reference for
 % the purpose, namely: \pkg{babel}, \pkg{cleveref}, \pkg{translator}, and
@@ -6232,8 +7210,8 @@
   name-sg-ab = eq. ,
   Name-pl-ab = Eqs. ,
   name-pl-ab = eqs. ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   Name-sg = Theorem ,
@@ -6586,8 +7564,8 @@
   case = G ,
     Name-sg = Gleichung ,
     Name-pl = Gleichungen ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = n ,
@@ -6931,8 +7909,8 @@
   name-sg = équation ,
   Name-pl = Équations ,
   name-pl = équations ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,
@@ -7180,8 +8158,8 @@
   name-sg-ab = eq. ,
   Name-pl-ab = Eqs. ,
   name-pl-ab = eqs. ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,
@@ -7411,8 +8389,8 @@
   name-sg = ecuación ,
   Name-pl = Ecuaciones ,
   name-pl = ecuaciones ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,
@@ -7648,8 +8626,8 @@
   name-sg-ab = vgl. ,
   Name-pl-ab = Vgl.'s ,
   name-pl-ab = vgl.'s ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = f ,
@@ -7657,12 +8635,11 @@
   name-sg = stelling ,
   Name-pl = Stellingen ,
   name-pl = stellingen ,
+
 %    \end{macrocode}
-%
 % 2022-01-09, \texttt{niluxv}: An alternative plural is ``lemmata''.  That is
 % also a correct English plural for lemma, but the English language file
 % chooses ``lemmas''.  For consistency we therefore choose ``lemma's''.
-%
 %    \begin{macrocode}
 type = lemma ,
   gender = n ,
@@ -7726,11 +8703,10 @@
   name-sg = algoritme ,
   Name-pl = Algoritmes ,
   name-pl = algoritmes ,
+
 %    \end{macrocode}
-%
 % 2022-01-09, \texttt{niluxv}: EN-NL Van Dale translates listing as (3)
 % ``uitdraai van computerprogramma'', ``listing''.
-%
 %    \begin{macrocode}
 type = listing ,
   gender = m ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-dutch.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-dutch.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-dutch.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -161,8 +161,8 @@
   name-sg-ab = vgl. ,
   Name-pl-ab = Vgl.'s ,
   name-pl-ab = vgl.'s ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = f ,
@@ -170,6 +170,7 @@
   name-sg = stelling ,
   Name-pl = Stellingen ,
   name-pl = stellingen ,
+
 type = lemma ,
   gender = n ,
   Name-sg = Lemma ,
@@ -232,6 +233,7 @@
   name-sg = algoritme ,
   Name-pl = Algoritmes ,
   name-pl = algoritmes ,
+
 type = listing ,
   gender = m ,
   Name-sg = Listing ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-english.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -154,8 +154,8 @@
   name-sg-ab = eq. ,
   Name-pl-ab = Eqs. ,
   name-pl-ab = eqs. ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   Name-sg = Theorem ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-french.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -157,8 +157,8 @@
   name-sg = équation ,
   Name-pl = Équations ,
   name-pl = équations ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-german.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -285,8 +285,8 @@
   case = G ,
     Name-sg = Gleichung ,
     Name-pl = Gleichungen ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = n ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-portuguese.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -169,8 +169,8 @@
   name-sg-ab = eq. ,
   Name-pl-ab = Eqs. ,
   name-pl-ab = eqs. ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.lang
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.lang	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever-spanish.lang	2022-01-28 22:24:51 UTC (rev 61778)
@@ -157,8 +157,8 @@
   name-sg = ecuación ,
   Name-pl = Ecuaciones ,
   name-pl = ecuaciones ,
-  preref  = {(} ,
-  postref = {)} ,
+  refbounds-first-sg = {,(,),} ,
+  refbounds = {(,,,)} ,
 
 type = theorem ,
   gender = m ,

Modified: trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty	2022-01-28 22:24:34 UTC (rev 61777)
+++ trunk/Master/texmf-dist/tex/latex/zref-clever/zref-clever.sty	2022-01-28 22:24:51 UTC (rev 61778)
@@ -53,7 +53,7 @@
       }%
     \endinput
   }%
-\ProvidesExplPackage {zref-clever} {2022-01-10} {0.1.2-alpha}
+\ProvidesExplPackage {zref-clever} {2022-01-28} {0.2.0-alpha}
   {Clever LaTeX cross-references based on zref}
 \RequirePackage { zref-base }
 \RequirePackage { zref-user }
@@ -109,7 +109,7 @@
   {
     \bool_if:nTF
       { \prop_if_in_p:Nn \l__zrefclever_counter_resetby_prop {#1} }
-      { \prop_item:Nn  \l__zrefclever_counter_resetby_prop {#1} }
+      { \prop_item:Nn \l__zrefclever_counter_resetby_prop {#1} }
       {
         \seq_map_tokens:Nn \l__zrefclever_counter_resetters_seq
           { \__zrefclever_counter_reset_by_aux:nn {#1} }
@@ -165,11 +165,6 @@
   }
 \msg_new:nnn { zref-clever } { key-requires-value }
   { The~'#1'~key~'#2'~requires~a~value~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { key-boolean-or-empty }
-  {
-    The~key~'#1'~only~accepts~the~values~'true',~'false'~
-    or~an~empty~value~\msg_line_context:.
-  }
 \msg_new:nnn { zref-clever } { language-declared }
   { Language~'#1'~is~already~declared~\msg_line_context:.~Nothing~to~do. }
 \msg_new:nnn { zref-clever } { unknown-language-alias }
@@ -186,7 +181,7 @@
   }
 \msg_new:nnn { zref-clever } { unknown-language-opt }
   {
-    Language~'#1'~is~unknown~\msg_line_context:.~Using~default.~
+    Language~'#1'~is~unknown~\msg_line_context:.~
     See~documentation~for~'\iow_char:N\\zcDeclareLanguage'~and~
     '\iow_char:N\\zcDeclareLanguageAlias'.
   }
@@ -249,15 +244,6 @@
   { Option~'#1'~is~only~available~after~\iow_char:N\\begin\{document\}. }
 \msg_new:nnn { zref-clever } { langfile-loaded }
   { Loaded~'#1'~language~file. }
-\msg_new:nnn { zref-clever } { langfile-not-available }
-  { Language~file~for~'#1'~not~available~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { unknown-language-load }
-  {
-    Language~'#1'~is~unknown~\msg_line_context:.~
-    Unable~to~load~language~file.~See~documentation~for~
-    '\iow_char:N\\zcDeclareLanguage'~and~
-    '\iow_char:N\\zcDeclareLanguageAlias'.
-  }
 \msg_new:nnn { zref-clever } { zref-property-undefined }
   {
     Option~'ref=#1'~requested~\msg_line_context:.~
@@ -283,6 +269,12 @@
     Unknown~compatibility~module~'#1'~given~to~option~'nocompat'.~
     Nothing~to~do.
   }
+\msg_new:nnn { zref-clever } { refbounds-must-be-four }
+  {
+    The~value~of~option~'#1'~must~be~a~comma~sepatared~list~
+    of~four~items.~We~received~'#2'~items~\msg_line_context:.~
+    Option~not~set.
+  }
 \msg_new:nnn { zref-clever } { missing-zref-check }
   {
     Option~'check'~requested~\msg_line_context:.~
@@ -294,11 +286,6 @@
   { Reference~property~'#1'~undefined~for~label~'#2'~\msg_line_context:. }
 \msg_new:nnn { zref-clever } { missing-name }
   { Reference~format~option~'#1'~undefined~for~type~'#2'~\msg_line_context:. }
-\msg_new:nnn { zref-clever } { missing-string }
-  {
-    We~couldn't~find~a~value~for~reference~option~'#1'~\msg_line_context:.~
-    But~we~should~have:~throw~a~rock~at~the~maintainer.
-  }
 \msg_new:nnn { zref-clever } { single-element-range }
   { Range~for~type~'#1'~resulted~in~single~element~\msg_line_context:. }
 \msg_new:nnn { zref-clever } { compat-package }
@@ -324,13 +311,139 @@
 \cs_generate_variant:Nn \__zrefclever_extract_unexp:nnn { Vnn , nvn , Vvn }
 \cs_new:Npn \__zrefclever_extract:nnn #1#2#3
   { \zref at extractdefault {#1} {#2} {#3} }
+\cs_new:Npn \__zrefclever_opt_varname_general:nn #1#2
+  { l__zrefclever_opt_general_ #1 _ #2 }
+\cs_new:Npn \__zrefclever_opt_varname_type:nnn #1#2#3
+  { l__zrefclever_opt_type_ #1 _ #2 _ #3 }
+\cs_generate_variant:Nn \__zrefclever_opt_varname_type:nnn { enn , een }
+\cs_new:Npn \__zrefclever_opt_varname_language:nnn #1#2#3
+  {
+    \__zrefclever_language_if_declared:nTF {#1}
+      {
+        g__zrefclever_opt_language_
+        \tl_use:c { \__zrefclever_language_varname:n {#1} }
+        _ #2 _ #3
+      }
+      { g__zrefclever_opt_lang_unknown_ \int_rand:n { 1000000 } _ #3 }
+  }
+\cs_generate_variant:Nn \__zrefclever_opt_varname_language:nnn { enn }
+\cs_new:Npn \__zrefclever_opt_varname_lang_default:nnn #1#2#3
+  {
+    \__zrefclever_language_if_declared:nTF {#1}
+      {
+        g__zrefclever_opt_lang_
+        \tl_use:c { \__zrefclever_language_varname:n {#1} }
+        _default_ #2 _ #3
+      }
+      { g__zrefclever_opt_lang_unknown_ \int_rand:n { 1000000 } _ #3 }
+  }
+\cs_generate_variant:Nn \__zrefclever_opt_varname_lang_default:nnn { enn }
+\cs_new:Npn \__zrefclever_opt_varname_lang_type:nnnn #1#2#3#4
+  {
+    \__zrefclever_language_if_declared:nTF {#1}
+      {
+        g__zrefclever_opt_lang_
+        \tl_use:c { \__zrefclever_language_varname:n {#1} }
+        _type_ #2 _ #3 _ #4
+      }
+      { g__zrefclever_opt_lang_unknown_ \int_rand:n { 1000000 } _ #4 }
+  }
+\cs_generate_variant:Nn
+  \__zrefclever_opt_varname_lang_type:nnnn { eenn , eeen }
+\cs_new:Npn \__zrefclever_opt_varname_fallback:nn #1#2
+  { c__zrefclever_opt_fallback_ #1 _ #2 }
+\cs_new_protected:Npn \__zrefclever_opt_tl_unset:N #1
+  { \tl_set_eq:NN #1 \c_novalue_tl }
+\cs_new_protected:Npn \__zrefclever_opt_tl_gunset:N #1
+  { \tl_gset_eq:NN #1 \c_novalue_tl }
+\cs_generate_variant:Nn \__zrefclever_opt_tl_unset:N { c }
+\cs_generate_variant:Nn \__zrefclever_opt_tl_gunset:N { c }
+\prg_new_conditional:Npnn \__zrefclever_opt_tl_if_set:N #1 { F , TF }
+  {
+    \bool_lazy_and:nnTF
+      { \tl_if_exist_p:N #1 }
+      { ! \tl_if_novalue_p:n {#1} }
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+\cs_new_protected:Npn \__zrefclever_opt_tl_gset_if_new:Nn #1#2
+  {
+    \__zrefclever_opt_tl_if_set:NF #1
+      { \tl_gset:Nn #1 {#2} }
+  }
+\cs_generate_variant:Nn \__zrefclever_opt_tl_gset_if_new:Nn { cn }
+\prg_new_protected_conditional:Npnn \__zrefclever_opt_tl_get:NN #1#2 { F }
+  {
+    \__zrefclever_opt_tl_if_set:NTF #1
+      {
+        \tl_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_tl_get:NN { cN } { F }
+\cs_new_protected:Npn \__zrefclever_opt_seq_set_clist_split:Nn #1#2
+  { \seq_set_split:Nnn #1 { , } {#2} }
+\cs_new_protected:Npn \__zrefclever_opt_seq_gset_clist_split:Nn #1#2
+  { \seq_gset_split:Nnn #1 { , } {#2} }
+\cs_new_protected:Npn \__zrefclever_opt_seq_unset:N #1
+  { \cs_set_eq:NN #1 \scan_stop: }
+\cs_new_protected:Npn \__zrefclever_opt_seq_gunset:N #1
+  { \cs_gset_eq:NN #1 \scan_stop: }
+\cs_generate_variant:Nn \__zrefclever_opt_seq_unset:N { c }
+\cs_generate_variant:Nn \__zrefclever_opt_seq_gunset:N { c }
+\prg_new_conditional:Npnn \__zrefclever_opt_seq_if_set:N #1 { F , TF }
+  { \seq_if_exist:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_seq_if_set:N { c } { F , TF }
+\prg_new_protected_conditional:Npnn \__zrefclever_opt_seq_get:NN #1#2 { F }
+  {
+    \__zrefclever_opt_seq_if_set:NTF #1
+      {
+        \seq_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_seq_get:NN { cN } { F }
+\cs_new_protected:Npn \__zrefclever_opt_bool_unset:N #1
+  { \cs_set_eq:NN #1 \scan_stop: }
+\cs_new_protected:Npn \__zrefclever_opt_bool_gunset:N #1
+  { \cs_gset_eq:NN #1 \scan_stop: }
+\cs_generate_variant:Nn \__zrefclever_opt_bool_unset:N { c }
+\cs_generate_variant:Nn \__zrefclever_opt_bool_gunset:N { c }
+\prg_new_conditional:Npnn \__zrefclever_opt_bool_if_set:N #1 { F , TF }
+  { \bool_if_exist:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_bool_if_set:N { c } { F , TF }
+\prg_new_protected_conditional:Npnn \__zrefclever_opt_bool_get:NN #1#2 { F }
+  {
+    \__zrefclever_opt_bool_if_set:NTF #1
+      {
+        \bool_set_eq:NN #2 #1
+        \prg_return_true:
+      }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_bool_get:NN { cN } { F }
+\prg_new_conditional:Npnn \__zrefclever_opt_bool_if:N #1 { T , F , TF }
+  {
+    \__zrefclever_opt_bool_if_set:NTF #1
+      { \bool_if:NTF #1 { \prg_return_true: } { \prg_return_false: } }
+      { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_opt_bool_if:N { c } { T , F , TF }
 \tl_new:N \l__zrefclever_setup_type_tl
-\tl_new:N \l__zrefclever_base_language_tl
+\tl_new:N \l__zrefclever_setup_language_tl
 \tl_new:N \l__zrefclever_lang_decl_case_tl
 \seq_new:N \l__zrefclever_lang_declension_seq
 \seq_new:N \l__zrefclever_lang_gender_seq
 \seq_const_from_clist:Nn
-  \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+  \c__zrefclever_rf_opts_tl_not_type_specific_seq
   {
     tpairsep ,
     tlistsep ,
@@ -338,7 +451,7 @@
     notesep ,
   }
 \seq_const_from_clist:Nn
-  \c__zrefclever_ref_options_possibly_type_specific_seq
+  \c__zrefclever_rf_opts_tl_maybe_type_specific_seq
   {
     namesep ,
     pairsep ,
@@ -345,12 +458,32 @@
     listsep ,
     lastsep ,
     rangesep ,
-    preref ,
-    postref ,
+    namefont ,
+    reffont ,
   }
 \seq_const_from_clist:Nn
-  \c__zrefclever_ref_options_type_names_seq
+  \c__zrefclever_rf_opts_seq_refbounds_seq
   {
+    refbounds-first ,
+    refbounds-first-sg ,
+    refbounds-first-pb ,
+    refbounds-first-rb ,
+    refbounds-mid ,
+    refbounds-mid-rb ,
+    refbounds-mid-re ,
+    refbounds-last ,
+    refbounds-last-pe ,
+    refbounds-last-re ,
+  }
+\seq_const_from_clist:Nn
+  \c__zrefclever_rf_opts_bool_maybe_type_specific_seq
+  {
+    cap ,
+    abbrev ,
+  }
+\seq_const_from_clist:Nn
+  \c__zrefclever_rf_opts_tl_type_names_seq
+  {
     Name-sg ,
     name-sg ,
     Name-pl ,
@@ -360,39 +493,95 @@
     Name-pl-ab ,
     name-pl-ab ,
   }
-\seq_const_from_clist:Nn
-  \c__zrefclever_ref_options_font_seq
+\seq_new:N \c__zrefclever_rf_opts_tl_typesetup_seq
+\seq_gconcat:NNN \c__zrefclever_rf_opts_tl_typesetup_seq
+  \c__zrefclever_rf_opts_tl_maybe_type_specific_seq
+  \c__zrefclever_rf_opts_tl_type_names_seq
+\seq_new:N \c__zrefclever_rf_opts_tl_reference_seq
+\seq_gconcat:NNN \c__zrefclever_rf_opts_tl_reference_seq
+  \c__zrefclever_rf_opts_tl_not_type_specific_seq
+  \c__zrefclever_rf_opts_tl_maybe_type_specific_seq
+\clist_map_inline:nn
   {
-    namefont ,
-    reffont ,
+    reference ,
+    typesetup ,
+    langsetup ,
+    langfile ,
   }
-\seq_new:N \c__zrefclever_ref_options_typesetup_seq
-\seq_gconcat:NNN \c__zrefclever_ref_options_typesetup_seq
-  \c__zrefclever_ref_options_possibly_type_specific_seq
-  \c__zrefclever_ref_options_type_names_seq
-\seq_gconcat:NNN \c__zrefclever_ref_options_typesetup_seq
-  \c__zrefclever_ref_options_typesetup_seq
-  \c__zrefclever_ref_options_font_seq
-\seq_new:N \c__zrefclever_ref_options_reference_seq
-\seq_gconcat:NNN \c__zrefclever_ref_options_reference_seq
-  \c__zrefclever_ref_options_necessarily_not_type_specific_seq
-  \c__zrefclever_ref_options_possibly_type_specific_seq
-\seq_gconcat:NNN \c__zrefclever_ref_options_reference_seq
-  \c__zrefclever_ref_options_reference_seq
-  \c__zrefclever_ref_options_font_seq
-\prop_new:N \g__zrefclever_languages_prop
+  {
+    \keys_define:nn { zref-clever/ #1 }
+      {
+        +refbounds-first .meta:n =
+          {
+            refbounds-first = {##1} ,
+            refbounds-first-sg = {##1} ,
+            refbounds-first-pb = {##1} ,
+            refbounds-first-rb = {##1} ,
+          } ,
+        +refbounds-first .default:x = \c_novalue_tl ,
+        +refbounds-mid .meta:n =
+          {
+            refbounds-mid = {##1} ,
+            refbounds-mid-rb = {##1} ,
+            refbounds-mid-re = {##1} ,
+          } ,
+        +refbounds-mid .default:x = \c_novalue_tl ,
+        +refbounds-last .meta:n =
+          {
+            refbounds-last = {##1} ,
+            refbounds-last-pe = {##1} ,
+            refbounds-last-re = {##1} ,
+          } ,
+        +refbounds-last .default:x = \c_novalue_tl ,
+        +refbounds-rb .meta:n =
+          {
+            refbounds-first-rb = {##1} ,
+            refbounds-mid-rb = {##1} ,
+          } ,
+        +refbounds-rb .default:x = \c_novalue_tl ,
+        +refbounds-re .meta:n =
+          {
+            refbounds-mid-re = {##1} ,
+            refbounds-last-re = {##1} ,
+          } ,
+        +refbounds-re .default:x = \c_novalue_tl ,
+        +refbounds .meta:n =
+          {
+            +refbounds-first = {##1} ,
+            +refbounds-mid = {##1} ,
+            +refbounds-last = {##1} ,
+          } ,
+        +refbounds .default:x = \c_novalue_tl ,
+        refbounds .meta:n = { +refbounds = {##1} } ,
+        refbounds .default:x = \c_novalue_tl ,
+      }
+  }
+\cs_new:Npn \__zrefclever_language_varname:n #1
+  { g__zrefclever_declared_language_ #1 _tl }
+\cs_set_eq:NN \zrefclever_language_varname:n
+  \__zrefclever_language_varname:n
+\prg_new_conditional:Npnn \__zrefclever_language_if_declared:n #1 { T , F , TF }
+  {
+    \tl_if_exist:cTF { \__zrefclever_language_varname:n {#1} }
+     { \prg_return_true:  }
+     { \prg_return_false: }
+  }
+\prg_generate_conditional_variant:Nnn
+  \__zrefclever_language_if_declared:n { x } { T , F , TF }
+\prg_set_eq_conditional:NNn \zrefclever_language_if_declared:n
+  \__zrefclever_language_if_declared:n { TF }
 \NewDocumentCommand \zcDeclareLanguage { O { } m }
   {
     \group_begin:
     \tl_if_empty:nF {#2}
       {
-        \prop_if_in:NnTF \g__zrefclever_languages_prop {#2}
+        \__zrefclever_language_if_declared:nTF {#2}
           { \msg_warning:nnn { zref-clever } { language-declared } {#2} }
           {
-            \prop_gput:Nnn \g__zrefclever_languages_prop {#2} {#2}
-            \prop_new:c { g__zrefclever_lang_ #2 _prop }
-            \tl_set:Nn \l__zrefclever_base_language_tl {#2}
-            \keys_set:nn { zref-clever / declarelang } {#1}
+            \tl_new:c { \__zrefclever_language_varname:n {#2} }
+            \tl_gset:cn { \__zrefclever_language_varname:n {#2} } {#2}
+            \tl_set:Nn \l__zrefclever_setup_language_tl {#2}
+            \keys_set:nn { zref-clever/declarelang } {#1}
           }
       }
     \group_end:
@@ -402,56 +591,60 @@
   {
     \tl_if_empty:nF {#1}
       {
-        \prop_if_in:NnTF \g__zrefclever_languages_prop {#2}
+        \__zrefclever_language_if_declared:nTF {#2}
           {
-            \exp_args:NNnx
-              \prop_gput:Nnn \g__zrefclever_languages_prop {#1}
-                { \prop_item:Nn \g__zrefclever_languages_prop {#2} }
+            \tl_gset:cx { \__zrefclever_language_varname:n {#1} }
+              { \tl_use:c { \__zrefclever_language_varname:n {#2} } }
           }
           { \msg_warning:nnn { zref-clever } { unknown-language-alias } {#2} }
       }
   }
 \@onlypreamble \zcDeclareLanguageAlias
-\keys_define:nn { zref-clever / declarelang }
+\keys_define:nn { zref-clever/declarelang }
   {
     declension .code:n =
       {
-        \prop_gput:cnn
-          { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-          { declension } {#1}
+        \seq_gset_from_clist:cn
+          {
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_setup_language_tl } { declension } { seq }
+          }
+          {#1}
       } ,
     declension .value_required:n = true ,
     gender .code:n =
       {
-        \prop_gput:cnn
-          { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-          { gender } {#1}
+        \seq_gset_from_clist:cn
+          {
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_setup_language_tl } { gender } { seq }
+          }
+          {#1}
       } ,
     gender .value_required:n = true ,
-    allcaps .code:n =
+    allcaps .choices:nn =
+      { true , false }
       {
-        \prop_gput:cnn
-          { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-          { allcaps } { true }
+        \use:c { bool_gset_ \l_keys_choice_tl :c }
+          {
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_setup_language_tl } { allcaps } { bool }
+          }
       } ,
-    allcaps .value_forbidden:n = true ,
+    allcaps .default:n = true ,
   }
-\cs_new_protected:Npn \__zrefclever_process_language_options:
+\cs_new_protected:Npn \__zrefclever_process_language_settings:
   {
-    \exp_args:NNx \prop_get:NnNTF \g__zrefclever_languages_prop
+    \__zrefclever_language_if_declared:xTF
       { \l__zrefclever_ref_language_tl }
-      \l__zrefclever_base_language_tl
       {
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l__zrefclever_lang_declension_seq
+        \__zrefclever_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g__zrefclever_lang_
-                \l__zrefclever_base_language_tl _prop
-              }
-              { declension }
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_ref_language_tl } { declension } { seq }
           }
+          \l__zrefclever_lang_declension_seq
+          { \seq_clear:N \l__zrefclever_lang_declension_seq }
         \seq_if_empty:NTF \l__zrefclever_lang_declension_seq
           {
             \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
@@ -482,16 +675,13 @@
                   }
               }
           }
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l__zrefclever_lang_gender_seq
+        \__zrefclever_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g__zrefclever_lang_
-                \l__zrefclever_base_language_tl _prop
-              }
-              { gender }
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_ref_language_tl } { gender } { seq }
           }
+          \l__zrefclever_lang_gender_seq
+          { \seq_clear:N \l__zrefclever_lang_gender_seq }
         \seq_if_empty:NTF \l__zrefclever_lang_gender_seq
           {
             \tl_if_empty:NF \l__zrefclever_ref_gender_tl
@@ -518,17 +708,12 @@
                   }
               }
           }
-        \str_if_eq:eeT
+        \__zrefclever_opt_bool_if:cT
           {
-            \prop_item:cn
-              {
-                g__zrefclever_lang_
-                \l__zrefclever_base_language_tl _prop
-              }
-              { allcaps }
+            \__zrefclever_opt_varname_language:enn
+              { \l__zrefclever_ref_language_tl } { allcaps } { bool }
           }
-          { true }
-          { \prop_put:Nnn \l__zrefclever_ref_options_prop { cap } { true } }
+          { \keys_set:nn { zref-clever/reference } { cap = true } }
       }
       {
         \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
@@ -550,34 +735,34 @@
       }
   }
 \seq_new:N \g__zrefclever_loaded_langfiles_seq
-\bool_new:N \l__zrefclever_load_langfile_verbose_bool
 \cs_new_protected:Npn \__zrefclever_provide_langfile:n #1
   {
     \group_begin:
     \@bsphack
-    \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
-      \l__zrefclever_base_language_tl
+    \__zrefclever_language_if_declared:nT {#1}
       {
-        \seq_if_in:NVF
+        \seq_if_in:NxF
           \g__zrefclever_loaded_langfiles_seq
-          \l__zrefclever_base_language_tl
+          { \tl_use:c { \__zrefclever_language_varname:n {#1} } }
           {
             \exp_args:Nx \file_get:nnNTF
-              { zref-clever- \l__zrefclever_base_language_tl .lang }
+              {
+                zref-clever-
+                \tl_use:c { \__zrefclever_language_varname:n {#1} }
+                .lang
+              }
               { \ExplSyntaxOn }
               \l_tmpa_tl
               {
+                \tl_set:Nn \l__zrefclever_setup_language_tl {#1}
                 \tl_clear:N \l__zrefclever_setup_type_tl
-                \exp_args:NNx \seq_set_from_clist:Nn
-                  \l__zrefclever_lang_declension_seq
+                \__zrefclever_opt_seq_get:cNF
                   {
-                    \prop_item:cn
-                      {
-                        g__zrefclever_lang_
-                        \l__zrefclever_base_language_tl _prop
-                      }
-                      { declension }
+                    \__zrefclever_opt_varname_language:nnn
+                      {#1} { declension } { seq }
                   }
+                  \l__zrefclever_lang_declension_seq
+                  { \seq_clear:N \l__zrefclever_lang_declension_seq }
                 \seq_if_empty:NTF \l__zrefclever_lang_declension_seq
                   { \tl_clear:N \l__zrefclever_lang_decl_case_tl }
                   {
@@ -584,65 +769,31 @@
                     \seq_get_left:NN \l__zrefclever_lang_declension_seq
                       \l__zrefclever_lang_decl_case_tl
                   }
-                \exp_args:NNx \seq_set_from_clist:Nn
-                  \l__zrefclever_lang_gender_seq
+                \__zrefclever_opt_seq_get:cNF
                   {
-                    \prop_item:cn
-                      {
-                        g__zrefclever_lang_
-                        \l__zrefclever_base_language_tl _prop
-                      }
-                      { gender }
+                    \__zrefclever_opt_varname_language:nnn
+                      {#1} { gender } { seq }
                   }
-                \keys_set:nV { zref-clever / langfile } \l_tmpa_tl
-                \seq_gput_right:NV \g__zrefclever_loaded_langfiles_seq
-                  \l__zrefclever_base_language_tl
-                \msg_note:nnx { zref-clever } { langfile-loaded }
-                  { \l__zrefclever_base_language_tl }
+                  \l__zrefclever_lang_gender_seq
+                  { \seq_clear:N \l__zrefclever_lang_gender_seq }
+                \keys_set:nV { zref-clever/langfile } \l_tmpa_tl
+                \seq_gput_right:Nx \g__zrefclever_loaded_langfiles_seq
+                  { \tl_use:c { \__zrefclever_language_varname:n {#1} } }
+                \msg_info:nnx { zref-clever } { langfile-loaded }
+                  { \tl_use:c { \__zrefclever_language_varname:n {#1} } }
               }
               {
-                \bool_if:NT \l__zrefclever_load_langfile_verbose_bool
-                  {
-                    \msg_warning:nnx { zref-clever } { langfile-not-available }
-                      { \l__zrefclever_base_language_tl }
-                  }
-                \seq_gput_right:NV \g__zrefclever_loaded_langfiles_seq
-                  \l__zrefclever_base_language_tl
+                \seq_gput_right:Nx \g__zrefclever_loaded_langfiles_seq
+                  { \tl_use:c { \__zrefclever_language_varname:n {#1} } }
               }
           }
       }
-      {
-        \bool_if:NT \l__zrefclever_load_langfile_verbose_bool
-          { \msg_warning:nnn { zref-clever } { unknown-language-load } {#1} }
-      }
     \@esphack
     \group_end:
   }
 \cs_generate_variant:Nn \__zrefclever_provide_langfile:n { x }
-\cs_new_protected:Npn \__zrefclever_provide_langfile_verbose:n #1
+\keys_define:nn { zref-clever/langfile }
   {
-    \group_begin:
-    \bool_set_true:N \l__zrefclever_load_langfile_verbose_bool
-    \__zrefclever_provide_langfile:n {#1}
-    \group_end:
-  }
-\cs_generate_variant:Nn \__zrefclever_provide_langfile_verbose:n { x }
-\cs_new_protected:Npn \__zrefclever_provide_lang_opt_type:nn #1#2
-  {
-    \exp_args:Nnx \prop_gput_if_new:cnn
-      { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-      { type- \l__zrefclever_setup_type_tl - #1 } {#2}
-  }
-\cs_generate_variant:Nn \__zrefclever_provide_lang_opt_type:nn { nV }
-\cs_new_protected:Npn \__zrefclever_provide_lang_opt_default:nn #1#2
-  {
-    \prop_gput_if_new:cnn
-      { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-      { default- #1 } {#2}
-  }
-\cs_generate_variant:Nn \__zrefclever_provide_lang_opt_default:nn { nV }
-\keys_define:nn { zref-clever / langfile }
-  {
     type .code:n =
       {
         \tl_if_empty:nTF {#1}
@@ -655,7 +806,7 @@
         \seq_if_empty:NTF \l__zrefclever_lang_declension_seq
           {
             \msg_info:nnxx { zref-clever } { language-no-decl-setup }
-              { \l__zrefclever_base_language_tl } {#1}
+              { \l__zrefclever_setup_language_tl } {#1}
           }
           {
             \seq_if_in:NnTF \l__zrefclever_lang_declension_seq {#1}
@@ -662,7 +813,7 @@
               { \tl_set:Nn \l__zrefclever_lang_decl_case_tl {#1} }
               {
                 \msg_info:nnxx { zref-clever } { unknown-decl-case }
-                  {#1} { \l__zrefclever_base_language_tl }
+                  {#1} { \l__zrefclever_setup_language_tl }
                 \seq_get_left:NN \l__zrefclever_lang_declension_seq
                   \l__zrefclever_lang_decl_case_tl
               }
@@ -670,12 +821,13 @@
       } ,
     case .value_required:n = true ,
 
+    gender .default:x = \c_novalue_tl ,
     gender .code:n =
       {
         \seq_if_empty:NTF \l__zrefclever_lang_gender_seq
           {
             \msg_info:nnxxx { zref-clever } { language-no-gender }
-              { \l__zrefclever_base_language_tl } { gender } {#1}
+              { \l__zrefclever_setup_language_tl } { gender } {#1}
           }
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
@@ -684,72 +836,65 @@
                   { option-only-type-specific } { gender }
               }
               {
-                \clist_clear:N \l_tmpa_clist
-                \clist_map_inline:nn {#1}
+                \tl_if_novalue:nF {#1}
                   {
-                    \seq_if_in:NnTF \l__zrefclever_lang_gender_seq {##1}
-                      { \clist_put_right:Nn \l_tmpa_clist {##1} }
+                    \seq_clear:N \l_tmpa_seq
+                    \clist_map_inline:nn {#1}
                       {
-                        \msg_info:nnxx { zref-clever }
-                          { gender-not-declared }
-                          { \l__zrefclever_base_language_tl } {##1}
+                        \seq_if_in:NnTF \l__zrefclever_lang_gender_seq {##1}
+                          { \seq_put_right:Nn \l_tmpa_seq {##1} }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { gender-not-declared }
+                              { \l__zrefclever_setup_language_tl } {##1}
+                          }
                       }
+                    \__zrefclever_opt_seq_if_set:cF
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          { gender }
+                          { seq }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \__zrefclever_opt_varname_lang_type:eenn
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl }
+                              { gender }
+                              { seq }
+                          }
+                          \l_tmpa_seq
+                      }
                   }
-                \clist_if_empty:NF \l_tmpa_clist
-                  {
-                    \exp_args:Nnx \__zrefclever_provide_lang_opt_type:nn
-                      { gender } { \clist_use:Nn \l_tmpa_clist { , } }
-                  }
               }
           }
       } ,
-    gender .value_required:n = true ,
-
-    cap .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-          {
-            \__zrefclever_provide_lang_opt_default:nV
-              { cap } \l_keys_choice_tl
-          }
-          {
-            \__zrefclever_provide_lang_opt_type:nV
-              { cap } \l_keys_choice_tl
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-          {
-            \__zrefclever_provide_lang_opt_default:nV
-              { abbrev } \l_keys_choice_tl
-          }
-          {
-            \__zrefclever_provide_lang_opt_type:nV
-              { abbrev } \l_keys_choice_tl
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+  \c__zrefclever_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-              { \__zrefclever_provide_lang_opt_default:nn {#1} {##1} }
               {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \__zrefclever_opt_tl_gset_if_new:cn
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
+              {
                 \msg_info:nnn { zref-clever }
                   { option-not-type-specific } {#1}
               }
@@ -757,25 +902,48 @@
       }
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_possibly_type_specific_seq
+  \c__zrefclever_rf_opts_tl_maybe_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-              { \__zrefclever_provide_lang_opt_default:nn {#1} {##1} }
-              { \__zrefclever_provide_lang_opt_type:nn {#1} {##1} }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \__zrefclever_opt_tl_gset_if_new:cn
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \__zrefclever_opt_tl_gset_if_new:cn
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
+              }
           } ,
       }
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_type_names_seq
+  \c__zrefclever_rf_opts_tl_type_names_seq
   {
-    \keys_define:nn { zref-clever / langfile }
+    \keys_define:nn { zref-clever/langfile }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
@@ -785,18 +953,217 @@
               }
               {
                 \tl_if_empty:NTF \l__zrefclever_lang_decl_case_tl
-                  { \__zrefclever_provide_lang_opt_type:nn {#1} {##1} }
                   {
-                    \__zrefclever_provide_lang_opt_type:nn
-                      { \l__zrefclever_lang_decl_case_tl - #1 } {##1}
+                    \tl_if_novalue:nF {##1}
+                      {
+                        \__zrefclever_opt_tl_gset_if_new:cn
+                          {
+                            \__zrefclever_opt_varname_lang_type:eenn
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl }
+                              {#1} { tl }
+                          }
+                          {##1}
+                      }
                   }
+                  {
+                    \tl_if_novalue:nF {##1}
+                      {
+                        \__zrefclever_opt_tl_gset_if_new:cn
+                          {
+                            \__zrefclever_opt_varname_lang_type:eeen
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl }
+                              { \l__zrefclever_lang_decl_case_tl - #1 } { tl }
+                          }
+                          {##1}
+                      }
+                  }
               }
           } ,
       }
   }
-\prop_new:N \g__zrefclever_fallback_unknown_lang_prop
-\prop_gset_from_keyval:Nn \g__zrefclever_fallback_unknown_lang_prop
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_seq_refbounds_seq
   {
+    \keys_define:nn { zref-clever/langfile }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \__zrefclever_opt_seq_if_set:cF
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl } {#1} { seq }
+                      }
+                      {
+                        \seq_gclear:N \g_tmpa_seq
+                        \__zrefclever_opt_seq_gset_clist_split:Nn
+                          \g_tmpa_seq {##1}
+                        \bool_lazy_or:nnTF
+                          { \tl_if_empty_p:n {##1} }
+                          {
+                            \int_compare_p:nNn
+                              { \seq_count:N \g_tmpa_seq } = { 4 }
+                          }
+                          {
+                            \seq_gset_eq:cN
+                              {
+                                \__zrefclever_opt_varname_lang_default:enn
+                                  { \l__zrefclever_setup_language_tl }
+                                  {#1} { seq }
+                              }
+                              \g_tmpa_seq
+                          }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { refbounds-must-be-four }
+                              {#1} { \seq_count:N \g_tmpa_seq }
+                          }
+                      }
+                  }
+              }
+              {
+                \tl_if_novalue:nF {##1}
+                  {
+                    \__zrefclever_opt_seq_if_set:cF
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl } {#1} { seq }
+                      }
+                      {
+                        \seq_gclear:N \g_tmpa_seq
+                        \__zrefclever_opt_seq_gset_clist_split:Nn
+                          \g_tmpa_seq {##1}
+                        \bool_lazy_or:nnTF
+                          { \tl_if_empty_p:n {##1} }
+                          {
+                            \int_compare_p:nNn
+                              { \seq_count:N \g_tmpa_seq } = { 4 }
+                          }
+                          {
+                            \seq_gset_eq:cN
+                              {
+                                \__zrefclever_opt_varname_lang_type:eenn
+                                  { \l__zrefclever_setup_language_tl }
+                                  { \l__zrefclever_setup_type_tl }
+                                  {#1} { seq }
+                              }
+                              \g_tmpa_seq
+                          }
+                          {
+                            \msg_info:nnxx { zref-clever }
+                              { refbounds-must-be-four }
+                              {#1} { \seq_count:N \g_tmpa_seq }
+                          }
+                      }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/langfile }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \__zrefclever_opt_bool_if_set:cF
+                  {
+                    \__zrefclever_opt_varname_lang_default:enn
+                      { \l__zrefclever_setup_language_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_true:c
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+              {
+                \__zrefclever_opt_bool_if_set:cF
+                  {
+                    \__zrefclever_opt_varname_lang_type:eenn
+                      { \l__zrefclever_setup_language_tl }
+                      { \l__zrefclever_setup_type_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_true:c
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \__zrefclever_opt_bool_if_set:cF
+                  {
+                    \__zrefclever_opt_varname_lang_default:enn
+                      { \l__zrefclever_setup_language_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_false:c
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+              {
+                \__zrefclever_opt_bool_if_set:cF
+                  {
+                    \__zrefclever_opt_varname_lang_type:eenn
+                      { \l__zrefclever_setup_language_tl }
+                      { \l__zrefclever_setup_type_tl }
+                      {#1} { bool }
+                  }
+                  {
+                    \bool_gset_false:c
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { bool }
+                      }
+                  }
+              }
+          } ,
+        #1 / unset .code:n = { } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
+\cs_new_protected:Npn \__zrefclever_opt_tl_cset_fallback:nn #1#2
+  {
+    \tl_const:cn
+      { \__zrefclever_opt_varname_fallback:nn {#1} { tl } } {#2}
+  }
+\keyval_parse:nnn
+  { }
+  { \__zrefclever_opt_tl_cset_fallback:nn }
+  {
     tpairsep  = {,~} ,
     tlistsep  = {,~} ,
     tlastsep  = {,~} ,
@@ -806,49 +1173,7 @@
     listsep   = {,~} ,
     lastsep   = {,~} ,
     rangesep  = {\textendash} ,
-    preref    = {} ,
-    postref   = {} ,
   }
-\prg_new_protected_conditional:Npnn
-  \__zrefclever_get_lang_opt_type:nnnN #1#2#3#4 { F }
-  {
-    \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
-      \l__zrefclever_base_language_tl
-      {
-        \prop_get:cnNTF
-          { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-          { type- #2 - #3 } #4
-          { \prg_return_true:  }
-          { \prg_return_false: }
-      }
-      { \prg_return_false: }
-  }
-\prg_generate_conditional_variant:Nnn
-  \__zrefclever_get_lang_opt_type:nnnN { xxxN , xxnN } { F }
-\prg_new_protected_conditional:Npnn
-  \__zrefclever_get_lang_opt_default:nnN #1#2#3 { F }
-  {
-    \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
-      \l__zrefclever_base_language_tl
-      {
-        \prop_get:cnNTF
-          { g__zrefclever_lang_ \l__zrefclever_base_language_tl _prop }
-          { default- #2 } #3
-          { \prg_return_true:  }
-          { \prg_return_false: }
-      }
-      { \prg_return_false: }
-  }
-\prg_generate_conditional_variant:Nnn
-  \__zrefclever_get_lang_opt_default:nnN { xnN } { F }
-\prg_new_protected_conditional:Npnn
-  \__zrefclever_get_fallback_unknown_lang_opt:nN #1#2 { F }
-  {
-    \prop_get:NnNTF \g__zrefclever_fallback_unknown_lang_prop
-      { #1 } #2
-      { \prg_return_true:  }
-      { \prg_return_false: }
-  }
 \cs_new_protected:Npn \__zrefclever_prop_put_non_empty:Nnn #1#2#3
   {
     \tl_if_empty:nTF {#3}
@@ -856,7 +1181,7 @@
       { \prop_put:Nnn #1 {#2} {#3} }
   }
 \tl_new:N \l__zrefclever_ref_property_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     ref .code:n =
       {
@@ -874,7 +1199,7 @@
   }
 \bool_new:N \l__zrefclever_typeset_ref_bool
 \bool_new:N \l__zrefclever_typeset_name_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     typeset .choice: ,
     typeset / both .code:n =
@@ -901,7 +1226,7 @@
     noref .value_forbidden:n = true ,
   }
 \bool_new:N \l__zrefclever_typeset_sort_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     sort .bool_set:N = \l__zrefclever_typeset_sort_bool ,
     sort .initial:n = true ,
@@ -910,7 +1235,7 @@
     nosort .value_forbidden:n = true ,
   }
 \seq_new:N \l__zrefclever_typesort_seq
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     typesort .code:n =
       {
@@ -925,7 +1250,7 @@
     notypesort .value_forbidden:n = true ,
   }
 \bool_new:N \l__zrefclever_typeset_compress_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     comp .bool_set:N = \l__zrefclever_typeset_compress_bool ,
     comp .initial:n = true ,
@@ -934,113 +1259,79 @@
     nocomp .value_forbidden:n = true ,
   }
 \bool_new:N \l__zrefclever_typeset_range_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     range .bool_set:N = \l__zrefclever_typeset_range_bool ,
     range .initial:n = false ,
     range .default:n = true ,
   }
-\bool_new:N \l__zrefclever_capitalize_first_bool
-\keys_define:nn { zref-clever / reference }
+\bool_new:N \l__zrefclever_capfirst_bool
+\keys_define:nn { zref-clever/reference }
   {
-    cap .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          { \prop_remove:Nn \l__zrefclever_ref_options_prop { cap } }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              { \prop_put:Nnn \l__zrefclever_ref_options_prop { cap } {#1} }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    capfirst .bool_set:N = \l__zrefclever_capitalize_first_bool ,
+    capfirst .bool_set:N = \l__zrefclever_capfirst_bool ,
     capfirst .initial:n = false ,
     capfirst .default:n = true ,
   }
 \bool_new:N \l__zrefclever_noabbrev_first_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
-    abbrev .code:n =
-      {
-        \tl_if_empty:nTF {#1}
-          { \prop_remove:Nn \l__zrefclever_ref_options_prop { abbrev } }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              { \prop_put:Nnn \l__zrefclever_ref_options_prop { abbrev } {#1} }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
-
     noabbrevfirst .bool_set:N = \l__zrefclever_noabbrev_first_bool ,
     noabbrevfirst .initial:n = false ,
     noabbrevfirst .default:n = true ,
   }
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     S .meta:n =
-      { capfirst = true , noabbrevfirst = true },
-    S .value_forbidden:n = true ,
+      { capfirst = {#1} , noabbrevfirst = {#1} },
+    S .default:n = true ,
   }
-\bool_new:N \l__zrefclever_use_hyperref_bool
-\bool_new:N \l__zrefclever_warn_hyperref_bool
-\keys_define:nn { zref-clever / reference }
+\bool_new:N \l__zrefclever_hyperlink_bool
+\bool_new:N \l__zrefclever_hyperref_warn_bool
+\keys_define:nn { zref-clever/reference }
   {
     hyperref .choice: ,
     hyperref / auto .code:n =
       {
-        \bool_set_true:N \l__zrefclever_use_hyperref_bool
-        \bool_set_false:N \l__zrefclever_warn_hyperref_bool
+        \bool_set_true:N \l__zrefclever_hyperlink_bool
+        \bool_set_false:N \l__zrefclever_hyperref_warn_bool
       } ,
     hyperref / true .code:n =
       {
-        \bool_set_true:N \l__zrefclever_use_hyperref_bool
-        \bool_set_true:N \l__zrefclever_warn_hyperref_bool
+        \bool_set_true:N \l__zrefclever_hyperlink_bool
+        \bool_set_true:N \l__zrefclever_hyperref_warn_bool
       } ,
     hyperref / false .code:n =
       {
-        \bool_set_false:N \l__zrefclever_use_hyperref_bool
-        \bool_set_false:N \l__zrefclever_warn_hyperref_bool
+        \bool_set_false:N \l__zrefclever_hyperlink_bool
+        \bool_set_false:N \l__zrefclever_hyperref_warn_bool
       } ,
     hyperref .initial:n = auto ,
-    hyperref .default:n = auto
+    hyperref .default:n = true ,
+    nohyperref .meta:n = { hyperref = false } ,
+    nohyperref .value_forbidden:n = true ,
   }
 \AddToHook { begindocument }
   {
     \__zrefclever_if_package_loaded:nTF { hyperref }
       {
-        \bool_if:NT \l__zrefclever_use_hyperref_bool
+        \bool_if:NT \l__zrefclever_hyperlink_bool
           { \RequirePackage { zref-hyperref } }
       }
       {
-        \bool_if:NT \l__zrefclever_warn_hyperref_bool
+        \bool_if:NT \l__zrefclever_hyperref_warn_bool
           { \msg_warning:nn { zref-clever } { missing-hyperref } }
-        \bool_set_false:N \l__zrefclever_use_hyperref_bool
+        \bool_set_false:N \l__zrefclever_hyperlink_bool
       }
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         hyperref .code:n =
-          { \msg_warning:nn { zref-clever } { hyperref-preamble-only } }
+          { \msg_warning:nn { zref-clever } { hyperref-preamble-only } } ,
+        nohyperref .code:n =
+          { \bool_set_false:N \l__zrefclever_hyperlink_bool } ,
       }
   }
 \str_new:N \l__zrefclever_nameinlink_str
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nameinlink .choice: ,
     nameinlink / true .code:n =
@@ -1054,12 +1345,14 @@
     nameinlink .initial:n = tsingle ,
     nameinlink .default:n = true ,
   }
-\bool_new:N \l__zrefclever_preposinlink_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
-    preposinlink .bool_set:N =  \l__zrefclever_preposinlink_bool ,
-    preposinlink .initial:n = false ,
-    preposinlink .default:n = true ,
+    preposinlink .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-12 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preposinlink } { refbounds }
+      } ,
   }
 
 \tl_new:N \l__zrefclever_ref_language_tl
@@ -1083,10 +1376,9 @@
             \tl_set:Nn \l__zrefclever_main_language_tl { english }
           }
       }
-    \tl_set:Nn \l__zrefclever_ref_language_tl
-      { \l__zrefclever_current_language_tl }
   }
-\keys_define:nn { zref-clever / reference }
+\tl_set:Nn  \l_zrefclever_ref_language_tl { \l__zrefclever_ref_language_tl }
+\keys_define:nn { zref-clever/reference }
   {
     lang .code:n =
       {
@@ -1098,8 +1390,6 @@
                 {
                   \tl_set:Nn \l__zrefclever_ref_language_tl
                     { \l__zrefclever_current_language_tl }
-                  \__zrefclever_provide_langfile_verbose:x
-                    { \l__zrefclever_ref_language_tl }
                 }
 
                 { main }
@@ -1106,24 +1396,21 @@
                 {
                   \tl_set:Nn \l__zrefclever_ref_language_tl
                     { \l__zrefclever_main_language_tl }
-                  \__zrefclever_provide_langfile_verbose:x
-                    { \l__zrefclever_ref_language_tl }
                 }
               }
               {
-                \prop_if_in:NnTF \g__zrefclever_languages_prop {#1}
-                  { \tl_set:Nn \l__zrefclever_ref_language_tl {#1} }
+                \tl_set:Nn \l__zrefclever_ref_language_tl {#1}
+                \__zrefclever_language_if_declared:nF {#1}
                   {
                     \msg_warning:nnn { zref-clever }
                       { unknown-language-opt } {#1}
-                    \tl_set:Nn \l__zrefclever_ref_language_tl
-                      { \l__zrefclever_current_language_tl }
                   }
-                \__zrefclever_provide_langfile_verbose:x
-                  { \l__zrefclever_ref_language_tl }
               }
+            \__zrefclever_provide_langfile:x
+              { \l__zrefclever_ref_language_tl }
           }
       } ,
+    lang .initial:n = current ,
     lang .value_required:n = true ,
   }
 \AddToHook { begindocument / before }
@@ -1130,8 +1417,7 @@
   {
     \AddToHook { begindocument }
       {
-        \__zrefclever_provide_langfile:x { \l__zrefclever_ref_language_tl }
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             lang .code:n =
               {
@@ -1141,8 +1427,6 @@
                     {
                       \tl_set:Nn \l__zrefclever_ref_language_tl
                         { \l__zrefclever_current_language_tl }
-                      \__zrefclever_provide_langfile:x
-                        { \l__zrefclever_ref_language_tl }
                     }
 
                     { main }
@@ -1149,29 +1433,22 @@
                     {
                       \tl_set:Nn \l__zrefclever_ref_language_tl
                         { \l__zrefclever_main_language_tl }
-                      \__zrefclever_provide_langfile:x
-                        { \l__zrefclever_ref_language_tl }
                     }
                   }
                   {
-                    \prop_if_in:NnTF \g__zrefclever_languages_prop {#1}
-                      { \tl_set:Nn \l__zrefclever_ref_language_tl {#1} }
+                    \tl_set:Nn \l__zrefclever_ref_language_tl {#1}
+                    \__zrefclever_language_if_declared:nF {#1}
                       {
                         \msg_warning:nnn { zref-clever }
                           { unknown-language-opt } {#1}
-                        \tl_set:Nn \l__zrefclever_ref_language_tl
-                          { \l__zrefclever_current_language_tl }
                       }
-                    \__zrefclever_provide_langfile:x
-                      { \l__zrefclever_ref_language_tl }
                   }
               } ,
-            lang .value_required:n = true ,
           }
       }
   }
 \tl_new:N \l__zrefclever_ref_decl_case_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     d .code:n =
       { \msg_warning:nnn { zref-clever } { option-document-only } { d } } ,
@@ -1178,7 +1455,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         d .tl_set:N = \l__zrefclever_ref_decl_case_tl ,
         d .value_required:n = true ,
@@ -1190,7 +1467,7 @@
 \bool_new:N \l__zrefclever_nudge_singular_bool
 \bool_new:N \l__zrefclever_nudge_gender_bool
 \tl_new:N \l__zrefclever_ref_gender_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nudge .choice: ,
     nudge / true .code:n =
@@ -1251,7 +1528,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         g .tl_set:N = \l__zrefclever_ref_gender_tl ,
         g .value_required:n = true ,
@@ -1258,9 +1535,9 @@
       }
   }
 \tl_new:N \l__zrefclever_ref_typeset_font_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   { font .tl_set:N = \l__zrefclever_ref_typeset_font_tl }
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     titleref .code:n = { \RequirePackage { zref-titleref } } ,
     titleref .value_forbidden:n = true ,
@@ -1267,7 +1544,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         titleref .code:n =
           { \msg_warning:nn { zref-clever } { titleref-preamble-only } }
@@ -1274,7 +1551,7 @@
       }
   }
 \tl_new:N \l__zrefclever_zcref_note_tl
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     note .tl_set:N = \l__zrefclever_zcref_note_tl ,
     note .value_required:n = true ,
@@ -1281,7 +1558,7 @@
   }
 \bool_new:N \l__zrefclever_zrefcheck_available_bool
 \bool_new:N \l__zrefclever_zcref_with_check_bool
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     check .code:n = { \RequirePackage { zref-check } } ,
     check .value_forbidden:n = true ,
@@ -1291,7 +1568,7 @@
     \__zrefclever_if_package_loaded:nTF { zref-check }
       {
         \bool_set_true:N \l__zrefclever_zrefcheck_available_bool
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             check .code:n =
               {
@@ -1303,7 +1580,7 @@
       }
       {
         \bool_set_false:N \l__zrefclever_zrefcheck_available_bool
-        \keys_define:nn { zref-clever / reference }
+        \keys_define:nn { zref-clever/reference }
           {
             check .value_forbidden:n = false ,
             check .code:n =
@@ -1312,7 +1589,7 @@
       }
   }
 \prop_new:N \l__zrefclever_counter_type_prop
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     countertype .code:n =
       {
@@ -1341,7 +1618,7 @@
       } ,
   }
 \seq_new:N \l__zrefclever_counter_resetters_seq
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     counterresetters .code:n =
       {
@@ -1367,7 +1644,7 @@
     counterresetters .value_required:n = true ,
   }
 \prop_new:N \l__zrefclever_counter_resetby_prop
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     counterresetby .code:n =
       {
@@ -1391,7 +1668,7 @@
       } ,
   }
 \tl_new:N \l__zrefclever_current_counter_tl
-\keys_define:nn { zref-clever / label }
+\keys_define:nn { zref-clever/label }
   {
     currentcounter .tl_set:N = \l__zrefclever_current_counter_tl ,
     currentcounter .value_required:n = true ,
@@ -1399,7 +1676,7 @@
   }
 \bool_new:N \g__zrefclever_nocompat_bool
 \seq_new:N \g__zrefclever_nocompat_modules_seq
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     nocompat .code:n =
       {
@@ -1419,7 +1696,7 @@
   }
 \AddToHook { begindocument }
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
         nocompat .code:n =
           {
@@ -1445,129 +1722,137 @@
         \seq_gremove_all:Nn \g__zrefclever_nocompat_modules_seq {#1}
       }
   }
-\prop_new:N \l__zrefclever_ref_options_prop
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_reference_seq
+  \c__zrefclever_rf_opts_tl_reference_seq
   {
-    \keys_define:nn { zref-clever / reference }
+    \keys_define:nn { zref-clever/reference }
       {
-        #1 .default:V = \c_novalue_tl ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_novalue:nTF {##1}
-              { \prop_remove:Nn \l__zrefclever_ref_options_prop {#1} }
-              { \prop_put:Nnn \l__zrefclever_ref_options_prop {#1} {##1} }
+              {
+                \__zrefclever_opt_tl_unset:c
+                  { \__zrefclever_opt_varname_general:nn {#1} { tl } }
+              }
+              {
+                \tl_set:cn
+                  { \__zrefclever_opt_varname_general:nn {#1} { tl } }
+                  {##1}
+              }
           } ,
       }
   }
-\keys_define:nn { zref-clever / reference }
+\keys_define:nn { zref-clever/reference }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
-  }
-\keys_define:nn { }
-  {
-    zref-clever / zcsetup .inherit:n =
+    preref .code:n =
       {
-        zref-clever / label ,
-        zref-clever / reference ,
-      }
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
-\ProcessKeysOptions { zref-clever / zcsetup }
-\NewDocumentCommand \zcsetup { m }
-  { \__zrefclever_zcsetup:n {#1} }
-\cs_new_protected:Npn \__zrefclever_zcsetup:n #1
-  { \keys_set:nn { zref-clever / zcsetup } {#1} }
-\cs_generate_variant:Nn \__zrefclever_zcsetup:n { x }
-\NewDocumentCommand \zcRefTypeSetup { m m }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_seq_refbounds_seq
   {
-    \prop_if_exist:cF { l__zrefclever_type_ #1 _options_prop }
-      { \prop_new:c { l__zrefclever_type_ #1 _options_prop } }
-    \tl_set:Nn \l__zrefclever_setup_type_tl {#1}
-    \keys_set:nn { zref-clever / typesetup } {#2}
-  }
-\keys_define:nn { zref-clever / typesetup }
-  {
-    cap .code:n =
+    \keys_define:nn { zref-clever/reference }
       {
-        \tl_if_empty:nTF {#1}
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
           {
-            \prop_remove:cn
+            \tl_if_novalue:nTF {##1}
               {
-                l__zrefclever_type_
-                \l__zrefclever_setup_type_tl _options_prop
+                \__zrefclever_opt_seq_unset:c
+                  { \__zrefclever_opt_varname_general:nn {#1} { seq } }
               }
-              { cap }
-          }
-          {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
               {
-                \prop_put:cnn
+                \seq_clear:N \l_tmpa_seq
+                \__zrefclever_opt_seq_set_clist_split:Nn
+                  \l_tmpa_seq {##1}
+                \bool_lazy_or:nnTF
+                  { \tl_if_empty_p:n {##1} }
+                  { \int_compare_p:nNn { \seq_count:N \l_tmpa_seq } = { 4 } }
                   {
-                    l__zrefclever_type_
-                    \l__zrefclever_setup_type_tl _options_prop
+                    \seq_set_eq:cN
+                      { \__zrefclever_opt_varname_general:nn {#1} { seq } }
+                      \l_tmpa_seq
                   }
-                  { cap } {#1}
+                  {
+                    \msg_warning:nnxx { zref-clever }
+                      { refbounds-must-be-four }
+                      {#1} { \seq_count:N \l_tmpa_seq }
+                  }
               }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .code:n =
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/reference }
       {
-        \tl_if_empty:nTF {#1}
+        #1 .choice: ,
+        #1 / true .code:n =
           {
-            \prop_remove:cn
-              {
-                l__zrefclever_type_
-                \l__zrefclever_setup_type_tl _options_prop
-              }
-              { abbrev }
-          }
+            \bool_set_true:c
+              { \__zrefclever_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 / false .code:n =
           {
-            \bool_lazy_or:nnTF
-              { \str_if_eq_p:nn {#1} { true  } }
-              { \str_if_eq_p:nn {#1} { false } }
-              {
-                \prop_put:cnn
-                  {
-                    l__zrefclever_type_
-                    \l__zrefclever_setup_type_tl _options_prop
-                  }
-                  { abbrev } {#1}
-              }
-              {
-                \msg_warning:nnn { zref-clever }
-                  { key-boolean-or-empty } {#1}
-              }
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
+            \bool_set_false:c
+              { \__zrefclever_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 / unset .code:n =
+          {
+            \__zrefclever_opt_bool_unset:c
+              { \__zrefclever_opt_varname_general:nn {#1} { bool } }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
   }
+\keys_define:nn { }
+  {
+    zref-clever/zcsetup .inherit:n =
+      {
+        zref-clever/label ,
+        zref-clever/reference ,
+      }
+  }
+\ProcessKeysOptions { zref-clever/zcsetup }
+\NewDocumentCommand \zcsetup { m }
+  { \__zrefclever_zcsetup:n {#1} }
+\cs_new_protected:Npn \__zrefclever_zcsetup:n #1
+  { \keys_set:nn { zref-clever/zcsetup } {#1} }
+\cs_generate_variant:Nn \__zrefclever_zcsetup:n { x }
+\NewDocumentCommand \zcRefTypeSetup { m m }
+  {
+    \tl_set:Nn \l__zrefclever_setup_type_tl {#1}
+    \keys_set:nn { zref-clever/typesetup } {#2}
+  }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+  \c__zrefclever_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / typesetup }
+    \keys_define:nn { zref-clever/typesetup }
       {
         #1 .code:n =
           {
@@ -1577,65 +1862,151 @@
       }
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_typesetup_seq
+  \c__zrefclever_rf_opts_tl_typesetup_seq
   {
-    \keys_define:nn { zref-clever / typesetup }
+    \keys_define:nn { zref-clever/typesetup }
       {
-        #1 .default:V = \c_novalue_tl ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_novalue:nTF {##1}
               {
-                \prop_remove:cn
+                \__zrefclever_opt_tl_unset:c
                   {
-                    l__zrefclever_type_
-                    \l__zrefclever_setup_type_tl _options_prop
+                    \__zrefclever_opt_varname_type:enn
+                      { \l__zrefclever_setup_type_tl } {#1} { tl }
                   }
-                  {#1}
               }
               {
-                \prop_put:cnn
+                \tl_set:cn
                   {
-                    l__zrefclever_type_
-                    \l__zrefclever_setup_type_tl _options_prop
+                    \__zrefclever_opt_varname_type:enn
+                      { \l__zrefclever_setup_type_tl } {#1} { tl }
                   }
-                  {#1} {##1}
+                  {##1}
               }
           } ,
       }
   }
-\keys_define:nn { zref-clever / typesetup }
+\keys_define:nn { zref-clever/typesetup }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
+    preref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/typesetup }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_novalue:nTF {##1}
+              {
+                \__zrefclever_opt_seq_unset:c
+                  {
+                    \__zrefclever_opt_varname_type:enn
+                      { \l__zrefclever_setup_type_tl } {#1} { seq }
+                  }
+              }
+              {
+                \seq_clear:N \l_tmpa_seq
+                \__zrefclever_opt_seq_set_clist_split:Nn
+                  \l_tmpa_seq {##1}
+                \bool_lazy_or:nnTF
+                  { \tl_if_empty_p:n {##1} }
+                  { \int_compare_p:nNn { \seq_count:N \l_tmpa_seq } = { 4 } }
+                  {
+                    \seq_set_eq:cN
+                      {
+                        \__zrefclever_opt_varname_type:enn
+                          { \l__zrefclever_setup_type_tl } {#1} { seq }
+                      }
+                      \l_tmpa_seq
+                  }
+                  {
+                    \msg_warning:nnxx { zref-clever }
+                      { refbounds-must-be-four }
+                      {#1} { \seq_count:N \l_tmpa_seq }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/typesetup }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \bool_set_true:c
+              {
+                \__zrefclever_opt_varname_type:enn
+                  { \l__zrefclever_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \bool_set_false:c
+              {
+                \__zrefclever_opt_varname_type:enn
+                  { \l__zrefclever_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 / unset .code:n =
+          {
+            \__zrefclever_opt_bool_unset:c
+              {
+                \__zrefclever_opt_varname_type:enn
+                  { \l__zrefclever_setup_type_tl }
+                  {#1} { bool }
+              }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 \NewDocumentCommand \zcLanguageSetup { m m }
   {
     \group_begin:
-    \prop_get:NnNTF \g__zrefclever_languages_prop {#1}
-      \l__zrefclever_base_language_tl
+    \__zrefclever_language_if_declared:nTF {#1}
       {
         \tl_clear:N \l__zrefclever_setup_type_tl
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l__zrefclever_lang_declension_seq
+        \tl_set:Nn \l__zrefclever_setup_language_tl {#1}
+        \__zrefclever_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g__zrefclever_lang_
-                \l__zrefclever_base_language_tl _prop
-              }
-              { declension }
+            \__zrefclever_opt_varname_language:nnn
+              {#1} { declension } { seq }
           }
+          \l__zrefclever_lang_declension_seq
+          { \seq_clear:N \l__zrefclever_lang_declension_seq }
         \seq_if_empty:NTF \l__zrefclever_lang_declension_seq
           { \tl_clear:N \l__zrefclever_lang_decl_case_tl }
           {
@@ -1642,37 +2013,21 @@
             \seq_get_left:NN \l__zrefclever_lang_declension_seq
               \l__zrefclever_lang_decl_case_tl
           }
-        \exp_args:NNx \seq_set_from_clist:Nn
-          \l__zrefclever_lang_gender_seq
+        \__zrefclever_opt_seq_get:cNF
           {
-            \prop_item:cn
-              {
-                g__zrefclever_lang_
-                \l__zrefclever_base_language_tl _prop
-              }
-              { gender }
+            \__zrefclever_opt_varname_language:nnn
+              {#1} { gender } { seq }
           }
-        \keys_set:nn { zref-clever / langsetup } {#2}
+          \l__zrefclever_lang_gender_seq
+          { \seq_clear:N \l__zrefclever_lang_gender_seq }
+        \keys_set:nn { zref-clever/langsetup } {#2}
       }
       { \msg_warning:nnn { zref-clever } { unknown-language-setup } {#1} }
     \group_end:
   }
 \@onlypreamble \zcLanguageSetup
-\cs_new_protected:Npn \__zrefclever_declare_lang_opt_type:nnnn #1#2#3#4
+\keys_define:nn { zref-clever/langsetup }
   {
-    \prop_gput:cnn { g__zrefclever_lang_ #1 _prop }
-      { type- #2 - #3 } {#4}
-  }
-\cs_generate_variant:Nn
-  \__zrefclever_declare_lang_opt_type:nnnn { VVnn , VVxn , VVnx , VVnV }
-\cs_new_protected:Npn \__zrefclever_declare_lang_opt_default:nnn #1#2#3
-  {
-    \prop_gput:cnn { g__zrefclever_lang_ #1 _prop }
-      { default- #2 } {#3}
-  }
-\cs_generate_variant:Nn \__zrefclever_declare_lang_opt_default:nnn { Vnn , VnV }
-\keys_define:nn { zref-clever / langsetup }
-  {
     type .code:n =
       {
         \tl_if_empty:nTF {#1}
@@ -1685,7 +2040,7 @@
         \seq_if_empty:NTF \l__zrefclever_lang_declension_seq
           {
             \msg_warning:nnxx { zref-clever } { language-no-decl-setup }
-              { \l__zrefclever_base_language_tl } {#1}
+              { \l__zrefclever_setup_language_tl } {#1}
           }
           {
             \seq_if_in:NnTF \l__zrefclever_lang_declension_seq {#1}
@@ -1692,7 +2047,7 @@
               { \tl_set:Nn \l__zrefclever_lang_decl_case_tl {#1} }
               {
                 \msg_warning:nnxx { zref-clever } { unknown-decl-case }
-                  {#1} { \l__zrefclever_base_language_tl }
+                  {#1} { \l__zrefclever_setup_language_tl }
                 \seq_get_left:NN \l__zrefclever_lang_declension_seq
                   \l__zrefclever_lang_decl_case_tl
               }
@@ -1700,12 +2055,13 @@
       } ,
     case .value_required:n = true ,
 
+    gender .default:x = \c_novalue_tl ,
     gender .code:n =
       {
         \seq_if_empty:NTF \l__zrefclever_lang_gender_seq
           {
             \msg_warning:nnxxx { zref-clever } { language-no-gender }
-              { \l__zrefclever_base_language_tl } { gender } {#1}
+              { \l__zrefclever_setup_language_tl } { gender } {#1}
           }
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
@@ -1714,82 +2070,69 @@
                   { option-only-type-specific } { gender }
               }
               {
-                \clist_clear:N \l_tmpa_clist
-                \clist_map_inline:nn {#1}
+                \tl_if_novalue:nTF {#1}
                   {
-                    \seq_if_in:NnTF \l__zrefclever_lang_gender_seq {##1}
-                      { \clist_put_right:Nn \l_tmpa_clist {##1} }
+                    \__zrefclever_opt_seq_gunset:c
                       {
-                        \msg_warning:nnxx { zref-clever }
-                          { gender-not-declared }
-                          { \l__zrefclever_base_language_tl } {##1}
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          { gender }
+                          { seq }
                       }
                   }
-                \clist_if_empty:NF \l_tmpa_clist
                   {
-                    \__zrefclever_declare_lang_opt_type:VVnx
-                      \l__zrefclever_base_language_tl
-                      \l__zrefclever_setup_type_tl
-                      { gender } { \clist_use:Nn \l_tmpa_clist { , } }
+                    \seq_clear:N \l_tmpa_seq
+                    \clist_map_inline:nn {#1}
+                      {
+                        \seq_if_in:NnTF \l__zrefclever_lang_gender_seq {##1}
+                          { \seq_put_right:Nn \l_tmpa_seq {##1} }
+                          {
+                            \msg_warning:nnxx { zref-clever }
+                              { gender-not-declared }
+                              { \l__zrefclever_setup_language_tl } {##1}
+                          }
+                      }
+                    \seq_gset_eq:cN
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          { gender }
+                          { seq }
+                      }
+                      \l_tmpa_seq
                   }
               }
           }
       } ,
-    gender .value_required:n = true ,
-
-    cap .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-          {
-            \__zrefclever_declare_lang_opt_default:VnV
-              \l__zrefclever_base_language_tl
-              { cap } \l_keys_choice_tl
-          }
-          {
-            \__zrefclever_declare_lang_opt_type:VVnV
-              \l__zrefclever_base_language_tl
-              \l__zrefclever_setup_type_tl
-              { cap } \l_keys_choice_tl
-          }
-      } ,
-    cap .default:n = true ,
-    nocap .meta:n = { cap = false } ,
-    nocap .value_forbidden:n = true ,
-
-    abbrev .choices:nn =
-      { true , false }
-      {
-        \tl_if_empty:NTF \l__zrefclever_setup_type_tl
-          {
-            \__zrefclever_declare_lang_opt_default:VnV
-              \l__zrefclever_base_language_tl
-              { abbrev } \l_keys_choice_tl
-          }
-          {
-            \__zrefclever_declare_lang_opt_type:VVnV
-              \l__zrefclever_base_language_tl
-              \l__zrefclever_setup_type_tl
-              { abbrev } \l_keys_choice_tl
-          }
-      } ,
-    abbrev .default:n = true ,
-    noabbrev .meta:n = { abbrev = false },
-    noabbrev .value_forbidden:n = true ,
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_necessarily_not_type_specific_seq
+  \c__zrefclever_rf_opts_tl_not_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
-        #1 .value_required:n = true ,
+        #1 .default:x = \c_novalue_tl ,
         #1 .code:n =
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
               {
-                \__zrefclever_declare_lang_opt_default:Vnn
-                  \l__zrefclever_base_language_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \__zrefclever_opt_tl_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl } {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl } {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
               {
                 \msg_warning:nnn { zref-clever }
@@ -1799,9 +2142,9 @@
       }
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_possibly_type_specific_seq
+  \c__zrefclever_rf_opts_tl_maybe_type_specific_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
         #1 .value_required:n = true ,
         #1 .code:n =
@@ -1808,38 +2151,79 @@
           {
             \tl_if_empty:NTF \l__zrefclever_setup_type_tl
               {
-                \__zrefclever_declare_lang_opt_default:Vnn
-                  \l__zrefclever_base_language_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \__zrefclever_opt_tl_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl } {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl } {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
               {
-                \__zrefclever_declare_lang_opt_type:VVnn
-                  \l__zrefclever_base_language_tl
-                  \l__zrefclever_setup_type_tl
-                  {#1} {##1}
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \__zrefclever_opt_tl_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { tl }
+                      }
+                  }
+                  {
+                    \tl_gset:cn
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { tl }
+                      }
+                      {##1}
+                  }
               }
           } ,
       }
   }
-\keys_define:nn { zref-clever / langsetup }
+\keys_define:nn { zref-clever/langsetup }
   {
     refpre .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpre } { preref }
+          { refpre } { refbounds }
       } ,
     refpos .code:n =
       {
         % NOTE Option deprecated in 2022-01-10 for v0.1.2-alpha.
         \msg_warning:nnnn { zref-clever }{ option-deprecated }
-          { refpos } { postref }
+          { refpos } { refbounds }
       } ,
+    preref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { preref } { refbounds }
+      } ,
+    postref .code:n =
+      {
+        % NOTE Option deprecated in 2022-01-14 for v0.2.0-alpha.
+        \msg_warning:nnnn { zref-clever }{ option-deprecated }
+          { postref } { refbounds }
+      } ,
   }
 \seq_map_inline:Nn
-  \c__zrefclever_ref_options_type_names_seq
+  \c__zrefclever_rf_opts_tl_type_names_seq
   {
-    \keys_define:nn { zref-clever / langsetup }
+    \keys_define:nn { zref-clever/langsetup }
       {
         #1 .value_required:n = true ,
         #1 .code:n =
@@ -1850,33 +2234,212 @@
                   { option-only-type-specific } {#1}
               }
               {
-                \tl_if_empty:NTF \l__zrefclever_lang_decl_case_tl
+                \tl_if_novalue:nTF {##1}
                   {
-                    \__zrefclever_declare_lang_opt_type:VVnn
-                      \l__zrefclever_base_language_tl
-                      \l__zrefclever_setup_type_tl
-                      {#1} {##1}
+                    \__zrefclever_opt_tl_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl }
+                          {#1} { tl }
+                      }
                   }
                   {
-                    \__zrefclever_declare_lang_opt_type:VVxn
-                      \l__zrefclever_base_language_tl
-                      \l__zrefclever_setup_type_tl
-                      { \l__zrefclever_lang_decl_case_tl - #1 } {##1}
+                    \tl_if_empty:NTF \l__zrefclever_lang_decl_case_tl
+                      {
+                        \tl_gset:cn
+                          {
+                            \__zrefclever_opt_varname_lang_type:eenn
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl }
+                              {#1} { tl }
+                          }
+                          {##1}
+                      }
+                      {
+                        \tl_gset:cn
+                          {
+                            \__zrefclever_opt_varname_lang_type:eeen
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl }
+                              { \l__zrefclever_lang_decl_case_tl - #1 }
+                              { tl }
+                          }
+                          {##1}
+                      }
                   }
               }
           } ,
       }
   }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_seq_refbounds_seq
+  {
+    \keys_define:nn { zref-clever/langsetup }
+      {
+        #1 .default:x = \c_novalue_tl ,
+        #1 .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \__zrefclever_opt_seq_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_default:enn
+                          { \l__zrefclever_setup_language_tl }
+                          {#1} { seq }
+                      }
+                  }
+                  {
+                    \seq_gclear:N \g_tmpa_seq
+                    \__zrefclever_opt_seq_gset_clist_split:Nn
+                      \g_tmpa_seq {##1}
+                    \bool_lazy_or:nnTF
+                      { \tl_if_empty_p:n {##1} }
+                      {
+                        \int_compare_p:nNn
+                          { \seq_count:N \g_tmpa_seq } = { 4 }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \__zrefclever_opt_varname_lang_default:enn
+                              { \l__zrefclever_setup_language_tl }
+                              {#1} { seq }
+                          }
+                          \g_tmpa_seq
+                      }
+                      {
+                        \msg_warning:nnxx { zref-clever }
+                          { refbounds-must-be-four }
+                          {#1} { \seq_count:N \g_tmpa_seq }
+                      }
+                  }
+              }
+              {
+                \tl_if_novalue:nTF {##1}
+                  {
+                    \__zrefclever_opt_seq_gunset:c
+                      {
+                        \__zrefclever_opt_varname_lang_type:eenn
+                          { \l__zrefclever_setup_language_tl }
+                          { \l__zrefclever_setup_type_tl } {#1} { seq }
+                      }
+                  }
+                  {
+                    \seq_gclear:N \g_tmpa_seq
+                    \__zrefclever_opt_seq_gset_clist_split:Nn
+                      \g_tmpa_seq {##1}
+                    \bool_lazy_or:nnTF
+                      { \tl_if_empty_p:n {##1} }
+                      {
+                        \int_compare_p:nNn
+                          { \seq_count:N \g_tmpa_seq } = { 4 }
+                      }
+                      {
+                        \seq_gset_eq:cN
+                          {
+                            \__zrefclever_opt_varname_lang_type:eenn
+                              { \l__zrefclever_setup_language_tl }
+                              { \l__zrefclever_setup_type_tl } {#1} { seq }
+                          }
+                          \g_tmpa_seq
+                      }
+                      {
+                        \msg_warning:nnxx { zref-clever }
+                          { refbounds-must-be-four }
+                          {#1} { \seq_count:N \g_tmpa_seq }
+                      }
+                  }
+              }
+          } ,
+      }
+  }
+\seq_map_inline:Nn
+  \c__zrefclever_rf_opts_bool_maybe_type_specific_seq
+  {
+    \keys_define:nn { zref-clever/langsetup }
+      {
+        #1 .choice: ,
+        #1 / true .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \bool_gset_true:c
+                  {
+                    \__zrefclever_opt_varname_lang_default:enn
+                      { \l__zrefclever_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \bool_gset_true:c
+                  {
+                    \__zrefclever_opt_varname_lang_type:eenn
+                      { \l__zrefclever_setup_language_tl }
+                      { \l__zrefclever_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 / false .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \bool_gset_false:c
+                  {
+                    \__zrefclever_opt_varname_lang_default:enn
+                      { \l__zrefclever_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \bool_gset_false:c
+                  {
+                    \__zrefclever_opt_varname_lang_type:eenn
+                      { \l__zrefclever_setup_language_tl }
+                      { \l__zrefclever_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 / unset .code:n =
+          {
+            \tl_if_empty:NTF \l__zrefclever_setup_type_tl
+              {
+                \__zrefclever_opt_bool_gunset:c
+                  {
+                    \__zrefclever_opt_varname_lang_default:enn
+                      { \l__zrefclever_setup_language_tl }
+                      {#1} { bool }
+                  }
+              }
+              {
+                \__zrefclever_opt_bool_gunset:c
+                  {
+                    \__zrefclever_opt_varname_lang_type:eenn
+                      { \l__zrefclever_setup_language_tl }
+                      { \l__zrefclever_setup_type_tl }
+                      {#1} { bool }
+                  }
+              }
+          } ,
+        #1 .default:n = true ,
+        no #1 .meta:n = { #1 = false } ,
+        no #1 .value_forbidden:n = true ,
+      }
+  }
 \NewDocumentCommand \zcref { s O { } m }
   { \zref at wrapper@babel \__zrefclever_zcref:nnn {#3} {#1} {#2} }
 \cs_new_protected:Npn \__zrefclever_zcref:nnn #1#2#3
   {
     \group_begin:
-      \keys_set:nn { zref-clever / reference } {#3}
+      \keys_set:nn { zref-clever/reference } {#3}
       \seq_set_from_clist:Nn \l__zrefclever_zcref_labels_seq {#1}
       \bool_set:Nn \l__zrefclever_link_star_bool {#2}
       \__zrefclever_provide_langfile:x { \l__zrefclever_ref_language_tl }
-      \__zrefclever_process_language_options:
+      \__zrefclever_process_language_settings:
       \bool_lazy_and:nnT
         { \l__zrefclever_zrefcheck_available_bool }
         { \l__zrefclever_zcref_with_check_bool }
@@ -1891,7 +2454,10 @@
       \group_end:
       \tl_if_empty:NF \l__zrefclever_zcref_note_tl
         {
-          \__zrefclever_get_ref_opt_typeset:nN { notesep } \l_tmpa_tl
+          \__zrefclever_get_rf_opt_tl:nxxN { notesep }
+            { \l__zrefclever_label_type_a_tl }
+            { \l__zrefclever_ref_language_tl }
+            \l_tmpa_tl
           \l_tmpa_tl
           \l__zrefclever_zcref_note_tl
         }
@@ -1914,9 +2480,11 @@
 \bool_new:N \l__zrefclever_link_star_bool
 \NewDocumentCommand \zcpageref { s O { } m }
   {
-    \IfBooleanTF {#1}
-      { \zcref*[#2, ref = page] {#3} }
-      { \zcref [#2, ref = page] {#3} }
+    \group_begin:
+    \IfBooleanT {#1}
+      { \bool_set_false:N \l__zrefclever_hyperlink_bool }
+    \zcref [#2, ref = page] {#3}
+    \group_end:
   }
 \tl_new:N \l__zrefclever_label_type_a_tl
 \tl_new:N \l__zrefclever_label_type_b_tl
@@ -1931,7 +2499,7 @@
 \cs_new_protected:Npn \__zrefclever_sort_labels:
   {
     \seq_clear:N \l__zrefclever_label_types_seq
-    \tl_if_eq:NnF \l__zrefclever_ref_property_tl { page }
+    \tl_if_eq:NnF \l__zrefclever_ref_propserty_tl { page }
       {
         \seq_map_function:NN \l__zrefclever_zcref_labels_seq
           \__zrefclever_label_type_put_new_right:n
@@ -1973,7 +2541,7 @@
 \cs_new_protected:Npn \__zrefclever_label_type_put_new_right:n #1
   {
     \__zrefclever_extract_default:Nnnn
-      \l__zrefclever_label_type_a_tl {#1} { zc at type } { \c_empty_tl }
+      \l__zrefclever_label_type_a_tl {#1} { zc at type } { }
     \seq_if_in:NVF \l__zrefclever_label_types_seq
       \l__zrefclever_label_type_a_tl
       {
@@ -1997,15 +2565,15 @@
 \cs_new_protected:Npn \__zrefclever_sort_default_same_type:nn #1#2
   {
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_enclval_a_tl
-      {#1} { zc at enclval } { \c_empty_tl }
+      {#1} { zc at enclval } { }
     \tl_reverse:N \l__zrefclever_label_enclval_a_tl
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_enclval_b_tl
-      {#2} { zc at enclval } { \c_empty_tl }
+      {#2} { zc at enclval } { }
     \tl_reverse:N \l__zrefclever_label_enclval_b_tl
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_extdoc_a_tl
-      {#1} { externaldocument } { \c_empty_tl }
+      {#1} { externaldocument } { }
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_extdoc_b_tl
-      {#2} { externaldocument } { \c_empty_tl }
+      {#2} { externaldocument } { }
 
     \bool_set_false:N \l__zrefclever_sort_decided_bool
 
@@ -2190,6 +2758,7 @@
 \bool_new:N \l__zrefclever_last_of_type_bool
 \int_new:N \l__zrefclever_type_count_int
 \int_new:N \l__zrefclever_label_count_int
+\int_new:N \l__zrefclever_ref_count_int
 \tl_new:N \l__zrefclever_label_a_tl
 \tl_new:N \l__zrefclever_label_b_tl
 \tl_new:N \l__zrefclever_typeset_queue_prev_tl
@@ -2198,9 +2767,10 @@
 \tl_new:N \l__zrefclever_type_first_label_type_tl
 \tl_new:N \l__zrefclever_type_name_tl
 \bool_new:N \l__zrefclever_name_in_link_bool
+\bool_new:N \l__zrefclever_type_name_missing_bool
 \tl_new:N \l__zrefclever_name_format_tl
 \tl_new:N \l__zrefclever_name_format_fallback_tl
-\tl_new:N \l__zrefclever_type_name_gender_tl
+\seq_new:N \l__zrefclever_type_name_gender_seq
 \int_new:N \l__zrefclever_range_count_int
 \int_new:N \l__zrefclever_range_same_count_int
 \tl_new:N \l__zrefclever_range_beg_label_tl
@@ -2214,12 +2784,22 @@
 \tl_new:N \l__zrefclever_listsep_tl
 \tl_new:N \l__zrefclever_lastsep_tl
 \tl_new:N \l__zrefclever_rangesep_tl
-\tl_new:N \l__zrefclever_preref_tl
-\tl_new:N \l__zrefclever_postref_tl
 \tl_new:N \l__zrefclever_namefont_tl
 \tl_new:N \l__zrefclever_reffont_tl
-\bool_new:N \l__zrefclever_capitalize_bool
+\bool_new:N \l__zrefclever_cap_bool
 \bool_new:N \l__zrefclever_abbrev_bool
+\seq_new:N \l__zrefclever_refbounds_first_seq
+\seq_new:N \l__zrefclever_refbounds_first_sg_seq
+\seq_new:N \l__zrefclever_refbounds_first_pb_seq
+\seq_new:N \l__zrefclever_refbounds_first_rb_seq
+\seq_new:N \l__zrefclever_refbounds_mid_seq
+\seq_new:N \l__zrefclever_refbounds_mid_rb_seq
+\seq_new:N \l__zrefclever_refbounds_mid_re_seq
+\seq_new:N \l__zrefclever_refbounds_last_seq
+\seq_new:N \l__zrefclever_refbounds_last_pe_seq
+\seq_new:N \l__zrefclever_refbounds_last_re_seq
+\seq_new:N \l__zrefclever_type_first_refbounds_seq
+\bool_new:N \l__zrefclever_type_first_refbounds_set_bool
 \bool_new:N \l__zrefclever_verbose_testing_bool
 \cs_new_protected:Npn \__zrefclever_typeset_refs:
   {
@@ -2232,15 +2812,23 @@
     \tl_clear:N \l__zrefclever_range_beg_label_tl
     \int_zero:N \l__zrefclever_label_count_int
     \int_zero:N \l__zrefclever_type_count_int
+    \int_zero:N \l__zrefclever_ref_count_int
     \int_zero:N \l__zrefclever_range_count_int
     \int_zero:N \l__zrefclever_range_same_count_int
+    \bool_set_false:N \l__zrefclever_type_first_refbounds_set_bool
 
     % Get type block options (not type-specific).
-    \__zrefclever_get_ref_opt_typeset:nN { tpairsep }
+    \__zrefclever_get_rf_opt_tl:nxxN { tpairsep }
+      { \l__zrefclever_label_type_a_tl }
+      { \l__zrefclever_ref_language_tl }
       \l__zrefclever_tpairsep_tl
-    \__zrefclever_get_ref_opt_typeset:nN { tlistsep }
+    \__zrefclever_get_rf_opt_tl:nxxN { tlistsep }
+      { \l__zrefclever_label_type_a_tl }
+      { \l__zrefclever_ref_language_tl }
       \l__zrefclever_tlistsep_tl
-    \__zrefclever_get_ref_opt_typeset:nN { tlastsep }
+    \__zrefclever_get_rf_opt_tl:nxxN { tlastsep }
+      { \l__zrefclever_label_type_a_tl }
+      { \l__zrefclever_ref_language_tl }
       \l__zrefclever_tlastsep_tl
 
     % Process label stack.
@@ -2323,32 +2911,86 @@
               }
           }
 
-        % Get type-specific separators, pre-/postref font and other options,
-        % once per type.
+        % Get possibly type-specific separators, refbounds, font and other
+        % options, once per type.
         \int_compare:nNnT { \l__zrefclever_label_count_int } = { 0 }
           {
-            \__zrefclever_get_ref_opt_typeset:nN { namesep  }
+            \__zrefclever_get_rf_opt_tl:nxxN { namesep }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_namesep_tl
-            \__zrefclever_get_ref_opt_typeset:nN { pairsep  }
+            \__zrefclever_get_rf_opt_tl:nxxN { pairsep }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_pairsep_tl
-            \__zrefclever_get_ref_opt_typeset:nN { listsep  }
+            \__zrefclever_get_rf_opt_tl:nxxN { listsep }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_listsep_tl
-            \__zrefclever_get_ref_opt_typeset:nN { lastsep  }
+            \__zrefclever_get_rf_opt_tl:nxxN { lastsep }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_lastsep_tl
-            \__zrefclever_get_ref_opt_typeset:nN { rangesep }
+            \__zrefclever_get_rf_opt_tl:nxxN { rangesep }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_rangesep_tl
-            \__zrefclever_get_ref_opt_typeset:nN { preref   }
-              \l__zrefclever_preref_tl
-            \__zrefclever_get_ref_opt_typeset:nN { postref  }
-              \l__zrefclever_postref_tl
-            \__zrefclever_get_ref_opt_font:nN { namefont }
+            \__zrefclever_get_rf_opt_tl:nxxN { namefont }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_namefont_tl
-            \__zrefclever_get_ref_opt_font:nN { reffont  }
+            \__zrefclever_get_rf_opt_tl:nxxN { reffont }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_reffont_tl
-            \__zrefclever_get_ref_opt_bool:nnN { cap    } { false }
-              \l__zrefclever_capitalize_bool
-            \__zrefclever_get_ref_opt_bool:nnN { abbrev } { false }
+            \__zrefclever_get_rf_opt_bool:nnxxN { cap } { false }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_cap_bool
+            \__zrefclever_get_rf_opt_bool:nnxxN { abbrev } { false }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
               \l__zrefclever_abbrev_bool
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-first }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_first_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-first-sg }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_first_sg_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-first-pb }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_first_pb_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-first-rb }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_first_rb_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-mid }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_mid_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-mid-rb }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_mid_rb_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-mid-re }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_mid_re_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-last }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_last_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-last-pe }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_last_pe_seq
+            \__zrefclever_get_rf_opt_seq:nxxN { refbounds-last-re }
+              { \l__zrefclever_label_type_a_tl }
+              { \l__zrefclever_ref_language_tl }
+              \l__zrefclever_refbounds_last_re_seq
           }
 
         % Here we send this to a couple of auxiliary functions.
@@ -2373,6 +3015,9 @@
             \l__zrefclever_label_a_tl
           \tl_set:NV \l__zrefclever_type_first_label_type_tl
             \l__zrefclever_label_type_a_tl
+          \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+            \l__zrefclever_refbounds_first_sg_seq
+          \bool_set_true:N \l__zrefclever_type_first_refbounds_set_bool
         }
 
         % The last is the second: we have a pair (if not repeated).
@@ -2379,13 +3024,22 @@
         % Test: 'zc-typeset01.lvt': "Last of type: pair"
         { 1 }
         {
-          \int_compare:nNnF { \l__zrefclever_range_same_count_int } = { 1 }
+          \int_compare:nNnTF { \l__zrefclever_range_same_count_int } = { 1 }
             {
+              \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                \l__zrefclever_refbounds_first_sg_seq
+              \bool_set_true:N \l__zrefclever_type_first_refbounds_set_bool
+            }
+            {
               \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                 {
                   \exp_not:V \l__zrefclever_pairsep_tl
-                  \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                  \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                    \l__zrefclever_refbounds_last_pe_seq
                 }
+              \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                \l__zrefclever_refbounds_first_pb_seq
+              \bool_set_true:N \l__zrefclever_type_first_refbounds_set_bool
             }
         }
       }
@@ -2398,28 +3052,56 @@
             % Test: 'zc-typeset01.lvt': "Last of type: not range"
             { 0 }
             {
-              \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+              \int_compare:nNnTF { \l__zrefclever_ref_count_int } < { 2 }
                 {
-                  \exp_not:V \l__zrefclever_lastsep_tl
-                  \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l__zrefclever_pairsep_tl
+                      \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                        \l__zrefclever_refbounds_last_pe_seq
+                    }
                 }
+                {
+                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l__zrefclever_lastsep_tl
+                      \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                        \l__zrefclever_refbounds_last_seq
+                    }
+                }
             }
             % Last in the range is also the second in it.
             % Test: 'zc-typeset01.lvt': "Last of type: pair in sequence"
             { 1 }
             {
-              \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+              \int_compare:nNnTF
+                { \l__zrefclever_range_same_count_int } = { 1 }
                 {
                   % We know `range_beg_label' is not empty, since this is the
                   % second element in the range, but the third or more in the
                   % type list.
-                  \exp_not:V \l__zrefclever_listsep_tl
-                  \__zrefclever_get_ref:V \l__zrefclever_range_beg_label_tl
-                  \int_compare:nNnF
-                    { \l__zrefclever_range_same_count_int } = { 1 }
+                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                     {
+                      \exp_not:V \l__zrefclever_pairsep_tl
+                      \__zrefclever_get_ref:VN
+                        \l__zrefclever_range_beg_label_tl
+                        \l__zrefclever_refbounds_last_pe_seq
+                    }
+                  \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                    \l__zrefclever_refbounds_first_pb_seq
+                  \bool_set_true:N
+                    \l__zrefclever_type_first_refbounds_set_bool
+                }
+                {
+                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                    {
+                      \exp_not:V \l__zrefclever_listsep_tl
+                      \__zrefclever_get_ref:VN
+                        \l__zrefclever_range_beg_label_tl
+                        \l__zrefclever_refbounds_mid_seq
                       \exp_not:V \l__zrefclever_lastsep_tl
-                      \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                      \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                        \l__zrefclever_refbounds_last_seq
                     }
                 }
             }
@@ -2437,32 +3119,71 @@
                 { 0 }
                 {
                   % If `range_beg_label' is empty, it means it was also the
-                  % first of the type, and hence was already handled.
-                  \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                  % first of the type, and hence its typesetting was already
+                  % handled, and we just have to set refbounds.
+                  \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                     {
-                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                      \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                        \l__zrefclever_refbounds_first_sg_seq
+                      \bool_set_true:N
+                        \l__zrefclever_type_first_refbounds_set_bool
+                    }
+                    {
+                      \int_compare:nNnTF
+                        { \l__zrefclever_ref_count_int } < { 2 }
                         {
-                          \exp_not:V \l__zrefclever_lastsep_tl
-                          \__zrefclever_get_ref:V
-                            \l__zrefclever_range_beg_label_tl
+                          \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                            {
+                              \exp_not:V \l__zrefclever_pairsep_tl
+                              \__zrefclever_get_ref:VN
+                                \l__zrefclever_range_beg_label_tl
+                                \l__zrefclever_refbounds_last_pe_seq
+                            }
                         }
+                        {
+                          \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                            {
+                              \exp_not:V \l__zrefclever_lastsep_tl
+                              \__zrefclever_get_ref:VN
+                                \l__zrefclever_range_beg_label_tl
+                                \l__zrefclever_refbounds_last_seq
+                            }
+                        }
                     }
                 }
-                % A `range', but with no skipped value, treat as list.
+                % A `range', but with no skipped value, treat as pair if range
+                % started with first of type, otherwise as list.
                 % Test: 'zc-typeset01.lvt': "Last of type: range to pair"
                 { 1 }
                 {
-                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                  % Ditto.
+                  \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                     {
-                      % Ditto.
-                      \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                      \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                        \l__zrefclever_refbounds_first_pb_seq
+                      \bool_set_true:N
+                        \l__zrefclever_type_first_refbounds_set_bool
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                         {
+                          \exp_not:V \l__zrefclever_pairsep_tl
+                          \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                            \l__zrefclever_refbounds_last_pe_seq
+                        }
+                    }
+                    {
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                        {
                           \exp_not:V \l__zrefclever_listsep_tl
-                          \__zrefclever_get_ref:V
+                          \__zrefclever_get_ref:VN
                             \l__zrefclever_range_beg_label_tl
+                            \l__zrefclever_refbounds_mid_seq
                         }
-                      \exp_not:V \l__zrefclever_lastsep_tl
-                      \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                        {
+                          \exp_not:V \l__zrefclever_lastsep_tl
+                          \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                            \l__zrefclever_refbounds_last_seq
+                        }
                     }
                 }
               }
@@ -2469,17 +3190,46 @@
               {
                 % An actual range.
                 % Test: 'zc-typeset01.lvt': "Last of type: range"
-                \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                % Ditto.
+                \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                   {
-                    % Ditto.
-                    \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                    \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                      \l__zrefclever_refbounds_first_rb_seq
+                    \bool_set_true:N
+                      \l__zrefclever_type_first_refbounds_set_bool
+                  }
+                  {
+                    \int_compare:nNnTF
+                      { \l__zrefclever_ref_count_int } < { 2 }
                       {
-                        \exp_not:V \l__zrefclever_lastsep_tl
-                        \__zrefclever_get_ref:V
-                          \l__zrefclever_range_beg_label_tl
+                        \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                          {
+                            \exp_not:V \l__zrefclever_pairsep_tl
+                            \__zrefclever_get_ref:VN
+                              \l__zrefclever_range_beg_label_tl
+                              \l__zrefclever_refbounds_mid_rb_seq
+                          }
+                        \seq_set_eq:NN
+                          \l__zrefclever_type_first_refbounds_seq
+                          \l__zrefclever_refbounds_first_pb_seq
+                        \bool_set_true:N
+                          \l__zrefclever_type_first_refbounds_set_bool
                       }
+                      {
+                        \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                          {
+                            \exp_not:V \l__zrefclever_lastsep_tl
+                            \__zrefclever_get_ref:VN
+                              \l__zrefclever_range_beg_label_tl
+                              \l__zrefclever_refbounds_mid_rb_seq
+                          }
+                      }
+                  }
+                \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                  {
                     \exp_not:V \l__zrefclever_rangesep_tl
-                    \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                    \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                      \l__zrefclever_refbounds_last_re_seq
                   }
               }
           }
@@ -2511,16 +3261,40 @@
               }
             % Test: 'zc-typeset01.lvt': "Last of type: option range"
             % Test: 'zc-typeset01.lvt': "Last of type: option range to pair"
-            \tl_set:Nx \l__zrefclever_typeset_queue_curr_tl
+            \bool_if:NTF \l__zrefclever_next_maybe_range_bool
               {
-                \bool_if:NTF \l__zrefclever_next_maybe_range_bool
-                  { \exp_not:V \l__zrefclever_pairsep_tl }
-                  { \exp_not:V \l__zrefclever_rangesep_tl }
-                \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                \tl_set:Nx \l__zrefclever_typeset_queue_curr_tl
+                  {
+                    \exp_not:V \l__zrefclever_pairsep_tl
+                    \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                      \l__zrefclever_refbounds_last_pe_seq
+                  }
+                \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                  \l__zrefclever_refbounds_first_pb_seq
+                \bool_set_true:N \l__zrefclever_type_first_refbounds_set_bool
               }
+              {
+                \tl_set:Nx \l__zrefclever_typeset_queue_curr_tl
+                  {
+                    \exp_not:V \l__zrefclever_rangesep_tl
+                    \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                      \l__zrefclever_refbounds_last_re_seq
+                  }
+                \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                  \l__zrefclever_refbounds_first_rb_seq
+                \bool_set_true:N \l__zrefclever_type_first_refbounds_set_bool
+              }
           }
       }
 
+    % If none of the special cases for the first of type refbounds have been
+    % set, do it.
+    \bool_if:NF \l__zrefclever_type_first_refbounds_set_bool
+      {
+        \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+          \l__zrefclever_refbounds_first_seq
+      }
+
     % Now that the type block is finished, we can add the name and the first
     % ref to the queue.  Also, if "typeset" option is not "both", handle it
     % here as well.
@@ -2536,7 +3310,10 @@
           {
             % Test: 'zc-typeset01.lvt': "Last of type: option typeset ref"
             \tl_put_left:Nx \l__zrefclever_typeset_queue_curr_tl
-              { \__zrefclever_get_ref:V \l__zrefclever_type_first_label_tl }
+              {
+                \__zrefclever_get_ref:VN \l__zrefclever_type_first_label_tl
+                  \l__zrefclever_type_first_refbounds_seq
+              }
           }
           {
             \bool_if:NTF \l__zrefclever_typeset_name_bool
@@ -2636,9 +3413,11 @@
         \tl_clear:N \l__zrefclever_type_first_label_type_tl
         \tl_clear:N \l__zrefclever_range_beg_label_tl
         \int_zero:N \l__zrefclever_label_count_int
+        \int_zero:N \l__zrefclever_ref_count_int
         \int_incr:N \l__zrefclever_type_count_int
         \int_zero:N \l__zrefclever_range_count_int
         \int_zero:N \l__zrefclever_range_same_count_int
+        \bool_set_false:N \l__zrefclever_type_first_refbounds_set_bool
       }
   }
 \cs_new_protected:Npn \__zrefclever_typeset_refs_not_last_of_type:
@@ -2666,6 +3445,7 @@
           \l__zrefclever_label_a_tl
         \tl_set:NV \l__zrefclever_type_first_label_type_tl
           \l__zrefclever_label_type_a_tl
+        \int_incr:N \l__zrefclever_ref_count_int
 
         % If the next label may be part of a range, we set `range_beg_label'
         % to "empty" (we deal with it as the "first", and must do it there, to
@@ -2710,10 +3490,12 @@
                 % Test: 'zc-typeset01.lvt': "Not last of type: no range"
                 { 0 }
                 {
+                  \int_incr:N \l__zrefclever_ref_count_int
                   \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                     {
                       \exp_not:V \l__zrefclever_listsep_tl
-                      \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                      \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                        \l__zrefclever_refbounds_mid_seq
                     }
                 }
                 % Last is second in the range: if `range_same_count' is also
@@ -2723,20 +3505,33 @@
                 % Test: 'zc-typeset01.lvt': "Not last of type: range pair"
                 { 1 }
                 {
-                  \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                  \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                     {
-                      \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                      \seq_set_eq:NN \l__zrefclever_type_first_refbounds_seq
+                        \l__zrefclever_refbounds_first_seq
+                      \bool_set_true:N
+                        \l__zrefclever_type_first_refbounds_set_bool
+                    }
+                    {
+                      \int_incr:N \l__zrefclever_ref_count_int
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                         {
                           \exp_not:V \l__zrefclever_listsep_tl
-                          \__zrefclever_get_ref:V
+                          \__zrefclever_get_ref:VN
                             \l__zrefclever_range_beg_label_tl
+                            \l__zrefclever_refbounds_mid_seq
                         }
-                      \int_compare:nNnF
-                        { \l__zrefclever_range_same_count_int } = { 1 }
+                    }
+                  \int_compare:nNnF
+                    { \l__zrefclever_range_same_count_int } = { 1 }
+                    {
+                      \int_incr:N \l__zrefclever_ref_count_int
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                         {
                           \exp_not:V \l__zrefclever_listsep_tl
-                          \__zrefclever_get_ref:V
+                          \__zrefclever_get_ref:VN
                             \l__zrefclever_label_a_tl
+                            \l__zrefclever_refbounds_mid_seq
                         }
                     }
                 }
@@ -2755,13 +3550,22 @@
                     % Test: 'zc-typeset01.lvt': "Not last of type: range to one"
                     { 0 }
                     {
-                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                      \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                         {
-                          \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                          \seq_set_eq:NN
+                            \l__zrefclever_type_first_refbounds_seq
+                            \l__zrefclever_refbounds_first_seq
+                          \bool_set_true:N
+                            \l__zrefclever_type_first_refbounds_set_bool
+                        }
+                        {
+                          \int_incr:N \l__zrefclever_ref_count_int
+                          \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                             {
                               \exp_not:V \l__zrefclever_listsep_tl
-                              \__zrefclever_get_ref:V
+                              \__zrefclever_get_ref:VN
                                 \l__zrefclever_range_beg_label_tl
+                                \l__zrefclever_refbounds_mid_seq
                             }
                         }
                     }
@@ -2768,31 +3572,63 @@
                     % Test: 'zc-typeset01.lvt': "Not last of type: range to pair"
                     { 1 }
                     {
-                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                      \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                         {
-                          \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                          \seq_set_eq:NN
+                            \l__zrefclever_type_first_refbounds_seq
+                            \l__zrefclever_refbounds_first_seq
+                          \bool_set_true:N
+                            \l__zrefclever_type_first_refbounds_set_bool
+                        }
+                        {
+                          \int_incr:N \l__zrefclever_ref_count_int
+                          \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                             {
                               \exp_not:V \l__zrefclever_listsep_tl
-                              \__zrefclever_get_ref:V
+                              \__zrefclever_get_ref:VN
                                 \l__zrefclever_range_beg_label_tl
+                                \l__zrefclever_refbounds_mid_seq
                             }
+                        }
+                      \int_incr:N \l__zrefclever_ref_count_int
+                      \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                        {
                           \exp_not:V \l__zrefclever_listsep_tl
-                          \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                          \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                            \l__zrefclever_refbounds_mid_seq
                         }
                     }
                   }
                   {
                     % Test: 'zc-typeset01.lvt': "Not last of type: range"
-                    \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                    \tl_if_empty:VTF \l__zrefclever_range_beg_label_tl
                       {
-                        \tl_if_empty:VF \l__zrefclever_range_beg_label_tl
+                        \seq_set_eq:NN
+                          \l__zrefclever_type_first_refbounds_seq
+                          \l__zrefclever_refbounds_first_rb_seq
+                        \bool_set_true:N
+                          \l__zrefclever_type_first_refbounds_set_bool
+                      }
+                      {
+                        \int_incr:N \l__zrefclever_ref_count_int
+                        \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
                           {
                             \exp_not:V \l__zrefclever_listsep_tl
-                            \__zrefclever_get_ref:V
+                            \__zrefclever_get_ref:VN
                               \l__zrefclever_range_beg_label_tl
+                              \l__zrefclever_refbounds_mid_rb_seq
                           }
+                      }
+                    % For the purposes of the serial comma, and thus for the
+                    % distinction of 'lastsep' and 'pairsep', a "range" counts
+                    % as one.  Since 'range_beg' has already been counted
+                    % (here or with the first of type), we refrain from
+                    % incrementing 'ref_count_int'.
+                    \tl_put_right:Nx \l__zrefclever_typeset_queue_curr_tl
+                      {
                         \exp_not:V \l__zrefclever_rangesep_tl
-                        \__zrefclever_get_ref:V \l__zrefclever_label_a_tl
+                        \__zrefclever_get_ref:VN \l__zrefclever_label_a_tl
+                          \l__zrefclever_refbounds_mid_re_seq
                       }
                   }
               }
@@ -2808,49 +3644,47 @@
   { \zref at default }
 \cs_new_protected:Npn \__zrefclever_name_default:
   { \zref at default }
-\cs_new:Npn \__zrefclever_get_ref:n #1
+\cs_new:Npn \__zrefclever_get_ref:nN #1#2
   {
     \zref at ifrefcontainsprop {#1} { \l__zrefclever_ref_property_tl }
       {
         \bool_if:nTF
           {
-            \l__zrefclever_use_hyperref_bool &&
+            \l__zrefclever_hyperlink_bool &&
             ! \l__zrefclever_link_star_bool
           }
           {
-            \bool_if:NF \l__zrefclever_preposinlink_bool
-              { \exp_not:V \l__zrefclever_preref_tl }
+            \exp_not:N \group_begin:
+            \exp_not:V \l__zrefclever_reffont_tl
+            \seq_item:Nn #2 { 1 }
             % It's two `@s', but escaped for DocStrip.
             \exp_not:N \hyper@@link
               { \__zrefclever_extract_url_unexp:n {#1} }
               { \__zrefclever_extract_unexp:nnn {#1} { anchor } { } }
               {
-                \bool_if:NT \l__zrefclever_preposinlink_bool
-                  { \exp_not:V \l__zrefclever_preref_tl }
-                \exp_not:N \group_begin:
-                \exp_not:V \l__zrefclever_reffont_tl
+                \seq_item:Nn #2 { 2 }
                 \__zrefclever_extract_unexp:nvn {#1}
                   { l__zrefclever_ref_property_tl } { }
-                \exp_not:N \group_end:
-                \bool_if:NT \l__zrefclever_preposinlink_bool
-                  { \exp_not:V \l__zrefclever_postref_tl }
+                \seq_item:Nn #2 { 3 }
               }
-            \bool_if:NF \l__zrefclever_preposinlink_bool
-              { \exp_not:V \l__zrefclever_postref_tl }
+            \seq_item:Nn #2 { 4 }
+            \exp_not:N \group_end:
           }
           {
-            \exp_not:V \l__zrefclever_preref_tl
             \exp_not:N \group_begin:
             \exp_not:V \l__zrefclever_reffont_tl
+            \seq_item:Nn #2 { 1 }
+            \seq_item:Nn #2 { 2 }
             \__zrefclever_extract_unexp:nvn {#1}
               { l__zrefclever_ref_property_tl } { }
+            \seq_item:Nn #2 { 3 }
+            \seq_item:Nn #2 { 4 }
             \exp_not:N \group_end:
-            \exp_not:V \l__zrefclever_postref_tl
           }
       }
       { \__zrefclever_ref_default: }
   }
-\cs_generate_variant:Nn \__zrefclever_get_ref:n { V }
+\cs_generate_variant:Nn \__zrefclever_get_ref:nN { VN }
 \cs_new:Npn \__zrefclever_get_ref_first:
   {
     \zref at ifrefundefined { \l__zrefclever_type_first_label_tl }
@@ -2862,6 +3696,7 @@
               { \l__zrefclever_type_first_label_tl }
               { \l__zrefclever_ref_property_tl }
               {
+                \exp_not:N \group_begin:
                 % It's two `@s', but escaped for DocStrip.
                 \exp_not:N \hyper@@link
                   {
@@ -2878,18 +3713,19 @@
                     \exp_not:V \l__zrefclever_type_name_tl
                     \exp_not:N \group_end:
                     \exp_not:V \l__zrefclever_namesep_tl
-                    \exp_not:V \l__zrefclever_preref_tl
                     \exp_not:N \group_begin:
                     \exp_not:V \l__zrefclever_reffont_tl
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 1 }
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 2 }
                     \__zrefclever_extract_unexp:Vvn
                       \l__zrefclever_type_first_label_tl
                       { l__zrefclever_ref_property_tl } { }
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 3 }
                     \exp_not:N \group_end:
-                    \bool_if:NT \l__zrefclever_preposinlink_bool
-                      { \exp_not:V \l__zrefclever_postref_tl }
                   }
-                \bool_if:NF \l__zrefclever_preposinlink_bool
-                  { \exp_not:V \l__zrefclever_postref_tl }
+                \exp_not:V \l__zrefclever_reffont_tl
+                \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 4 }
+                \exp_not:N \group_end:
               }
               {
                 \exp_not:N \group_begin:
@@ -2901,7 +3737,7 @@
               }
           }
           {
-            \tl_if_empty:NTF \l__zrefclever_type_name_tl
+            \bool_if:nTF \l__zrefclever_type_name_missing_bool
               {
                 \__zrefclever_name_default:
                 \exp_not:V \l__zrefclever_namesep_tl
@@ -2911,7 +3747,8 @@
                 \exp_not:V \l__zrefclever_namefont_tl
                 \exp_not:V \l__zrefclever_type_name_tl
                 \exp_not:N \group_end:
-                \exp_not:V \l__zrefclever_namesep_tl
+                \tl_if_empty:NF \l__zrefclever_type_name_tl
+                  { \exp_not:V \l__zrefclever_namesep_tl }
               }
             \zref at ifrefcontainsprop
               { \l__zrefclever_type_first_label_tl }
@@ -2919,12 +3756,14 @@
               {
                 \bool_if:nTF
                   {
-                    \l__zrefclever_use_hyperref_bool &&
+                    \l__zrefclever_hyperlink_bool &&
                     ! \l__zrefclever_link_star_bool
                   }
                   {
-                    \bool_if:NF \l__zrefclever_preposinlink_bool
-                      { \exp_not:V \l__zrefclever_preref_tl }
+                    \exp_not:N \group_begin:
+                    \exp_not:V \l__zrefclever_reffont_tl
+                    \seq_item:Nn
+                      \l__zrefclever_type_first_refbounds_seq { 1 }
                     % It's two '@s', but escaped for DocStrip.
                     \exp_not:N \hyper@@link
                       {
@@ -2936,29 +3775,29 @@
                           \l__zrefclever_type_first_label_tl { anchor } { }
                       }
                       {
-                        \bool_if:NT \l__zrefclever_preposinlink_bool
-                          { \exp_not:V \l__zrefclever_preref_tl }
-                        \exp_not:N \group_begin:
-                        \exp_not:V \l__zrefclever_reffont_tl
+                        \seq_item:Nn
+                          \l__zrefclever_type_first_refbounds_seq { 2 }
                         \__zrefclever_extract_unexp:Vvn
                           \l__zrefclever_type_first_label_tl
                           { l__zrefclever_ref_property_tl } { }
-                        \exp_not:N \group_end:
-                        \bool_if:NT \l__zrefclever_preposinlink_bool
-                          { \exp_not:V \l__zrefclever_postref_tl }
+                        \seq_item:Nn
+                          \l__zrefclever_type_first_refbounds_seq { 3 }
                       }
-                    \bool_if:NF \l__zrefclever_preposinlink_bool
-                      { \exp_not:V \l__zrefclever_postref_tl }
+                    \seq_item:Nn
+                      \l__zrefclever_type_first_refbounds_seq { 4 }
+                    \exp_not:N \group_end:
                   }
                   {
-                    \exp_not:V \l__zrefclever_preref_tl
                     \exp_not:N \group_begin:
                     \exp_not:V \l__zrefclever_reffont_tl
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 1 }
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 2 }
                     \__zrefclever_extract_unexp:Vvn
                       \l__zrefclever_type_first_label_tl
                       { l__zrefclever_ref_property_tl } { }
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 3 }
+                    \seq_item:Nn \l__zrefclever_type_first_refbounds_seq { 4 }
                     \exp_not:N \group_end:
-                    \exp_not:V \l__zrefclever_postref_tl
                   }
               }
               { \__zrefclever_ref_default: }
@@ -2968,18 +3807,24 @@
 \cs_new_protected:Npn \__zrefclever_type_name_setup:
   {
     \zref at ifrefundefined { \l__zrefclever_type_first_label_tl }
-      { \tl_clear:N \l__zrefclever_type_name_tl }
       {
+        \tl_clear:N \l__zrefclever_type_name_tl
+        \bool_set_true:N \l__zrefclever_type_name_missing_bool
+      }
+      {
         \tl_if_eq:NnTF
           \l__zrefclever_type_first_label_type_tl { zc at missingtype }
-          { \tl_clear:N \l__zrefclever_type_name_tl }
           {
+            \tl_clear:N \l__zrefclever_type_name_tl
+            \bool_set_true:N \l__zrefclever_type_name_missing_bool
+          }
+          {
             % Determine whether we should use capitalization, abbreviation,
             % and plural.
             \bool_lazy_or:nnTF
-              { \l__zrefclever_capitalize_bool }
+              { \l__zrefclever_cap_bool }
               {
-                \l__zrefclever_capitalize_first_bool &&
+                \l__zrefclever_capfirst_bool &&
                 \int_compare_p:nNn { \l__zrefclever_type_count_int } = { 0 }
               }
               { \tl_set:Nn \l__zrefclever_name_format_tl {Name} }
@@ -3034,19 +3879,15 @@
                   { \l__zrefclever_nudge_gender_bool }
                   { ! \tl_if_empty_p:N \l__zrefclever_ref_gender_tl }
                   {
-                    \__zrefclever_get_lang_opt_type:xxnNF
+                    \__zrefclever_get_rf_opt_seq:nxxN { gender }
+                      { \l__zrefclever_type_first_label_type_tl }
                       { \l__zrefclever_ref_language_tl }
-                      { \l__zrefclever_type_first_label_type_tl }
-                      { gender }
-                      \l__zrefclever_type_name_gender_tl
-                      { \tl_clear:N \l__zrefclever_type_name_gender_tl }
-                    \clist_set:NV \l_tmpa_clist
-                      \l__zrefclever_type_name_gender_tl
-                    \clist_if_in:NVF
-                      \l_tmpa_clist
+                      \l__zrefclever_type_name_gender_seq
+                    \seq_if_in:NVF
+                      \l__zrefclever_type_name_gender_seq
                       \l__zrefclever_ref_gender_tl
                       {
-                        \tl_if_empty:NTF \l__zrefclever_type_name_gender_tl
+                        \seq_if_empty:NTF \l__zrefclever_type_name_gender_seq
                           {
                             \msg_warning:nnxxx { zref-clever }
                               { nudge-gender-not-declared-for-type }
@@ -3059,7 +3900,10 @@
                               { nudge-gender-mismatch }
                               { \l__zrefclever_type_first_label_type_tl }
                               { \l__zrefclever_ref_gender_tl }
-                              { \l__zrefclever_type_name_gender_tl }
+                              {
+                                \seq_use:Nn
+                                  \l__zrefclever_type_name_gender_seq { ,~ }
+                              }
                               { \l__zrefclever_ref_language_tl }
                           }
                       }
@@ -3068,12 +3912,13 @@
 
             \tl_if_empty:NTF \l__zrefclever_name_format_fallback_tl
               {
-                \prop_get:cVNF
+                \__zrefclever_opt_tl_get:cNF
                   {
-                    l__zrefclever_type_
-                    \l__zrefclever_type_first_label_type_tl _options_prop
+                    \__zrefclever_opt_varname_type:een
+                      { \l__zrefclever_type_first_label_type_tl }
+                      { \l__zrefclever_name_format_tl }
+                      { tl }
                   }
-                  \l__zrefclever_name_format_tl
                   \l__zrefclever_type_name_tl
                   {
                     \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
@@ -3082,13 +3927,18 @@
                         \tl_put_left:NV \l__zrefclever_name_format_tl
                           \l__zrefclever_ref_decl_case_tl
                       }
-                    \__zrefclever_get_lang_opt_type:xxxNF
-                      { \l__zrefclever_ref_language_tl }
-                      { \l__zrefclever_type_first_label_type_tl }
-                      { \l__zrefclever_name_format_tl }
+                    \__zrefclever_opt_tl_get:cNF
+                      {
+                        \__zrefclever_opt_varname_lang_type:eeen
+                          { \l__zrefclever_ref_language_tl }
+                          { \l__zrefclever_type_first_label_type_tl }
+                          { \l__zrefclever_name_format_tl }
+                          { tl }
+                      }
                       \l__zrefclever_type_name_tl
                       {
                         \tl_clear:N \l__zrefclever_type_name_tl
+                        \bool_set_true:N \l__zrefclever_type_name_missing_bool
                         \msg_warning:nnxx { zref-clever } { missing-name }
                           { \l__zrefclever_name_format_tl }
                           { \l__zrefclever_type_first_label_type_tl }
@@ -3096,20 +3946,22 @@
                   }
               }
               {
-                \prop_get:cVNF
+                \__zrefclever_opt_tl_get:cNF
                   {
-                    l__zrefclever_type_
-                    \l__zrefclever_type_first_label_type_tl _options_prop
+                    \__zrefclever_opt_varname_type:een
+                      { \l__zrefclever_type_first_label_type_tl }
+                      { \l__zrefclever_name_format_tl }
+                      { tl }
                   }
-                  \l__zrefclever_name_format_tl
                   \l__zrefclever_type_name_tl
                   {
-                    \prop_get:cVNF
+                    \__zrefclever_opt_tl_get:cNF
                       {
-                        l__zrefclever_type_
-                        \l__zrefclever_type_first_label_type_tl _options_prop
+                        \__zrefclever_opt_varname_type:een
+                          { \l__zrefclever_type_first_label_type_tl }
+                          { \l__zrefclever_name_format_fallback_tl }
+                          { tl }
                       }
-                      \l__zrefclever_name_format_fallback_tl
                       \l__zrefclever_type_name_tl
                       {
                         \tl_if_empty:NF \l__zrefclever_ref_decl_case_tl
@@ -3124,19 +3976,29 @@
                               \l__zrefclever_name_format_fallback_tl
                               \l__zrefclever_ref_decl_case_tl
                           }
-                        \__zrefclever_get_lang_opt_type:xxxNF
-                          { \l__zrefclever_ref_language_tl }
-                          { \l__zrefclever_type_first_label_type_tl }
-                          { \l__zrefclever_name_format_tl }
-                          \l__zrefclever_type_name_tl
+                        \__zrefclever_opt_tl_get:cNF
                           {
-                            \__zrefclever_get_lang_opt_type:xxxNF
+                            \__zrefclever_opt_varname_lang_type:eeen
                               { \l__zrefclever_ref_language_tl }
                               { \l__zrefclever_type_first_label_type_tl }
-                              { \l__zrefclever_name_format_fallback_tl }
+                              { \l__zrefclever_name_format_tl }
+                              { tl }
+                          }
+                          \l__zrefclever_type_name_tl
+                          {
+                            \__zrefclever_opt_tl_get:cNF
+                              {
+                                \__zrefclever_opt_varname_lang_type:eeen
+                                  { \l__zrefclever_ref_language_tl }
+                                  { \l__zrefclever_type_first_label_type_tl }
+                                  { \l__zrefclever_name_format_fallback_tl }
+                                  { tl }
+                              }
                               \l__zrefclever_type_name_tl
                               {
                                 \tl_clear:N \l__zrefclever_type_name_tl
+                                \bool_set_true:N
+                                  \l__zrefclever_type_name_missing_bool
                                 \msg_warning:nnxx { zref-clever }
                                   { missing-name }
                                   { \l__zrefclever_name_format_tl }
@@ -3152,7 +4014,7 @@
     % Signal whether the type name is to be included in the hyperlink or not.
     \bool_lazy_any:nTF
       {
-        { ! \l__zrefclever_use_hyperref_bool }
+        { ! \l__zrefclever_hyperlink_bool }
         { \l__zrefclever_link_star_bool }
         { \tl_if_empty_p:N \l__zrefclever_type_name_tl }
         { \str_if_eq_p:Vn \l__zrefclever_nameinlink_str { false } }
@@ -3180,11 +4042,11 @@
 \cs_new:Npn \__zrefclever_extract_url_unexp:n #1
   {
     \zref at ifpropundefined { urluse }
-      { \__zrefclever_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+      { \__zrefclever_extract_unexp:nnn {#1} { url } { } }
       {
         \zref at ifrefcontainsprop {#1} { urluse }
-          { \__zrefclever_extract_unexp:nnn {#1} { urluse } { \c_empty_tl } }
-          { \__zrefclever_extract_unexp:nnn {#1} { url } { \c_empty_tl } }
+          { \__zrefclever_extract_unexp:nnn {#1} { urluse } { } }
+          { \__zrefclever_extract_unexp:nnn {#1} { url } { } }
       }
   }
 \cs_generate_variant:Nn \__zrefclever_extract_url_unexp:n { V }
@@ -3191,9 +4053,9 @@
 \cs_new_protected:Npn \__zrefclever_labels_in_sequence:nn #1#2
   {
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_extdoc_a_tl
-      {#1} { externaldocument } { \c_empty_tl }
+      {#1} { externaldocument } { }
     \__zrefclever_extract_default:Nnnn \l__zrefclever_label_extdoc_b_tl
-      {#2} { externaldocument } { \c_empty_tl }
+      {#2} { externaldocument } { }
 
     \tl_if_eq:NNT
       \l__zrefclever_label_extdoc_a_tl
@@ -3264,145 +4126,105 @@
           }
       }
   }
-\cs_new_protected:Npn \__zrefclever_get_ref_opt_typeset:nN #1#2
+\cs_new_protected:Npn \__zrefclever_get_rf_opt_tl:nnnN #1#2#3#4
   {
     % First attempt: general options.
-    \prop_get:NnNF \l__zrefclever_ref_options_prop {#1} #2
+    \__zrefclever_opt_tl_get:cNF
+      { \__zrefclever_opt_varname_general:nn {#1} { tl } }
+      #4
       {
         % If not found, try type specific options.
-        \bool_lazy_and:nnTF
+        \__zrefclever_opt_tl_get:cNF
+          { \__zrefclever_opt_varname_type:nnn {#2} {#1} { tl } }
+          #4
           {
-            \prop_if_exist_p:c
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-          }
-          {
-            \prop_if_in_p:cn
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-              {#1}
-          }
-          {
-            \prop_get:cnN
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-              {#1} #2
-          }
-          {
             % If not found, try type- and language-specific.
-            \__zrefclever_get_lang_opt_type:xxnNF
-              { \l__zrefclever_ref_language_tl }
-              { \l__zrefclever_label_type_a_tl }
-              {#1} #2
+            \__zrefclever_opt_tl_get:cNF
+              { \__zrefclever_opt_varname_lang_type:nnnn {#3} {#2} {#1} { tl } }
+              #4
               {
                 % If not found, try language-specific default.
-                \__zrefclever_get_lang_opt_default:xnNF
-                  { \l__zrefclever_ref_language_tl }
-                  {#1} #2
+                \__zrefclever_opt_tl_get:cNF
+                  { \__zrefclever_opt_varname_lang_default:nnn {#3} {#1} { tl } }
+                  #4
                   {
                     % If not found, try fallback.
-                    \__zrefclever_get_fallback_unknown_lang_opt:nNF {#1} #2
-                      {
-                        \tl_clear:N #2
-                        \msg_warning:nnn { zref-clever }
-                          { missing-string } {#1}
-                      }
+                    \__zrefclever_opt_tl_get:cNF
+                      { \__zrefclever_opt_varname_fallback:nn {#1} { tl } }
+                      #4
+                      { \tl_clear:N #4 }
                   }
               }
           }
       }
   }
-\cs_new_protected:Npn \__zrefclever_get_ref_opt_font:nN #1#2
+\cs_generate_variant:Nn \__zrefclever_get_rf_opt_tl:nnnN { nxxN }
+\cs_new_protected:Npn \__zrefclever_get_rf_opt_seq:nnnN #1#2#3#4
   {
     % First attempt: general options.
-    \prop_get:NnNF \l__zrefclever_ref_options_prop {#1} #2
+    \__zrefclever_opt_seq_get:cNF
+      { \__zrefclever_opt_varname_general:nn {#1} { seq } }
+      #4
       {
         % If not found, try type specific options.
-        \bool_if:nTF
+        \__zrefclever_opt_seq_get:cNF
+          { \__zrefclever_opt_varname_type:nnn {#2} {#1} { seq } }
+          #4
           {
-            \prop_if_exist_p:c
+            % If not found, try type- and language-specific.
+            \__zrefclever_opt_seq_get:cNF
+              { \__zrefclever_opt_varname_lang_type:nnnn {#3} {#2} {#1} { seq } }
+              #4
               {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
+                % If not found, try language-specific default.
+                \__zrefclever_opt_seq_get:cNF
+                  { \__zrefclever_opt_varname_lang_default:nnn {#3} {#1} { seq } }
+                  #4
+                  {
+                    % If not found, try fallback.
+                    \__zrefclever_opt_seq_get:cNF
+                      { \__zrefclever_opt_varname_fallback:nn {#1} { seq } }
+                      #4
+                      { \seq_clear:N #4 }
+                  }
               }
           }
-          {
-            \prop_get:cnNF
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-              {#1} #2
-              { \tl_clear:N #2 }
-          }
-          { \tl_clear:N #2 }
       }
   }
-\cs_new_protected:Npn \__zrefclever_get_ref_opt_bool:nnN #1#2#3
+\cs_generate_variant:Nn \__zrefclever_get_rf_opt_seq:nnnN { nxxN }
+\cs_new_protected:Npn \__zrefclever_get_rf_opt_bool:nnnnN #1#2#3#4#5
   {
     % First attempt: general options.
-    \prop_get:NnNF \l__zrefclever_ref_options_prop {#1} \l_tmpa_tl
+    \__zrefclever_opt_bool_get:cNF
+      { \__zrefclever_opt_varname_general:nn {#1} { bool } }
+      #5
       {
         % If not found, try type specific options.
-        \bool_lazy_and:nnTF
+        \__zrefclever_opt_bool_get:cNF
+          { \__zrefclever_opt_varname_type:nnn {#3} {#1} { bool } }
+          #5
           {
-            \prop_if_exist_p:c
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-          }
-          {
-            \prop_if_in_p:cn
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-              {#1}
-          }
-          {
-            \prop_get:cnN
-              {
-                l__zrefclever_type_
-                \l__zrefclever_label_type_a_tl _options_prop
-              }
-              {#1} \l_tmpa_tl
-          }
-          {
             % If not found, try type- and language-specific.
-            \__zrefclever_get_lang_opt_type:xxnNF
-              { \l__zrefclever_ref_language_tl }
-              { \l__zrefclever_label_type_a_tl }
-              {#1} \l_tmpa_tl
+            \__zrefclever_opt_bool_get:cNF
+              { \__zrefclever_opt_varname_lang_type:nnnn {#4} {#3} {#1} { bool } }
+              #5
               {
                 % If not found, try language-specific default.
-                \__zrefclever_get_lang_opt_default:xnNF
-                  { \l__zrefclever_ref_language_tl }
-                  {#1} \l_tmpa_tl
+                \__zrefclever_opt_bool_get:cNF
+                  { \__zrefclever_opt_varname_lang_default:nnn {#4} {#1} { bool } }
+                  #5
                   {
-                    % If not found, use default argument.
-                    \bool_lazy_or:nnTF
-                      { \str_if_eq_p:nn {#2} { true  } }
-                      { \str_if_eq_p:nn {#2} { false } }
-                      { \tl_set:Nn \l_tmpa_tl {#2} }
-                      {
-                        % And, if even that fails, presume false.
-                        \tl_set:Nn \l_tmpa_tl { false }
-                      }
+                    % If not found, try fallback.
+                    \__zrefclever_opt_bool_get:cNF
+                      { \__zrefclever_opt_varname_fallback:nn {#1} { bool } }
+                      #5
+                      { \use:c { bool_set_ #2 :N } #5 }
                   }
               }
           }
       }
-    % Having retrieved the option value, set the boolean.  At this point, we
-    % *know* '\l_tmpa_tl' is either 'true' or 'false'.
-    \use:c { bool_set_ \l_tmpa_tl :N } #3
   }
+\cs_generate_variant:Nn \__zrefclever_get_rf_opt_bool:nnnnN { nnxxN }
 \__zrefclever_compat_module:nn { appendix }
   {
     \AddToHook { cmd / appendix / before }
@@ -3638,11 +4460,7 @@
               { \__zrefclever_zcsetup:n { currentcounter = equation } }
           }
         \zcRefTypeSetup { equation }
-          {
-            reffont = \upshape ,
-            preref  = {\textup{(}} ,
-            postref = {\textup{)}} ,
-          }
+          { reffont = \upshape }
         \msg_info:nnn { zref-clever } { compat-package } { amsmath }
       }
   }



More information about the tex-live-commits mailing list.