diff --git a/plugins/story-blocks/shortcodes/FullBleedShortcode.php b/plugins/story-blocks/shortcodes/FullBleedShortcode.php
new file mode 100644
index 0000000..6664685
--- /dev/null
+++ b/plugins/story-blocks/shortcodes/FullBleedShortcode.php
@@ -0,0 +1,34 @@
+shortcode->getHandlers()->add('full-bleed', function (ShortcodeInterface $sc) {
+ $plugin = $this->grav['plugins']->getPlugin('story-blocks');
+ $page = $plugin ? $plugin->getCurrentPage() : null;
+
+ $imageName = htmlspecialchars($sc->getParameter('image', ''), ENT_QUOTES);
+ $alt = htmlspecialchars($sc->getParameter('alt', ''), ENT_QUOTES);
+ $caption = htmlspecialchars($sc->getParameter('caption', ''), ENT_QUOTES);
+ $credit = htmlspecialchars($sc->getParameter('credit', ''), ENT_QUOTES);
+ $imageUrl = ($page && $imageName) ? $page->url() . '/' . $imageName : $imageName;
+
+ $captionHtml = '';
+ if ($caption || $credit) {
+ $creditHtml = $credit ? ' · ' . $credit . '' : '';
+ $captionHtml = '' . $caption . $creditHtml . '';
+ }
+
+ return <<
+
+ {$captionHtml}
+
+HTML;
+ });
+ }
+}
diff --git a/plugins/story-blocks/shortcodes/ImageCaptionShortcode.php b/plugins/story-blocks/shortcodes/ImageCaptionShortcode.php
new file mode 100644
index 0000000..9848312
--- /dev/null
+++ b/plugins/story-blocks/shortcodes/ImageCaptionShortcode.php
@@ -0,0 +1,37 @@
+shortcode->getHandlers()->add('image-caption', function (ShortcodeInterface $sc) {
+ $plugin = $this->grav['plugins']->getPlugin('story-blocks');
+ $page = $plugin ? $plugin->getCurrentPage() : null;
+
+ $imageName = htmlspecialchars($sc->getParameter('image', ''), ENT_QUOTES);
+ $alt = htmlspecialchars($sc->getParameter('alt', ''), ENT_QUOTES);
+ $caption = htmlspecialchars($sc->getParameter('caption', ''), ENT_QUOTES);
+ $credit = htmlspecialchars($sc->getParameter('credit', ''), ENT_QUOTES);
+ $width = $sc->getParameter('width', 'column');
+ if (!in_array($width, ['column', 'full', 'bleed'])) $width = 'column';
+ $imageUrl = ($page && $imageName) ? $page->url() . '/' . $imageName : $imageName;
+
+ $widthClass = $width !== 'column' ? ' img-caption--' . $width : '';
+ $captionHtml = '';
+ if ($caption || $credit) {
+ $creditHtml = $credit ? ' · ' . $credit . '' : '';
+ $captionHtml = '' . $caption . $creditHtml . '';
+ }
+
+ return <<
+
+ {$captionHtml}
+
+HTML;
+ });
+ }
+}
diff --git a/themes/intotheeast/css/style.css b/themes/intotheeast/css/style.css
index 1b08180..732c2ec 100644
--- a/themes/intotheeast/css/style.css
+++ b/themes/intotheeast/css/style.css
@@ -1647,6 +1647,65 @@ body::after {
}
.pgallery__dot.is-active { background: var(--color-accent); }
+/* ── FullBleed shortcode ──────────────────────────────────── */
+.full-bleed {
+ width: 100vw;
+ left: 50%;
+ margin-left: -50vw;
+ position: relative;
+ margin-top: var(--space-16);
+ margin-bottom: var(--space-16);
+}
+.full-bleed__img {
+ width: 100%;
+ display: block;
+ max-height: 80vh;
+ object-fit: cover;
+}
+.full-bleed__caption {
+ text-align: center;
+ font-family: var(--font-ui);
+ font-size: var(--text-sm);
+ color: var(--color-ink-muted);
+ margin-top: var(--space-3);
+ padding: 0 var(--space-8);
+}
+.full-bleed__credit { font-style: italic; }
+
+/* ── ImageCaption shortcode ───────────────────────────────── */
+.img-caption {
+ margin-top: var(--space-12);
+ margin-bottom: var(--space-12);
+}
+.img-caption__img {
+ width: 100%;
+ display: block;
+ border-radius: var(--radius-sm);
+}
+.img-caption__text {
+ font-family: var(--font-ui);
+ font-size: var(--text-sm);
+ color: var(--color-ink-muted);
+ margin-top: var(--space-3);
+}
+.img-caption__credit { font-style: italic; }
+.img-caption--full {
+ width: calc(100% + var(--space-16));
+ margin-left: calc(var(--space-8) * -1);
+}
+.img-caption--full .img-caption__img { border-radius: 0; }
+.img-caption--bleed {
+ width: 100vw;
+ left: 50%;
+ margin-left: -50vw;
+ position: relative;
+}
+.img-caption--bleed .img-caption__img {
+ border-radius: 0;
+ max-height: 80vh;
+ object-fit: cover;
+}
+
/* ── Stories listing ──────────────────────────────────────── */
.stories-listing { padding: var(--space-10) 0; }
.stories-listing__heading {