221 lines
5.5 KiB
Svelte
221 lines
5.5 KiB
Svelte
|
|
<script lang="ts">
|
||
|
|
type Props = {
|
||
|
|
entries: {
|
||
|
|
id: string;
|
||
|
|
text: string;
|
||
|
|
possibleChoices: {
|
||
|
|
id: string;
|
||
|
|
text: string;
|
||
|
|
isSelected: boolean;
|
||
|
|
}[];
|
||
|
|
}[];
|
||
|
|
};
|
||
|
|
|
||
|
|
const { entries }: Props = $props();
|
||
|
|
|
||
|
|
function toParagraphs(text: string): string[] {
|
||
|
|
return text
|
||
|
|
.split(/\n\s*\n/g)
|
||
|
|
.map((paragraph) => paragraph.trim())
|
||
|
|
.filter(Boolean);
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
{#if entries.length > 0}
|
||
|
|
<section class="previous-entries" aria-label="Previous story entries">
|
||
|
|
<header class="previous-entries__header">
|
||
|
|
<h2 class="previous-entries__title">Previous entries</h2>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<ol class="previous-entries__list">
|
||
|
|
{#each entries as entry, index (entry.id)}
|
||
|
|
<li class="previous-entries__item">
|
||
|
|
<article class="entry-card" aria-label={`Entry ${index + 1}`}>
|
||
|
|
<header class="entry-card__header">
|
||
|
|
<p class="entry-card__index">Entry {String(index + 1).padStart(2, '0')}</p>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<div class="entry-card__body">
|
||
|
|
{#each toParagraphs(entry.text) as paragraph, paragraphIndex (paragraphIndex)}
|
||
|
|
<p class="entry-card__paragraph">{paragraph}</p>
|
||
|
|
{/each}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{#if entry.possibleChoices.length > 0}
|
||
|
|
<footer class="entry-card__choices">
|
||
|
|
<p class="entry-card__choices-label">Possible choices</p>
|
||
|
|
<ul class="entry-card__choices-list" aria-label="Choices for this entry">
|
||
|
|
{#each entry.possibleChoices as choice, choiceIndex (choice.id)}
|
||
|
|
<li class="entry-card__choice" class:entry-card__choice--selected={choice.isSelected}>
|
||
|
|
<span class="entry-card__choice-index" aria-hidden="true"
|
||
|
|
>{String(choiceIndex + 1).padStart(2, '0')}</span
|
||
|
|
>
|
||
|
|
<span class="entry-card__choice-text">{choice.text}</span>
|
||
|
|
{#if choice.isSelected}
|
||
|
|
<span class="entry-card__choice-state">Selected</span>
|
||
|
|
{/if}
|
||
|
|
</li>
|
||
|
|
{/each}
|
||
|
|
</ul>
|
||
|
|
</footer>
|
||
|
|
{/if}
|
||
|
|
</article>
|
||
|
|
</li>
|
||
|
|
{/each}
|
||
|
|
</ol>
|
||
|
|
</section>
|
||
|
|
{/if}
|
||
|
|
|
||
|
|
<style>
|
||
|
|
.previous-entries {
|
||
|
|
--previous-surface: var(--color-surface-container-low);
|
||
|
|
--previous-surface-elevated: var(--color-surface-container-lowest);
|
||
|
|
max-width: 88rem;
|
||
|
|
border-radius: var(--radius-xl);
|
||
|
|
}
|
||
|
|
|
||
|
|
.previous-entries__header {
|
||
|
|
margin-bottom: var(--space-4);
|
||
|
|
}
|
||
|
|
|
||
|
|
.previous-entries__title {
|
||
|
|
margin: var(--space-1) 0 0;
|
||
|
|
font-family: var(--font-display);
|
||
|
|
font-size: clamp(1.3rem, 1.12rem + 0.85vw, 1.9rem);
|
||
|
|
line-height: 1.15;
|
||
|
|
color: var(--color-on-surface);
|
||
|
|
}
|
||
|
|
|
||
|
|
.previous-entries__list {
|
||
|
|
list-style: none;
|
||
|
|
padding: 0;
|
||
|
|
margin: 0;
|
||
|
|
display: grid;
|
||
|
|
gap: var(--space-3);
|
||
|
|
grid-template-columns: 1fr;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card {
|
||
|
|
padding: clamp(0.9rem, 0.8rem + 0.7vw, 1.4rem);
|
||
|
|
border-radius: var(--radius-lg);
|
||
|
|
background-color: var(--previous-surface-elevated);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__header {
|
||
|
|
margin-bottom: var(--space-2);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__index {
|
||
|
|
margin: 0;
|
||
|
|
font-family: var(--font-label);
|
||
|
|
font-size: var(--text-label-md);
|
||
|
|
font-weight: var(--weight-semibold);
|
||
|
|
letter-spacing: 0.08em;
|
||
|
|
text-transform: uppercase;
|
||
|
|
color: color-mix(in srgb, var(--color-on-surface) 72%, transparent);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__body::-webkit-scrollbar {
|
||
|
|
width: 0.65rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__body::-webkit-scrollbar-track {
|
||
|
|
background: transparent;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__body::-webkit-scrollbar-thumb {
|
||
|
|
background-color: color-mix(in srgb, var(--colour-yellow-300) 26%, transparent);
|
||
|
|
border: 0.16rem solid transparent;
|
||
|
|
border-radius: var(--radius-full);
|
||
|
|
background-clip: content-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__paragraph {
|
||
|
|
font-family: var(--font-body);
|
||
|
|
font-size: clamp(1rem, 0.97rem + 0.2vw, 1.12rem);
|
||
|
|
line-height: var(--leading-loose);
|
||
|
|
color: var(--color-on-surface);
|
||
|
|
text-wrap: pretty;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__paragraph + .entry-card__paragraph {
|
||
|
|
margin-top: var(--space-3);
|
||
|
|
padding-top: var(--space-3);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choices {
|
||
|
|
margin-top: var(--space-3);
|
||
|
|
padding-top: var(--space-2);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choices-label {
|
||
|
|
margin: 0 0 var(--space-2);
|
||
|
|
font-family: var(--font-label);
|
||
|
|
font-size: var(--text-label-md);
|
||
|
|
font-weight: var(--weight-medium);
|
||
|
|
letter-spacing: var(--tracking-wide);
|
||
|
|
text-transform: uppercase;
|
||
|
|
color: color-mix(in srgb, var(--color-on-surface) 72%, transparent);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choices-list {
|
||
|
|
list-style: none;
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
display: grid;
|
||
|
|
gap: var(--space-2);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: auto 1fr auto;
|
||
|
|
align-items: start;
|
||
|
|
gap: var(--space-2);
|
||
|
|
padding: var(--space-2);
|
||
|
|
border-radius: var(--radius-md);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice-index {
|
||
|
|
font-family: var(--font-label);
|
||
|
|
font-size: var(--text-label-md);
|
||
|
|
font-weight: var(--weight-medium);
|
||
|
|
letter-spacing: var(--tracking-wide);
|
||
|
|
color: color-mix(in srgb, var(--color-on-surface) 62%, transparent);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice-text {
|
||
|
|
font-family: var(--font-body);
|
||
|
|
font-size: var(--text-body-lg);
|
||
|
|
line-height: var(--leading-relaxed);
|
||
|
|
color: color-mix(in srgb, var(--color-on-surface) 84%, transparent);
|
||
|
|
text-wrap: pretty;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice-state {
|
||
|
|
font-family: var(--font-label);
|
||
|
|
font-size: var(--text-label-md);
|
||
|
|
font-weight: var(--weight-medium);
|
||
|
|
letter-spacing: var(--tracking-wide);
|
||
|
|
text-transform: uppercase;
|
||
|
|
color: var(--color-primary);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice--selected {
|
||
|
|
background-color: color-mix(in srgb, var(--color-primary-container) 56%, transparent);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card__choice--selected .entry-card__choice-text {
|
||
|
|
color: var(--color-on-surface);
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (max-width: 42rem) {
|
||
|
|
.previous-entries {
|
||
|
|
padding: var(--space-2);
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry-card {
|
||
|
|
padding: var(--space-3);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|