diff --git a/css/components/_pretext.scss b/css/components/_pretext.scss index 45b9b4274a..1677e2af53 100644 --- a/css/components/_pretext.scss +++ b/css/components/_pretext.scss @@ -9,6 +9,7 @@ $navbar-breakpoint: 800px !default; @use 'spacing'; @use 'elements/lists'; @use 'elements/fillin'; +@use 'elements/veil'; @use 'elements/headings'; @use 'elements/links'; @use 'elements/tables'; diff --git a/css/components/elements/_veil.scss b/css/components/elements/_veil.scss new file mode 100644 index 0000000000..8b15135ec7 --- /dev/null +++ b/css/components/elements/_veil.scss @@ -0,0 +1,111 @@ +/* ========================================================================== + PreTeXt — final SCSS (light: royal blue, dark: burnt orange) + - Transparent background for revealed content + - Non-transparent button background (mode-aware) + - Works for inline (.veil--inline) and block (.veil--block) veils + - Includes keyboard focus and pressed feedback + ========================================================================== */ + +/* ---------------- Theme tokens via CSS variables ------------------------- */ +:root { + --veil-primary: #1d4ed8; /* royal blue */ + --veil-btn-bg: #f8fafc; /* very light gray-blue */ + --veil-text-color: inherit; + + --veil-focus-ring: rgba(29, 78, 216, 0.35); + --veil-hover-ring: rgba(29, 78, 216, 0.18); + --veil-pressed-shadow: rgba(0,0,0,0.06); +} + +/* Dark mode uses a burnt orange accent; PreTeXt toggles .dark-mode on */ +.dark-mode { + --veil-primary: #f59e0b; /* burnt orange */ + --veil-btn-bg: rgba(245, 158, 11, 0.12); + --veil-text-color: inherit; + + --veil-focus-ring: rgba(245, 158, 11, 0.45); + --veil-hover-ring: rgba(245, 158, 11, 0.22); + --veil-pressed-shadow: rgba(245, 158, 11, 0.16); +} + +/* ---------------- Containers -------------------------------------------- */ +.veil--inline { display: inline; } +.veil--block { margin: 0.25rem 0; } + +/* ---------------- Reveal button (shown when hidden) --------------------- */ +.veil .veil-toggle { + display: inline-block; + background: var(--veil-btn-bg); + color: var(--veil-primary); + padding: 0.06rem 0.35rem; + // border: 1px solid color-mix(in srgb, var(--veil-primary) 35%, transparent); + border: 1px solid currentColor; + border-radius: 0.25rem; + font-size: 0.85rem; + line-height: 1.2; + cursor: pointer; + vertical-align: baseline; + transition: box-shadow 120ms ease, transform 60ms ease, border-color 120ms ease; + + &:hover { + box-shadow: 0 0 0 2px var(--veil-hover-ring); + } + &:active { + transform: scale(0.995); + } + &:focus-visible { + outline: 2px solid var(--veil-focus-ring); + outline-offset: 2px; + } +} + +/* ---------------- Hidden by default ------------------------------------ */ +.veil .veil-content { + display: none; +} + +/* ---------------- Revealed state --------------------------------------- */ +.veil.revealed .veil-toggle { display: none; } + +.veil.revealed .veil-content { + display: inline; /* overridden to block for block variant */ + background: transparent; /* transparent background as requested */ + color: var(--veil-text-color); + border: 1px solid var(--veil-primary); + padding: 0.06rem 0.30rem; + border-radius: 0.20rem; + cursor: pointer; + transition: transform 60ms ease, box-shadow 120ms ease, border-color 120ms ease; + + &:hover { + box-shadow: 0 0 0 2px var(--veil-hover-ring) inset; + } + &:focus-visible { + outline: 2px solid var(--veil-focus-ring); + outline-offset: 2px; + } + + /* Pressed feedback (toggled by JS on pointer events) */ + &.is-pressed { + transform: scale(0.995); + box-shadow: 0 0 0 3px var(--veil-pressed-shadow) inset; + } +} + +/* Block variant shows content as a block when revealed */ +.veil--block.revealed .veil-content { + display: block; + padding: 0.40rem 0.55rem; +} + +/* ---------------- Print (HTML -> paper) --------------------------------- */ +@media print { + .veil .veil-toggle { display: none !important; } + .veil .veil-content { + display: inline !important; + border: none !important; + background: transparent !important; + padding: 0 !important; + } + .veil--block .veil-content { display: block !important; } +} \ No newline at end of file diff --git a/examples/sample-article/sample-article.xml b/examples/sample-article/sample-article.xml index 11b3e564a4..f474e60d68 100644 --- a/examples/sample-article/sample-article.xml +++ b/examples/sample-article/sample-article.xml @@ -10215,6 +10215,106 @@ along with MathBook XML. If not, see . +
+ Veil Element Testing + +

The function f(t) = e^{-t} satisfies the differential equation f'(t) = -f(t), which is characteristic of exponential decay.

+ +

This sentence contains a simple hidden phrase and continues normally.

+ +

Here is a veil wrapping emphasized hidden text within an emphasized span.

+ +

You can also hide inline math like f(t) = e^{-t} without breaking the flow.

+ +

+ Testing long text. Looks bad in print, but should be fine in HTML: + + This is a very long phrase that includes emphasis, + inline math \int_0^1 x^2 dx = \frac{1}{3}, and even a short sentence to see if line wrapping behaves properly. + +

+ +

+ Testing long text inside <p> tags: + +

+ This is a very long phrase that includes emphasis, + inline math \int_0^1 x^2 dx = \frac{1}{3}, and even a short sentence to see if line wrapping behaves properly. +

+ +

+ +

Multiple consecutive veils: first hidden, then some regular text, and second hidden part.

+ + h(x) = \int_0^x \sin(t)\ dt + +

A veil at the end of the sentence.

+ +

A hidden external link: PreTeXt website is a great resource.

+ +

The command is pip install pretext, which installs the toolkit.

+ +

Two quick reveals: first,second.

+ +

The derivative of e^{kt} is k\,e^{kt}.

+ +

The identity \sin^2\theta + \cos^2\theta = 1 is fundamental.

+ +
    +
  • The capital of France is Paris.
  • +
  • \int_0^1 x^2\,dx = \tfrac{1}{3}.
  • +
+ +
    +
  1. Differentiate: \frac{d}{dx}\big(x^3\big)=3x^2
  2. +
  3. Evaluate: f(2) = 12
  4. +
+ + + A tiny table with veiled entries + + + Quantity + Value + + + Slope + \frac{\Delta y}{\Delta x} + + + Secret code + AX-42 + + +
+ +
+ Just some cubic functions. + +
+ + +

Hint. Use an integrating factor \mu(x)=e^{\int p(x)\,dx} to solve y'+p(x)y=q(x).

+
+ + + \int_0^{2\pi}\sin(x)\,dx = 0 + + + + Geometric Series + + For |r| < 1, \sum_{k=0}^{\infty} r^k = \frac{1}{1-r}. + + +

Consider the partial sums S_n = \sum_{k=0}^{n} r^k and compute (1-r)S_n, then take n\to\infty.

+
+
+ +

The eigenvalues of \begin{pmatrix}2 \amp 0\\0 \amp 3\end{pmatrix} are 2, 3.

+ +
+ + + diff --git a/xsl/pretext-html.xsl b/xsl/pretext-html.xsl index 196a7cd34e..d85003fd2d 100644 --- a/xsl/pretext-html.xsl +++ b/xsl/pretext-html.xsl @@ -8646,6 +8646,58 @@ along with MathBook XML. If not, see . + + + + + + + + + + + + +
+ + +
+
+ diff --git a/xsl/pretext-latex-common.xsl b/xsl/pretext-latex-common.xsl index b253bc80d9..aa03ef1758 100644 --- a/xsl/pretext-latex-common.xsl +++ b/xsl/pretext-latex-common.xsl @@ -64,7 +64,6 @@ along with MathBook XML. If not, see . - @@ -1159,6 +1158,20 @@ along with MathBook XML. If not, see . + + %% Veil support (PreTeXt) + \usepackage[normalem]{ulem} + \usepackage{xcolor} + + + % \newif\ifPTXVeilRevealInPrint % future publisher-driven boolean + % \PTXVeilRevealInPrintfalse % default could be set in publisher later + + + \newcommand{\PTXveil}[1]{\uline{#1}} + + \newcommand{\PTXveilblock}[1]{#1} + %% A character like a tilde, but different @@ -2639,17 +2652,16 @@ along with MathBook XML. If not, see . - - - - - \par\rule{\workspacestrutwidth}{ - - }% - + + + + + \par\rule{\workspacestrutwidth}{ + + }% + - - + @@ -2658,12 +2670,35 @@ along with MathBook XML. If not, see . - - - + + + + + + + + PTX:WARNING: Veil inside math is not supported in LaTeX; content will be printed as-is. + + + + + + + + + \PTXveilblock{ + + } + + + + \PTXveil{ + + } + + -