Rain on the ridge
The trail turned to run-off an hour before the pass, and the map stopped agreeing with the ground somewhere after the second creek.
We waited it out under a slab of granite and watched the valley fill with cloud from the top down.
Three persistent stores in a global scope are the whole preferences layer. The toolbar writes them and the article reads them, and neither one knows the other exists. persistent keeps the choice across reloads, and setting color-scheme on the article is enough for its light-dark() colors to repaint.
Declare the stores once near the top of the page and anything below can read the same settings.
The trail turned to run-off an hour before the pass, and the map stopped agreeing with the ground somewhere after the second creek.
We waited it out under a slab of granite and watched the valley fill with cloud from the top down.
The following example assumes that you have imported the component and set up the theme.
<sv-ui-state id="reading-prefs" global>3 collapsed lines
<sv-store name="$scheme" persistent value="light"></sv-store> <sv-store type="number" name="$scale" persistent value="100"></sv-store> <sv-store type="number" name="$measure" persistent value="30"></sv-store></sv-ui-state>
<div class="reader">39 collapsed lines
<div class="reader-bar"> <div class="reader-schemes"> <button type="button" bind-class-toggle="is-active:$scheme === 'light'" bind-event="click:$scheme('light')">Light</button> <button type="button" bind-class-toggle="is-active:$scheme === 'dark'" bind-event="click:$scheme('dark')">Dark</button> </div>
<label class="reader-knob"> Text <input type="range" bind-event="input.passive:$scale(+EVENT.target.value)" bind-prop="value:$scale" max="130" min="90" step="10" /> </label>
<label class="reader-knob"> Width <input type="range" bind-event="input.passive:$measure(+EVENT.target.value)" bind-prop="value:$measure" max="42" min="22" step="2" /> </label> </div>
<article class="reader-article" bind-style="color-scheme:$scheme; font-size:$scale + '%'; max-inline-size:$measure + 'rem'"> <h4>Rain on the ridge</h4> <p> The trail turned to run-off an hour before the pass, and the map stopped agreeing with the ground somewhere after the second creek. </p> <p>We waited it out under a slab of granite and watched the valley fill with cloud from the top down.</p> </article></div>
<style>69 collapsed lines
.reader { display: grid; gap: 1em; justify-items: center; padding-block: 1em;
.reader-bar { display: flex; flex-wrap: wrap; gap: 1em; align-items: center; justify-content: center; }
.reader-schemes { display: flex; gap: 0.3em;
button { padding: 0.35em 0.8em; font: inherit; font-size: 0.85em; color: var(--sv-gray-3); cursor: pointer; background-color: var(--sv-gray-6); border: var(--sv-bdr-sz-sm) solid transparent; border-radius: var(--sv-bdr-rad-sm);
&.is-active { color: var(--sv-gray-0); border-color: var(--sv-accent); } } }
.reader-knob { display: flex; gap: 0.5em; align-items: center; font-size: 0.85em; color: var(--sv-gray-3);
input { inline-size: 7rem; accent-color: var(--sv-accent); } }
.reader-article { padding: 1.2em 1.4em; color: light-dark(#22222a, #e6e6ea); background-color: light-dark(#fcfcfe, #16161a); border-radius: var(--sv-bdr-rad-md);
h4 { margin: 0 0 0.6em; font-size: 1.1em; }
p { margin: 0 0 0.6em; line-height: 1.6; }
p:last-child { margin-block-end: 0; } } }</style>