ContentRows now delegates to BlockRenderer instead of maintaining its
own parallel if-else chain. Single source of truth for all block types.
Adds internal_component support (ContactFormComponent via /api/contact).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Palette: gray/zinc/slate/neutral → stein, red → fire, amber → erde,
sky → himmel, green → wald
- Footer: replaced raw rgb with stein tokens
- Radius: unified to rounded-xs across cards, buttons, inputs, pagination
- Buttons: .btn-primary/.btn-secondary now font-medium; added secondary
- Card hover: -translate-y-0.5 + shadow + wald-300 border
- Header active link: wald border-bottom + wald-700 text
- Mobile nav: bigger touch targets + wald active accent
- Pagination: prev/next text labels + wald-500 active state with
separated shape/color classes to avoid Tailwind conflicts
- Lead paragraph: scoped .markdown > p:first-child for top-level
MarkdownBlock only via [data-block-type="markdown"]
- Section dividers: subtle wald-200 gradient between content rows
- Global focus-visible ring (wald-500)
- Inline hex → palette tokens (Badge amber, Tag custom-color contrast)
- Font weights snapped to design system (300/400/500/600/700)
- transition-all → transition-colors where only color changes
- Removed em-dashes from user-visible templates
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Editor-controlled live-strommix card that surfaces what share of
electricity demand is currently covered by weather-dependent
renewables (Wind+Solar / Load), plus the conventional generation that
fills the gap, the cross-border saldo, and the day-ahead price (DE/FR
side-by-side). Status bucket + label + argument come from the CMS so
editors can iterate copy without a deploy.
- LiveStrommixBlockData type next to the other block-types.
- New `/api/strommix` aggregator route bundles four CMS external
collections (strommix_de, crossborder_de, price_de, price_fr) into a
single payload, computes the renewable + conventional sums and the
cross-border saldo (Σ flow_xx_gw, sign convention: + = export from
DE), surfaces stale-on-error flags from the CMS response headers.
Cache-control 5min so a single node only hits energy-charts once
per window.
- StrommixBlock.svelte renders the card: percentage, bucket label,
bucket argument (markdown), context row (conventional + saldo with
↑/↓ arrow), price row with optional FR comparison + negative-price
badge, footer with disclaimer + "Wie wird das berechnet?" link +
stale-data hint when the CMS served fallback. Re-polls every 5min
client-side; bucket thresholds + labels + arguments come from the
block instance so multiple placements can carry different copy.
- ContentRows.svelte dispatcher branch on `_type === "live_strommix"`.
Wired against `cms_content/_types/core/live_strommix.json5` (added in
the rustycms repo today). content_layout.row{1,2,3}Content already
allow the new block-type via the same commit on the CMS side.
New block for `youtube_video_gallery` CMS type. Carousel renders
2 iframes side-by-side on md+ (1 on mobile) with prev/next/dots; grid
shows YT thumbnails opening modal embeds. Description supports
markdown via marked; long URLs break with overflow-wrap:anywhere.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Introduced FilesBlockItem and FilesBlockData interfaces to support file handling in the CMS.
- Integrated FilesBlock component into ContentRows.svelte for rendering file blocks.
- Updated block type handling to include support for files, enhancing content versatility.
- Changed margin class from `my-6` to `mb-6` in ContentRows.svelte for consistent spacing.
- Updated PostCard.svelte to use `$derived` for post properties, enhancing reactivity.
- Refined DeadlineBannerBlock.svelte by removing unnecessary border classes and improving layout for better content alignment.
- Modified Button.svelte to support rendering children directly, enhancing flexibility.
- Added `tabindex="0"` to TabBar.svelte for improved accessibility.
- Fixed textarea closing tag in Textarea.svelte for proper HTML structure.
- Corrected span closing tag in Toggle.svelte for valid markup.
Skip container-custom py-8 wrapper for deadline_banner so the colored
bar spans the viewport. Banner ships its own inner container-custom
for content positioning.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Auto-mode deadline_banner now resolves to the next future event across
all calendar_items in the CMS instead of requiring a manually-curated
items[] pool. Server load hooks (+page.server.ts for /, /[...slug],
/post/[slug]) call resolveDeadlineBannerBlocks which fetches the
global calendar_item list once and attaches it as items[] when mode
is "auto" and items[] is not already resolved. Component logic
unchanged — it still picks the soonest future entry.
Also:
- cms.ts: getCalendarItems() bulk list fetcher
- PostOverviewBlock.svelte: design defaults to "cards" when value is
empty string (not just null/undefined) so existing entries with
design: "" render
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Introduced a new QuoteCarouselBlock component for displaying rotating quotes.
- Added QuoteCarouselBlockData interface to define the structure of the quote carousel data.
- Updated existing components and types to integrate the new quote carousel functionality.
- Enhanced blog-utils to support filtering posts by tags more effectively.
- Made various UI improvements in the Footer and PostCard components for better user experience.