polish(pres_mgmt): dark-mode token cleanup on agree/consent forms + style guide update

Replace all forbidden hardcoded colors (red/green bg, text-red-*, text-green-*)
with Skeleton semantic tokens (error/success) so forms render correctly in dark mode.
Update agreement text wrapper from bg-white/dark:bg-gray-900 to bg-surface-50-950.
Document Flowbite Svelte Modal standard pattern (incl. note that classes.footer
padding override does not work in current version).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-23 17:56:29 -04:00
parent 7e255a7845
commit 7c129d3237
5 changed files with 78 additions and 32 deletions

View File

@@ -277,7 +277,47 @@ $events_sess.pres_mgmt.session_qr_url[$lq__obj.id] = result; // ← URL string
--- ---
## 12. Known Issues & Workarounds ## 12. Flowbite Svelte Modal — Standard Usage
**LLM docs:** [flowbite-svelte.com/llm/components/modal.md](https://flowbite-svelte.com/llm/components/modal.md)
All consent/agreement modals in pres_mgmt use this pattern. Do not deviate.
```svelte
<Modal
title="Person Name — Agreement Title"
bind:open={$store.show_modal__thing}
autoclose={false}
placement="top-center"
size="lg">
<YourFormComponent {prop} />
{#snippet footer()}
<div class="w-full text-center">
<button
type="button"
onclick={() => ($store.show_modal__thing = false)}
class="btn preset-tonal-warning border border-warning-500">
<X size="1em" class="mr-1" />
Close
</button>
</div>
{/snippet}
</Modal>
```
**Rules:**
- `classes` prop, not deprecated `bodyClass`/`headerClass`/`footerClass`
- **`classes={{ footer: '...' }}` does NOT override footer padding** in the current Flowbite Svelte version — the default `p-4 md:p-5` applies regardless
- `autoclose={false}` — prevents backdrop click from dismissing the dialog
- `placement="top-center"` — keeps long forms near the top so content is immediately visible
- Scrolling inside a long body is **automatic** — never add `max-h` or `overflow` to the body
- The modal title should include the person's name so the inner component doesn't need a redundant `<h2>`
---
## 13. Known Issues & Workarounds
### `btn` + `preset-filled-*` resolves to transparent inside `card` components ### `btn` + `preset-filled-*` resolves to transparent inside `card` components

View File

@@ -156,12 +156,12 @@ async function handle_update__event_presenter({
{#if $lq__event_presenter_obj} {#if $lq__event_presenter_obj}
{#if !$lq__event_presenter_obj?.agree} {#if !$lq__event_presenter_obj?.agree}
<div class="text-center text-red-500"> <div class="text-center text-error-700-300">
<div class="text-red-500"> <div class="">
<X size="1em" class="m-1 text-red-500" /> <X size="1.3em" class="text-error-700-300" />
Not Yet Agreed Not Yet Agreed
</div> </div>
<div class="rounded-md border border-red-200 bg-red-100 p-4"> <div class="rounded-md border border-error-300-700 preset-tonal-error p-4">
Waiting for agreement to the Guest Speaker Consent and Release Waiting for agreement to the Guest Speaker Consent and Release
and Terms and Conditions before you can move on. Please review and Terms and Conditions before you can move on. Please review
and mark as agreed below. and mark as agreed below.
@@ -170,7 +170,7 @@ async function handle_update__event_presenter({
{/if} {/if}
<div <div
class="border-surface-200-800 prose dark:prose-invert max-w-none space-y-4 rounded-lg border bg-white p-4 dark:bg-gray-900"> class="border-surface-200-800 prose dark:prose-invert max-w-none space-y-4 rounded-lg border bg-surface-50-950 text-surface-900-100 p-4">
<Element_data_store <Element_data_store
ds_code="event_presenter_agree_text" ds_code="event_presenter_agree_text"
ds_type="html" ds_type="html"
@@ -178,17 +178,17 @@ async function handle_update__event_presenter({
</div> </div>
<section <section
class="space-y-2 rounded-md border text-lg" class="space-y-2 rounded-lg border-2 text-lg p-2"
class:border-red-200={!$lq__event_presenter_obj?.agree} class:border-warning-300-700={!$lq__event_presenter_obj?.agree}
class:bg-red-100={!$lq__event_presenter_obj?.agree} class:preset-filled-surface-400-600={!$lq__event_presenter_obj?.agree}
class:border-green-200={$lq__event_presenter_obj?.agree} class:border-success-300={$lq__event_presenter_obj?.agree}
class:bg-green-50={$lq__event_presenter_obj?.agree}> class:preset-tonal-success={$lq__event_presenter_obj?.agree}>
<!-- Highlight the persons name, email, and that whole line. --> <!-- Highlight the persons name, email, and that whole line. -->
<p class="rounded-t-md p-2 text-lg" <p class="rounded-md p-2 text-lg"
class:preset-tonal-warning={!$lq__event_presenter_obj?.agree} class:preset-tonal-warning={!$lq__event_presenter_obj?.agree}
class:preset-tonal-success={$lq__event_presenter_obj?.agree}> class:preset-tonal-success={$lq__event_presenter_obj?.agree}>
{#if $lq__event_presenter_obj?.agree} {#if $lq__event_presenter_obj?.agree}
<Check size="1em" class="mr-1 inline text-green-700" /> <Check size="1em" class="mr-1 inline text-success-700" />
{/if} {/if}
<strong <strong
>{$lq__event_presenter_obj.full_name} ({$lq__event_presenter_obj.email})</strong> >{$lq__event_presenter_obj.full_name} ({$lq__event_presenter_obj.email})</strong>
@@ -275,8 +275,10 @@ async function handle_update__event_presenter({
onclick={() => { onclick={() => {
console.log('*** Save button clicked ***'); console.log('*** Save button clicked ***');
}} }}
class="btn btn-md preset-tonal-warning border-warning-500 hover:preset-filled-secondary-500 m-2 border"> class="btn btn-md
<Check size="1em" class="m-1 text-orange-500" /> preset-filled-secondary-50-950 preset-outlined-secondary-300-700
hover:preset-filled-secondary-400-600 m-2">
<Check size="1em" class="m-1 text-orange-700-300" />
Save Opt-Out? Save Opt-Out?
{#await ae_promises.update__event_presenter_obj} {#await ae_promises.update__event_presenter_obj}
@@ -313,7 +315,7 @@ async function handle_update__event_presenter({
{#if !$lq__event_presenter_obj?.agree} {#if !$lq__event_presenter_obj?.agree}
<div> <div>
Not Agreed: Not Agreed:
<X size="1em" class="m-1 text-red-500" /> <X size="1em" class="m-1 text-error-500" />
<!-- <span class="fas fa-question text-red-500 m-1"></span> --> <!-- <span class="fas fa-question text-red-500 m-1"></span> -->
</div> </div>
<div> <div>
@@ -323,7 +325,7 @@ async function handle_update__event_presenter({
{:else} {:else}
<div> <div>
Agreed: Agreed:
<Check size="1em" class="m-1 text-green-500" /> <Check size="1em" class="m-1 text-success-500" />
Marked as agreed Marked as agreed
</div> </div>
{/if} {/if}
@@ -372,7 +374,9 @@ async function handle_update__event_presenter({
'saved'; 'saved';
}); });
}} }}
class="btn btn-lg preset-tonal-primary border-primary-500 hover:preset-filled-success-500 m-2 border"> class="btn btn-lg preset-filled-primary-100-900
preset-outlined-primary-400-600
hover:preset-filled-success-400-600 m-2">
<Check size="1em" class="m-1 text-orange-500" /> <Check size="1em" class="m-1 text-orange-500" />
Mark as agreed? Mark as agreed?

View File

@@ -298,7 +298,8 @@ if (!$events_sess.pres_mgmt) $events_sess.pres_mgmt = {};
bind:open={$events_sess.pres_mgmt.show_modal__presenter_agree} bind:open={$events_sess.pres_mgmt.show_modal__presenter_agree}
autoclose={false} autoclose={false}
placement="top-center" placement="top-center"
size="lg"> size="lg"
>
{@const FormAgreeComp = Comp_event_presenter_form_agree as any} {@const FormAgreeComp = Comp_event_presenter_form_agree as any}
<FormAgreeComp {lq__event_presenter_obj} /> <FormAgreeComp {lq__event_presenter_obj} />
{#snippet footer()} {#snippet footer()}

View File

@@ -128,12 +128,12 @@ async function handle_submit_form(event: SubmitEvent) {
{#if lq__event_session_obj} {#if lq__event_session_obj}
{#if !lq__event_session_obj?.poc_agree} {#if !lq__event_session_obj?.poc_agree}
<div class="text-center text-red-500"> <div class="text-center text-error-500">
<div class="text-red-500"> <div class="text-error-500">
<X size="1em" class="m-1 text-red-500" /> <X size="1em" class="m-1 text-error-500" />
Not Yet Agreed Not Yet Agreed
</div> </div>
<div class="rounded-md border border-red-200 bg-red-100 p-4"> <div class="rounded-md border border-error-300 bg-error-100 p-4">
Waiting for agreement to the {pres_mgmt_loc.current.label__session_poc_name} Consent and Release and Terms and Conditions Waiting for agreement to the {pres_mgmt_loc.current.label__session_poc_name} Consent and Release and Terms and Conditions
before you can move on. Please review and mark as agreed below. before you can move on. Please review and mark as agreed below.
</div> </div>
@@ -141,7 +141,7 @@ async function handle_submit_form(event: SubmitEvent) {
{/if} {/if}
<div <div
class="border-surface-200-800 prose dark:prose-invert max-w-none space-y-4 rounded-lg border bg-white p-4 dark:bg-gray-900"> class="border-surface-200-800 prose dark:prose-invert max-w-none space-y-4 rounded-lg border bg-surface-50-950 text-surface-900-100 p-4">
<Element_data_store <Element_data_store
ds_code="event_session_poc_agree_text" ds_code="event_session_poc_agree_text"
ds_type="html" ds_type="html"
@@ -150,16 +150,16 @@ async function handle_submit_form(event: SubmitEvent) {
<section <section
class="space-y-2 rounded-md border text-lg" class="space-y-2 rounded-md border text-lg"
class:border-red-200={!lq__event_session_obj?.poc_agree} class:border-error-300={!lq__event_session_obj?.poc_agree}
class:bg-red-100={!lq__event_session_obj?.poc_agree} class:bg-error-100={!lq__event_session_obj?.poc_agree}
class:border-green-200={lq__event_session_obj?.poc_agree} class:border-success-300={lq__event_session_obj?.poc_agree}
class:bg-green-50={lq__event_session_obj?.poc_agree}> class:bg-success-100={lq__event_session_obj?.poc_agree}>
<!-- Highlight the persons name, email, and that whole line. --> <!-- Highlight the persons name, email, and that whole line. -->
<p class="rounded-t-md p-2 text-lg" <p class="rounded-t-md p-2 text-lg"
class:preset-tonal-warning={!lq__event_session_obj?.poc_agree} class:preset-tonal-warning={!lq__event_session_obj?.poc_agree}
class:preset-tonal-success={lq__event_session_obj?.poc_agree}> class:preset-tonal-success={lq__event_session_obj?.poc_agree}>
{#if lq__event_session_obj?.poc_agree} {#if lq__event_session_obj?.poc_agree}
<Check size="1em" class="mr-1 inline text-green-700" /> <Check size="1em" class="mr-1 inline text-success-700" />
{/if} {/if}
<strong <strong
>{lq__event_session_obj.poc_person_full_name} ({lq__event_session_obj.poc_person_primary_email})</strong> >{lq__event_session_obj.poc_person_full_name} ({lq__event_session_obj.poc_person_primary_email})</strong>
@@ -281,7 +281,7 @@ async function handle_submit_form(event: SubmitEvent) {
{#if !lq__event_session_obj?.poc_agree} {#if !lq__event_session_obj?.poc_agree}
<div> <div>
Not Agreed: Not Agreed:
<X size="1em" class="m-1 text-red-500" /> <X size="1em" class="m-1 text-error-500" />
<!-- <span class="fas fa-question text-red-500 m-1"></span> --> <!-- <span class="fas fa-question text-red-500 m-1"></span> -->
</div> </div>
<div> <div>
@@ -291,7 +291,7 @@ async function handle_submit_form(event: SubmitEvent) {
{:else} {:else}
<div> <div>
Agreed: Agreed:
<Check size="1em" class="m-1 text-green-500" /> <Check size="1em" class="m-1 text-success-500" />
Marked as agreed Marked as agreed
</div> </div>
{/if} {/if}

View File

@@ -534,7 +534,8 @@ async function send_poc_email_link() {
bind:open={$events_sess.pres_mgmt.show_modal__session_poc_agree} bind:open={$events_sess.pres_mgmt.show_modal__session_poc_agree}
autoclose={false} autoclose={false}
placement="top-center" placement="top-center"
size="lg"> size="lg"
>
<Comp_event_session_poc_form_agree <Comp_event_session_poc_form_agree
lq__event_session_obj={$lq__event_session_obj} /> lq__event_session_obj={$lq__event_session_obj} />
{#snippet footer()} {#snippet footer()}