faith: use identical hero card for details and calendar overview
This commit is contained in:
@@ -0,0 +1,292 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { CalendarDay } from '$lib/calendarTypes';
|
||||||
|
import {
|
||||||
|
formatLongDate,
|
||||||
|
rankEmphasis,
|
||||||
|
humanizePsalterWeek,
|
||||||
|
humanizeSundayCycle,
|
||||||
|
t,
|
||||||
|
t1962,
|
||||||
|
type CalendarLang
|
||||||
|
} from './calendarI18n';
|
||||||
|
import { litBg, litInk } from './calendarColors';
|
||||||
|
|
||||||
|
let {
|
||||||
|
day,
|
||||||
|
lang,
|
||||||
|
todayIso,
|
||||||
|
href
|
||||||
|
}: {
|
||||||
|
day: CalendarDay;
|
||||||
|
lang: CalendarLang;
|
||||||
|
todayIso: string;
|
||||||
|
href?: string;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
|
const color = $derived(day.colorKeys[0] ?? 'GREEN');
|
||||||
|
const isToday = $derived(day.iso === todayIso);
|
||||||
|
const rankEmph = $derived(rankEmphasis(day.rank));
|
||||||
|
const rankNum = $derived(
|
||||||
|
rankEmph === 3 ? 'I' : rankEmph === 2 ? 'II' : rankEmph === 1 ? 'III' : 'IV'
|
||||||
|
);
|
||||||
|
|
||||||
|
function firstOr(arr: string[], fallback = ''): string {
|
||||||
|
return arr && arr.length ? arr[0] : fallback;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet card()}
|
||||||
|
<section
|
||||||
|
class="hero-banner"
|
||||||
|
style="background: {litBg(color)}; color: {litInk(color)}"
|
||||||
|
>
|
||||||
|
<span class="hc-rank" aria-hidden="true">{rankNum}</span>
|
||||||
|
<div class="hc-date">
|
||||||
|
{#if isToday}{t('today', lang)} · {/if}{formatLongDate(day.iso, lang)}
|
||||||
|
</div>
|
||||||
|
<h2 class="hc-name">{day.name}</h2>
|
||||||
|
<div class="hc-tags">
|
||||||
|
{#if day.rankName}
|
||||||
|
<span class="hc-tag">{day.rankName}</span>
|
||||||
|
{/if}
|
||||||
|
{#if day.colorNames.length}
|
||||||
|
<span class="hc-tag">{firstOr(day.colorNames)}</span>
|
||||||
|
{/if}
|
||||||
|
{#if day.seasonNames.length}
|
||||||
|
<span class="hc-tag">{firstOr(day.seasonNames)}</span>
|
||||||
|
{/if}
|
||||||
|
{#if day.psalterWeek}
|
||||||
|
<span class="hc-tag">{t('psalterWeek', lang)}: {humanizePsalterWeek(day.psalterWeek, lang)}</span>
|
||||||
|
{/if}
|
||||||
|
{#if day.sundayCycle}
|
||||||
|
<span class="hc-tag">{t('cycle', lang)}: {humanizeSundayCycle(day.sundayCycle)}</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if day.rite1962 && day.rite1962.commemorations.length}
|
||||||
|
<div class="hc-commems">
|
||||||
|
<div class="hc-commems-head">
|
||||||
|
<svg class="hc-commems-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
|
||||||
|
<span class="hc-commems-title">{t1962('commemorations', lang)}</span>
|
||||||
|
</div>
|
||||||
|
<div class="hc-commems-list">
|
||||||
|
{#each day.rite1962.commemorations as c (c.id)}
|
||||||
|
<span class="hc-commem">{c.name}</span>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if day.rite1962?.stationChurches?.length}
|
||||||
|
<div class="hc-stations">
|
||||||
|
<svg class="hc-stations-label" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 9h4"/><path d="M12 7v5"/><path d="M14 22v-4a2 2 0 0 0-4 0v4"/><path d="M18 22V5l-6-3-6 3v17"/><path d="M4 10.5V22"/><path d="M20 10.5V22"/><path d="M22 22H2"/></svg>
|
||||||
|
<span class="hc-stations-text">
|
||||||
|
<span class="hc-stations-title">{t1962('stationChurch', lang)}:</span>
|
||||||
|
{#each day.rite1962.stationChurches as s, i (s.key + (s.mass ?? ''))}
|
||||||
|
{#if i > 0}<span class="hc-stations-sep"> · </span>{/if}<span class="hc-station-name">{s.name}</span>{#if s.mass}<span class="hc-station-mass"> ({s.mass.replace(/_/g, ' ')})</span>{/if}
|
||||||
|
{/each}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if href}
|
||||||
|
<svg class="hc-chevron" width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{#if href}
|
||||||
|
<a class="hero-link" {href} aria-label={day.name}>
|
||||||
|
{@render card()}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
{@render card()}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.hero-link {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
.hero-banner {
|
||||||
|
position: relative;
|
||||||
|
border-radius: var(--radius-card);
|
||||||
|
padding: 2rem 2.2rem 3rem;
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform var(--transition-normal), box-shadow var(--transition-normal),
|
||||||
|
background 650ms cubic-bezier(0.33, 1, 0.68, 1),
|
||||||
|
color 650ms cubic-bezier(0.33, 1, 0.68, 1);
|
||||||
|
}
|
||||||
|
.hero-banner::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 10% 110%, rgba(255, 255, 255, 0.14), transparent 45%),
|
||||||
|
radial-gradient(circle at 95% -10%, rgba(0, 0, 0, 0.12), transparent 45%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.hero-banner > * {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.hero-link:hover .hero-banner {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 14px 32px rgba(0, 0, 0, 0.22);
|
||||||
|
}
|
||||||
|
.hero-link:active .hero-banner {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
.hero-link:focus-visible .hero-banner {
|
||||||
|
outline: 3px solid var(--color-primary);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
.hc-rank {
|
||||||
|
position: absolute;
|
||||||
|
top: 1.2rem;
|
||||||
|
right: 1.4rem;
|
||||||
|
min-width: 2.9rem;
|
||||||
|
height: 2.9rem;
|
||||||
|
padding: 0 0.85rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: Georgia, 'Times New Roman', serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.28);
|
||||||
|
opacity: 0.88;
|
||||||
|
}
|
||||||
|
.hc-date {
|
||||||
|
font-size: 0.74rem;
|
||||||
|
letter-spacing: 0.16em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
opacity: 0.88;
|
||||||
|
margin-bottom: 0.6rem;
|
||||||
|
}
|
||||||
|
.hc-name {
|
||||||
|
font-size: clamp(1.4rem, 3vw, 2rem);
|
||||||
|
line-height: 1.12;
|
||||||
|
margin: 0 0 0.3rem;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.hc-tags {
|
||||||
|
margin-top: 0.9rem;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.hc-tag {
|
||||||
|
padding: 0.3rem 0.75rem;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
background: rgba(255, 255, 255, 0.22);
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.hc-commems {
|
||||||
|
margin-top: 1.4rem;
|
||||||
|
padding-top: 1.1rem;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.22);
|
||||||
|
}
|
||||||
|
.hc-commems-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
margin-bottom: 0.55rem;
|
||||||
|
}
|
||||||
|
.hc-commems-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
.hc-commems-title {
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
.hc-commems-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.4rem 0.6rem;
|
||||||
|
}
|
||||||
|
.hc-commem {
|
||||||
|
padding: 0.3rem 0.7rem;
|
||||||
|
border-radius: var(--radius-pill);
|
||||||
|
background: rgba(255, 255, 255, 0.18);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.22);
|
||||||
|
font-size: 0.82rem;
|
||||||
|
}
|
||||||
|
.hc-stations {
|
||||||
|
margin-top: 0.9rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.55rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
.hc-stations-label {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 0.1rem;
|
||||||
|
opacity: 0.78;
|
||||||
|
}
|
||||||
|
.hc-stations-title {
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
opacity: 0.85;
|
||||||
|
margin-right: 0.35rem;
|
||||||
|
}
|
||||||
|
.hc-station-name {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.hc-station-mass {
|
||||||
|
opacity: 0.75;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
.hc-stations-sep {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.hc-chevron {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1.2rem;
|
||||||
|
right: 1.5rem;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-6px);
|
||||||
|
transition: transform var(--transition-normal), opacity var(--transition-normal);
|
||||||
|
}
|
||||||
|
.hero-link:hover .hc-chevron,
|
||||||
|
.hero-link:focus-visible .hc-chevron {
|
||||||
|
opacity: 0.88;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.hero-banner {
|
||||||
|
padding: 1.5rem 1.4rem 2.2rem;
|
||||||
|
}
|
||||||
|
.hc-rank {
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
min-width: 1.9rem;
|
||||||
|
height: 1.9rem;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.hc-chevron {
|
||||||
|
bottom: 0.9rem;
|
||||||
|
right: 1.1rem;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+2
-208
@@ -6,13 +6,8 @@
|
|||||||
import {
|
import {
|
||||||
getMonthName,
|
getMonthName,
|
||||||
getWeekdayShort,
|
getWeekdayShort,
|
||||||
formatLongDate,
|
|
||||||
hexFor,
|
|
||||||
rankEmphasis,
|
rankEmphasis,
|
||||||
humanizePsalterWeek,
|
|
||||||
humanizeSundayCycle,
|
|
||||||
t,
|
t,
|
||||||
t1962,
|
|
||||||
dioceseLabel,
|
dioceseLabel,
|
||||||
DIOCESES_1962,
|
DIOCESES_1962,
|
||||||
DIOCESES_1969,
|
DIOCESES_1969,
|
||||||
@@ -22,6 +17,7 @@
|
|||||||
} from '../../../../calendarI18n';
|
} from '../../../../calendarI18n';
|
||||||
import { litBg, litInk, LIT_COLOR_VAR } from '../../../../calendarColors';
|
import { litBg, litInk, LIT_COLOR_VAR } from '../../../../calendarColors';
|
||||||
import RingView from './RingView.svelte';
|
import RingView from './RingView.svelte';
|
||||||
|
import HeroCard from '../../../../HeroCard.svelte';
|
||||||
|
|
||||||
let { data }: { data: PageData } = $props();
|
let { data }: { data: PageData } = $props();
|
||||||
|
|
||||||
@@ -134,10 +130,6 @@
|
|||||||
|
|
||||||
const pageTitle = $derived(t('calendar', lang));
|
const pageTitle = $derived(t('calendar', lang));
|
||||||
|
|
||||||
function firstOr(arr: string[], fallback = ''): string {
|
|
||||||
return arr && arr.length ? arr[0] : fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When switching rites we drop ?diocese because the ID spaces differ (1962 has
|
// When switching rites we drop ?diocese because the ID spaces differ (1962 has
|
||||||
// diocesan calendars, 1969 only "general" or "switzerland"). The server
|
// diocesan calendars, 1969 only "general" or "switzerland"). The server
|
||||||
// re-applies each rite's default if none is given.
|
// re-applies each rite's default if none is given.
|
||||||
@@ -214,56 +206,7 @@
|
|||||||
</aside>
|
</aside>
|
||||||
{/if}
|
{/if}
|
||||||
{#if hero}
|
{#if hero}
|
||||||
{@const heroColor = hero.colorKeys[0] ?? 'GREEN'}
|
<HeroCard day={hero} {lang} {todayIso} href={detailHref(hero.iso)} />
|
||||||
{@const heroIsToday = hero.iso === todayIso}
|
|
||||||
<a class="today-card-link" href={detailHref(hero.iso)} aria-label={hero.name}>
|
|
||||||
<section
|
|
||||||
class="today-banner"
|
|
||||||
style="background: {litBg(heroColor)}; color: {litInk(heroColor)}"
|
|
||||||
>
|
|
||||||
<span class="tc-cross" aria-hidden="true">✝</span>
|
|
||||||
<div class="tc-today">
|
|
||||||
{#if heroIsToday}{t('today', lang)} · {/if}{formatLongDate(hero.iso, lang)}
|
|
||||||
</div>
|
|
||||||
<h2 class="tc-name">{hero.name}</h2>
|
|
||||||
<div class="tc-tags">
|
|
||||||
{#if hero.rankName}
|
|
||||||
<span class="tc-tag">{hero.rankName}</span>
|
|
||||||
{/if}
|
|
||||||
{#if hero.colorNames.length}
|
|
||||||
<span class="tc-tag">{firstOr(hero.colorNames)}</span>
|
|
||||||
{/if}
|
|
||||||
{#if hero.seasonNames.length}
|
|
||||||
<span class="tc-tag">{firstOr(hero.seasonNames)}</span>
|
|
||||||
{/if}
|
|
||||||
{#if hero.psalterWeek}
|
|
||||||
<span class="tc-tag">{t('psalterWeek', lang)}: {humanizePsalterWeek(hero.psalterWeek, lang)}</span>
|
|
||||||
{/if}
|
|
||||||
{#if hero.sundayCycle}
|
|
||||||
<span class="tc-tag">{t('cycle', lang)}: {humanizeSundayCycle(hero.sundayCycle)}</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{#if hero.rite1962 && hero.rite1962.commemorations.length}
|
|
||||||
<div class="tc-commems">
|
|
||||||
{#each hero.rite1962.commemorations as c (c.id)}
|
|
||||||
<span class="tc-commem">{c.name}</span>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{#if hero.rite1962?.stationChurches?.length}
|
|
||||||
<div class="tc-stations">
|
|
||||||
<span class="tc-stations-label" aria-hidden="true">✦</span>
|
|
||||||
<span class="tc-stations-text">
|
|
||||||
<span class="tc-stations-title">{t1962('stationChurch', lang)}:</span>
|
|
||||||
{#each hero.rite1962.stationChurches as s, i (s.key + (s.mass ?? ''))}
|
|
||||||
{#if i > 0}<span class="tc-stations-sep"> · </span>{/if}<span class="tc-station-name">{s.name}</span>{#if s.mass}<span class="tc-station-mass"> ({s.mass.replace(/_/g, ' ')})</span>{/if}
|
|
||||||
{/each}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<span class="tc-arrow" aria-hidden="true">→</span>
|
|
||||||
</section>
|
|
||||||
</a>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Color legend + view switcher -->
|
<!-- Color legend + view switcher -->
|
||||||
@@ -577,155 +520,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====== Today banner (design handoff) ====== */
|
|
||||||
.today-card-link {
|
|
||||||
display: block;
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
.today-banner {
|
|
||||||
position: relative;
|
|
||||||
border-radius: var(--radius-card);
|
|
||||||
padding: 2rem 2.2rem;
|
|
||||||
box-shadow: var(--shadow-md);
|
|
||||||
overflow: hidden;
|
|
||||||
transition: transform var(--transition-normal), box-shadow var(--transition-normal),
|
|
||||||
background 650ms cubic-bezier(0.33, 1, 0.68, 1),
|
|
||||||
color 650ms cubic-bezier(0.33, 1, 0.68, 1);
|
|
||||||
}
|
|
||||||
.today-banner::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 10% 110%, rgba(255, 255, 255, 0.14), transparent 45%),
|
|
||||||
radial-gradient(circle at 95% -10%, rgba(0, 0, 0, 0.12), transparent 45%);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.today-banner > * {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.today-card-link:hover .today-banner {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 14px 32px rgba(0, 0, 0, 0.22);
|
|
||||||
}
|
|
||||||
.today-card-link:active .today-banner {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
.today-card-link:focus-visible .today-banner {
|
|
||||||
outline: 3px solid var(--color-primary);
|
|
||||||
outline-offset: 3px;
|
|
||||||
}
|
|
||||||
.tc-cross {
|
|
||||||
position: absolute;
|
|
||||||
top: 1.2rem;
|
|
||||||
right: 1.6rem;
|
|
||||||
font-size: 3.4rem;
|
|
||||||
line-height: 1;
|
|
||||||
opacity: 0.28;
|
|
||||||
font-family: serif;
|
|
||||||
}
|
|
||||||
.tc-today {
|
|
||||||
font-size: 0.74rem;
|
|
||||||
letter-spacing: 0.16em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 700;
|
|
||||||
opacity: 0.88;
|
|
||||||
margin-bottom: 0.6rem;
|
|
||||||
}
|
|
||||||
.tc-name {
|
|
||||||
font-size: clamp(1.4rem, 3vw, 2rem);
|
|
||||||
line-height: 1.12;
|
|
||||||
margin: 0 0 0.3rem;
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.tc-tags {
|
|
||||||
margin-top: 0.9rem;
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.tc-tag {
|
|
||||||
padding: 0.3rem 0.75rem;
|
|
||||||
border-radius: var(--radius-pill);
|
|
||||||
background: rgba(255, 255, 255, 0.22);
|
|
||||||
font-size: 0.72rem;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.06em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
.tc-commems {
|
|
||||||
margin-top: 1.4rem;
|
|
||||||
padding-top: 1.1rem;
|
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.22);
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.4rem 0.6rem;
|
|
||||||
}
|
|
||||||
.tc-commem {
|
|
||||||
padding: 0.3rem 0.7rem;
|
|
||||||
border-radius: var(--radius-pill);
|
|
||||||
background: rgba(255, 255, 255, 0.18);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.22);
|
|
||||||
font-size: 0.82rem;
|
|
||||||
}
|
|
||||||
.tc-stations {
|
|
||||||
margin-top: 0.9rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
gap: 0.55rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
line-height: 1.45;
|
|
||||||
}
|
|
||||||
.tc-stations-label {
|
|
||||||
font-size: 0.95rem;
|
|
||||||
opacity: 0.7;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.tc-stations-title {
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.03em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 0.72rem;
|
|
||||||
opacity: 0.85;
|
|
||||||
margin-right: 0.35rem;
|
|
||||||
}
|
|
||||||
.tc-station-name {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.tc-station-mass {
|
|
||||||
opacity: 0.75;
|
|
||||||
font-size: 0.78rem;
|
|
||||||
}
|
|
||||||
.tc-stations-sep {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
.tc-arrow {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1.1rem;
|
|
||||||
right: 1.4rem;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
font-weight: 300;
|
|
||||||
opacity: 0.55;
|
|
||||||
transition: transform var(--transition-normal), opacity var(--transition-normal);
|
|
||||||
}
|
|
||||||
.today-card-link:hover .tc-arrow {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateX(4px);
|
|
||||||
}
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.today-banner {
|
|
||||||
padding: 1.5rem 1.4rem;
|
|
||||||
}
|
|
||||||
.tc-cross {
|
|
||||||
font-size: 2.4rem;
|
|
||||||
top: 1rem;
|
|
||||||
right: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ====== View switcher + color legend ====== */
|
/* ====== View switcher + color legend ====== */
|
||||||
.overview-controls {
|
.overview-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
+6
-134
@@ -5,20 +5,12 @@
|
|||||||
formatLongDate,
|
formatLongDate,
|
||||||
getMonthName,
|
getMonthName,
|
||||||
hexFor,
|
hexFor,
|
||||||
humanizePsalterWeek,
|
|
||||||
humanizeSundayCycle,
|
|
||||||
properLabel,
|
properLabel,
|
||||||
t,
|
t,
|
||||||
t1962,
|
t1962,
|
||||||
type CalendarLang
|
type CalendarLang
|
||||||
} from '../../../../../calendarI18n';
|
} from '../../../../../calendarI18n';
|
||||||
|
import HeroCard from '../../../../../HeroCard.svelte';
|
||||||
function kindLabel(kind: 'tempora' | 'sancti', l: CalendarLang): string {
|
|
||||||
if (kind === 'tempora')
|
|
||||||
return l === 'de' ? 'Temporale' : l === 'la' ? 'Temporale' : 'Temporal';
|
|
||||||
return l === 'de' ? 'Sanktorale' : l === 'la' ? 'Sanctorale' : 'Sanctoral';
|
|
||||||
}
|
|
||||||
import { litBg, litInk } from '../../../../../calendarColors';
|
|
||||||
|
|
||||||
let { data }: { data: PageData } = $props();
|
let { data }: { data: PageData } = $props();
|
||||||
|
|
||||||
@@ -57,7 +49,6 @@
|
|||||||
const prevHref = $derived(shiftDay(-1));
|
const prevHref = $derived(shiftDay(-1));
|
||||||
const nextHref = $derived(shiftDay(1));
|
const nextHref = $derived(shiftDay(1));
|
||||||
|
|
||||||
const isToday = $derived(iso === todayIso);
|
|
||||||
const monthTitle = $derived(`${getMonthName(month, lang)} ${year}`);
|
const monthTitle = $derived(`${getMonthName(month, lang)} ${year}`);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -82,47 +73,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<header
|
<HeroCard {day} {lang} {todayIso} />
|
||||||
class="detail-hero"
|
|
||||||
style="background: {litBg(day.colorKeys[0])}; color: {litInk(day.colorKeys[0])}; --accent: {dayHex}"
|
|
||||||
>
|
|
||||||
<div class="hero-date">
|
|
||||||
{formatLongDate(iso, lang)}
|
|
||||||
{#if isToday}
|
|
||||||
<span class="today-pip">{t('today', lang)}</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<h1 class="hero-name">{day.name}</h1>
|
|
||||||
<div class="hero-tags">
|
|
||||||
{#if day.rankName}
|
|
||||||
<span class="tag tag-rank">{day.rankName}</span>
|
|
||||||
{/if}
|
|
||||||
{#if day.seasonNames.length}
|
|
||||||
<span class="tag tag-season">{day.seasonNames[0]}</span>
|
|
||||||
{/if}
|
|
||||||
{#if day.colorNames.length}
|
|
||||||
<span class="tag tag-color">
|
|
||||||
<span class="color-swatch" style="background: {dayHex}"></span>
|
|
||||||
{day.colorNames[0]}
|
|
||||||
</span>
|
|
||||||
{/if}
|
|
||||||
{#if day.psalterWeek}
|
|
||||||
<span class="tag">{t('psalterWeek', lang)}: {humanizePsalterWeek(day.psalterWeek, lang)}</span>
|
|
||||||
{/if}
|
|
||||||
{#if day.sundayCycle}
|
|
||||||
<span class="tag">{t('cycle', lang)}: {humanizeSundayCycle(day.sundayCycle)}</span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{#if day.rite1962}
|
{#if day.rite1962}
|
||||||
{@const d = day.rite1962}
|
{@const d = day.rite1962}
|
||||||
<section class="detail" style="--accent: {dayHex}">
|
<section class="detail" style="--accent: {dayHex}">
|
||||||
<dl class="detail-extras">
|
<dl class="detail-extras">
|
||||||
<div>
|
|
||||||
<dt>{t1962('source', lang)}</dt>
|
|
||||||
<dd>{kindLabel(d.kind, lang)}</dd>
|
|
||||||
</div>
|
|
||||||
{#if d.vigilOf}
|
{#if d.vigilOf}
|
||||||
<div>
|
<div>
|
||||||
<dt>{t1962('vigilOf', lang)}</dt>
|
<dt>{t1962('vigilOf', lang)}</dt>
|
||||||
@@ -154,21 +110,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if d.stationChurches?.length}
|
|
||||||
<div class="stations">
|
|
||||||
<h4>{t1962('stationChurch', lang)}</h4>
|
|
||||||
<ul>
|
|
||||||
{#each d.stationChurches as s (s.key + (s.mass ?? ''))}
|
|
||||||
<li>
|
|
||||||
<span class="station-name">{s.name}</span>
|
|
||||||
{#if s.mass}
|
|
||||||
<span class="station-mass">{s.mass.replace(/_/g, ' ')}</span>
|
|
||||||
{/if}
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{#if d.propers.length}
|
{#if d.propers.length}
|
||||||
<section class="propers">
|
<section class="propers">
|
||||||
<h4>{t1962('propers', lang)}</h4>
|
<h4>{t1962('propers', lang)}</h4>
|
||||||
@@ -278,62 +219,6 @@
|
|||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-hero {
|
|
||||||
border-radius: var(--radius-card);
|
|
||||||
padding: 1.5rem 1.75rem;
|
|
||||||
box-shadow: var(--shadow-md);
|
|
||||||
}
|
|
||||||
.hero-date {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
opacity: 0.85;
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
}
|
|
||||||
.today-pip {
|
|
||||||
font-size: 0.62rem;
|
|
||||||
letter-spacing: 0.14em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 700;
|
|
||||||
padding: 3px 8px;
|
|
||||||
border-radius: 100px;
|
|
||||||
background: rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
|
||||||
.hero-name {
|
|
||||||
margin: 0 0 0.75rem;
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
.hero-tags {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.4rem;
|
|
||||||
padding: 0.25rem 0.7rem;
|
|
||||||
background: rgba(0, 0, 0, 0.14);
|
|
||||||
color: inherit;
|
|
||||||
border-radius: var(--radius-pill);
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.tag-rank {
|
|
||||||
background: rgba(0, 0, 0, 0.22);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.color-swatch {
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail {
|
.detail {
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
border-radius: var(--radius-card);
|
border-radius: var(--radius-card);
|
||||||
@@ -366,7 +251,6 @@
|
|||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
.commems h4,
|
.commems h4,
|
||||||
.stations h4,
|
|
||||||
.propers h4 {
|
.propers h4 {
|
||||||
margin: 0.5rem 0 0.4rem;
|
margin: 0.5rem 0 0.4rem;
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
@@ -375,12 +259,10 @@
|
|||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.commems,
|
.commems {
|
||||||
.stations {
|
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
}
|
}
|
||||||
.commems ul,
|
.commems ul {
|
||||||
.stations ul {
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -388,8 +270,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.35rem;
|
gap: 0.35rem;
|
||||||
}
|
}
|
||||||
.commems li,
|
.commems li {
|
||||||
.stations li {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
@@ -398,19 +279,10 @@
|
|||||||
border-radius: var(--radius-sm, 6px);
|
border-radius: var(--radius-sm, 6px);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
.commem-name,
|
.commem-name {
|
||||||
.station-name {
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
.station-name {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.station-mass {
|
|
||||||
color: var(--color-text-tertiary);
|
|
||||||
font-size: 0.78rem;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.propers {
|
.propers {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user