Skip to content

feat: case study success story, immersive styled + revamped index listing page #119

Merged
oycyc merged 22 commits into
masterfrom
feat/case-study-success-story/immersive-mode
Jun 16, 2026
Merged

feat: case study success story, immersive styled + revamped index listing page #119
oycyc merged 22 commits into
masterfrom
feat/case-study-success-story/immersive-mode

Conversation

@oycyc

@oycyc oycyc commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Primary items in this PR:

  • "Immersive" style for the case study (MarketSpark)
  • The index listing page updated (https://masterpoint.io/case-studies/) -- will revamp even more when Fable comes back and we publish the Anysphere Cursor case study to give a more "featured" case study look
  • Will address CodeRabbit review (some are valid, but very trivial) in a separate PR

✅ Approval on Slack: https://masterpoint.slack.com/archives/C0B9UE13C05/p1781613401380519?thread_ts=1781286627.209939&cid=C0B9UE13C05

Summary by CodeRabbit

  • New Features

    • Immersive case-study visual system and SCSS (card-stack, gradients, photo overlays, dot-grid, typography, CTA)
    • New immersive shortcodes: csi-section, csi-split, csi-steps, csi-impact, csi-list, csi-testimonial
    • Optional logo parameter for case-study about blocks; improved link rendering and pullquote animation
  • Bug Fixes

    • Scoped styling to avoid layout bleed between immersive and modern pages
  • Chores

    • Removed legacy case-study shortcodes/templates and template preview page
  • Documentation

    • Expanded case-studies guide with immersive authoring, animation, and styling guidance

@oycyc oycyc requested a review from a team as a code owner June 5, 2026 22:13
@netlify

netlify Bot commented Jun 5, 2026

Copy link
Copy Markdown

Deploy Preview for masterpoint ready!

Name Link
🔨 Latest commit 2396849
🔍 Latest deploy log https://app.netlify.com/projects/masterpoint/deploys/6a314af48759150009307190
😎 Deploy Preview https://deploy-preview-119--masterpoint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 44
Accessibility: 86
Best Practices: 100
SEO: 79
PWA: 70
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a scoped "immersive" case-study layout: new scoped CSS, an immersive page layout, multiple csi-* shortcodes, MarketSpark immersive and article-style content, removal of several legacy cs-* shortcodes/styles, a render-link partial, and updated case-studies docs.

Changes

Immersive Case Study Layout System

Layer / File(s) Summary
Modern layout cleanup and enhancement
assets/css/custom.scss, layouts/shortcodes/cs-about.html, layouts/shortcodes/cs-pullquote.html
Removes deprecated .case-study-modern shortcode styles (cs-lockup, cs-figure, cs-stat-grid/cs-stat-card, cs-callout, cs-beforeafter/cs-pane, cs-todo). Adds optional logo parameter to cs-about shortcode for rendering a logo image. Adds AOS attributes to cs-pullquote.
Immersive layout CSS foundation
assets/css/custom.scss
Adds immersive palette variables ($csi-ink, $csi-ink-soft, $csi-link, $csi-line), gradient mixins, and scoped .case-study-immersive styling: card stack, section variants (light/pine/dark), .csi-prose typography, split helpers, steps, impact tiles, testimonials, and .csi-cta.
Immersive template infrastructure
layouts/case-studies/immersive.html, layouts/case-studies/_markup/render-link.html
New immersive layout reusing modern hero/stat strip and wrapping .Content in csi-* containers. Adds render-link partial that marks external links with target="_blank" and rel="noopener noreferrer". Injects optional CTA and shared partials.
Immersive shortcodes
layouts/shortcodes/csi-section.html, layouts/shortcodes/csi-split.html, layouts/shortcodes/csi-steps.html, layouts/shortcodes/csi-impact.html, layouts/shortcodes/csi-testimonial.html, layouts/shortcodes/csi-list.html
Adds parameterized shortcodes: narrative band (csi-section), split media/text (csi-split), numbered steps (csi-steps), impact/outcome tiles (csi-impact), testimonial band (csi-testimonial), and compact icon list (csi-list). Each parses args and renders markdowned inner content; some include AOS attributes.
MarketSpark immersive case study
content/case-studies/marketspark.md
Converts MarketSpark case study to layout: immersive, composes sections with csi-split/csi-section, uses csi-impact for impact/outcome tiles, and ends with csi-testimonial. Adds logo TODOs in frontmatter.
MarketSpark modern layout variant
content/case-studies/marketspark-article-style.md
Adds an article-style MarketSpark page using existing modern shortcodes (cs-about, cs-wins, cs-pullquote) as an alternative layout example.
Case study system documentation
docs/case-studies.md
Updates docs to document three-layout model (Legacy/Modern/Immersive), immersive authoring rules (scoping, variant rotation, TOC behavior), AOS motion guidance, and CSS debugging pointer. Includes updated shortcode authoring notes.

Sequence Diagram

sequenceDiagram
  participant Content as MarketSpark Content
  participant Template as layouts/case-studies/immersive.html
  participant Shortcodes as csi-* Shortcodes
  participant CSS as assets/css/custom.scss

  Content->>Template: page frontmatter (layout: immersive) + .Content
  Template->>Template: render hero / stat-strip (modern markup)
  Template->>Shortcodes: invoke `csi-split`, `csi-section`, `csi-impact`, `csi-testimonial`
  Shortcodes->>Shortcodes: parse args/blocks, RenderString inner markdown, add AOS attrs
  Shortcodes->>Template: emit HTML with `csi-*` classes
  Template->>CSS: page uses `.case-study-immersive` scope
  CSS->>CSS: apply palette, variants, split, cards, testimonials, CTA styles
  Template->>Template: append CTA (callout), footer, scripts
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Gowiem
  • gberenice
  • westonplatter
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main changes: adding a new case study success story with immersive styling and updating the index listing.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/case-study-success-story/immersive-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (2)
content/case-studies/marketspark-article-style.md (2)

2-2: TODO: Pending MarketSpark logo assets.

The TODO notes that proper logo variants (dark & light) are needed from MarketSpark. Once obtained, consider using the new logo parameter in the cs-about shortcode (lines 38-45) for consistent branding.

Do you want me to open a tracking issue for this TODO, or help generate placeholder content until the assets are received?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark-article-style.md` at line 2, Add a tracking
TODO and placeholder flow for the missing MarketSpark logo assets: open a
tracking issue that requests both dark and light logo files and links it in this
file, then update the cs-about shortcode usage (cs-about) to accept a new logo
parameter and set it to a placeholder SVG/PNG fallback until the real assets
arrive; once you get the provided dark & light files, replace the placeholders
by assigning the actual logo parameter values to cs-about and remove the
TODO/tracking reference.

64-64: 💤 Low value

Consider running trunk fmt to address style issues.

Static analysis detected minor hyphenation style issues:

  • Line 64: "zero trust" → "zero-trust"
  • Line 94: "per service right sizing" → "per-service right-sizing"

As per coding guidelines, run trunk fmt to auto-fix these issues.

📝 Expected fixes

Line 64:

-- [**Tailscale**](https://tailscale.com/) VPN subnet router architecture for secure, zero trust, identity-aware seamless access to private infrastructure. Replaced legacy VPN that required manual key management and cumbersome configuration.
+- [**Tailscale**](https://tailscale.com/) VPN subnet router architecture for secure, zero-trust, identity-aware seamless access to private infrastructure. Replaced legacy VPN that required manual key management and cumbersome configuration.

Line 94:

-body: The migration towards AWS Fargate's serverless compute engine enables MarketSpark to run their applications without needing to manage underlying servers. Fargate also reduced compute spend on the same workloads with proper per service right sizing (additionally, [Fargate Spot is used where tolerated, delivering up to a 70% AWS discount](https://aws.amazon.com/fargate/pricing/)).
+body: The migration towards AWS Fargate's serverless compute engine enables MarketSpark to run their applications without needing to manage underlying servers. Fargate also reduced compute spend on the same workloads with proper per-service right-sizing (additionally, [Fargate Spot is used where tolerated, delivering up to a 70% AWS discount](https://aws.amazon.com/fargate/pricing/)).

Also applies to: 94-94

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark-article-style.md` at line 64, Run the
formatter (trunk fmt) to auto-fix hyphenation style issues, and manually ensure
the two phrases are corrected: change "zero trust" to "zero-trust" in the
Tailscale VPN description and change "per service right sizing" to "per-service
right-sizing" where that phrase appears; re-run trunk fmt and commit the updated
markdown.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@assets/css/custom.scss`:
- Line 5189: Fix the stylelint failures in assets/css/custom.scss by removing
the stray empty '//' comment lines (delete the lines that only contain '//'),
ensure there is a single blank line before any remaining '//' comment lines to
satisfy the blank-line-before-comment rule, and normalize the CSS color keyword
casing by replacing occurrences of 'currentColor' with the lint-expected
'currentcolor' (search for 'currentColor' tokens in the immersive block). Apply
these fixes for all reported occurrences (lines referenced in the review) so the
immersive block passes stylelint.
- Around line 5583-5591: The stylesheet defines .csi-media but never handles the
emitted modifier .csi-media--contain, so contain="true" has no effect; add a
rule targeting the modifier (e.g., .csi-media--contain or .csi-media.--contain
depending on naming) that applies object-fit: contain (and any necessary
width/height settings) to the inner img (the selector that targets the image
inside .csi-media), ensuring the .csi-media element switches from cover behavior
to contain when the shortcode emits csi-media--contain.
- Around line 5441-5443: The .csi-section__num rule always hides the number so
the csi-section's num prop never shows; update the stylesheet to stop globally
hiding it — either remove the ".csi-section__num { display: none; }" rule or
change it to a visible default like ".csi-section__num { display: inline-block;
}", or make it conditional (e.g. ".csi-section:not([data-num]) .csi-section__num
{ display: none; }") so the num renders when csi-section provides a value.

In `@content/case-studies/marketspark-article-style.md`:
- Line 6: The front matter currently sets draft: false which will publish the
unfinished page; change the front-matter key draft to true (i.e., replace draft:
false with draft: true) so the document is excluded from production
builds—update the top-of-file front matter where the draft field is defined.

In `@content/case-studies/marketspark.md`:
- Line 4: The front matter has a contradictory draft flag: change the YAML key
draft from false to true in the marketspark case study so the doc stays hidden
from production (update the front-matter `draft:` value in
content/case-studies/marketspark.md to `true`, leaving the "NOT READY FOR
RELEASE" note intact).

In `@layouts/case-studies/_markup/render-link.html`:
- Around line 7-8: The external-link detection using strings.HasPrefix
.Destination "http" (variable $external) is too narrow and misses uppercase
schemes and protocol-relative URLs; update the check in render-link.html to
robustly detect external links by either parsing .Destination with net/url
(url.Parse and test parsed.Scheme != "") or by normalizing case and matching
prefixes "http://", "https://", and "//" (e.g.,
strings.HasPrefix(strings.ToLower(.Destination), "http://") ||
strings.HasPrefix(strings.ToLower(.Destination), "https://") ||
strings.HasPrefix(.Destination, "//")); then use that result for adding
target="_blank" rel="noopener noreferrer".

In `@layouts/case-studies/immersive.html`:
- Line 31: The alt attribute's inline template alt="{{ .Params.client | default
"" }} logo" breaks the HTML parser due to the nested quotes; update the template
to produce the client text safely (for example use the default function with
explicit args or a template branch/printf) so the attribute string is formed
without embedded quote tokens — replace the current expression that references
.Params.client and default "" inside the img tag with a parser-safe expression
such as using default with its argument order or using printf/{{ with ...
}}...{{ end }} to emit "(client) logo".

In `@layouts/shortcodes/cs-about.html`:
- Around line 18-22: The img alt currently uses "{{ $name }} logo" which
produces " logo" when $name is empty; update the template that renders the logo
(the block using $logo and $name in the cs-about__logo div) to provide a
fallback for $name—e.g., use the template default for $name (or a conditional)
so the alt becomes something like "Site logo" when $name is missing, ensuring
the alt attribute is always descriptive or intentionally empty for decorative
images.

In `@layouts/shortcodes/csi-steps.html`:
- Around line 11-13: The rendering uses the original index $i from iterating
$blocks but skips empty trimmed blocks ($b), causing skipped step numbers; fix
by computing the sequence from the filtered/non-empty blocks instead of $i —
e.g., filter out empty blocks before the range or introduce a render counter
(like $step) that you initialize before the loop and increment only when $b is
non-empty, then use that counter for labels wherever $i was used; update
references to $i in the template to use the new counter or iterate over the
filtered list so numbering is contiguous.

---

Nitpick comments:
In `@content/case-studies/marketspark-article-style.md`:
- Line 2: Add a tracking TODO and placeholder flow for the missing MarketSpark
logo assets: open a tracking issue that requests both dark and light logo files
and links it in this file, then update the cs-about shortcode usage (cs-about)
to accept a new logo parameter and set it to a placeholder SVG/PNG fallback
until the real assets arrive; once you get the provided dark & light files,
replace the placeholders by assigning the actual logo parameter values to
cs-about and remove the TODO/tracking reference.
- Line 64: Run the formatter (trunk fmt) to auto-fix hyphenation style issues,
and manually ensure the two phrases are corrected: change "zero trust" to
"zero-trust" in the Tailscale VPN description and change "per service right
sizing" to "per-service right-sizing" where that phrase appears; re-run trunk
fmt and commit the updated markdown.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 821b32c2-19ac-40dc-aed9-f55af0420e35

📥 Commits

Reviewing files that changed from the base of the PR and between a2de83c and 01cc0e5.

⛔ Files ignored due to path filters (5)
  • static/img/case-studies/marketspark/aws-organization-docs.png is excluded by !**/*.png
  • static/img/case-studies/marketspark/marketspark-aws.jpg is excluded by !**/*.jpg
  • static/img/case-studies/marketspark/telecommunications.jpg is excluded by !**/*.jpg
  • static/img/case-studies/opentofu.jpg is excluded by !**/*.jpg
  • static/img/case-studies/spacelift.jpg is excluded by !**/*.jpg
📒 Files selected for processing (21)
  • assets/css/custom.scss
  • content/case-studies/marketspark-article-style.md
  • content/case-studies/marketspark.md
  • content/case-studies/template.md
  • docs/case-studies.md
  • layouts/case-studies/_markup/render-link.html
  • layouts/case-studies/immersive.html
  • layouts/shortcodes/cs-about.html
  • layouts/shortcodes/cs-beforeafter.html
  • layouts/shortcodes/cs-callout.html
  • layouts/shortcodes/cs-figure.html
  • layouts/shortcodes/cs-lockup.html
  • layouts/shortcodes/cs-pane.html
  • layouts/shortcodes/cs-pullquote.html
  • layouts/shortcodes/cs-stats.html
  • layouts/shortcodes/cs-todo.html
  • layouts/shortcodes/csi-impact.html
  • layouts/shortcodes/csi-section.html
  • layouts/shortcodes/csi-split.html
  • layouts/shortcodes/csi-steps.html
  • layouts/shortcodes/csi-testimonial.html
💤 Files with no reviewable changes (8)
  • layouts/shortcodes/cs-todo.html
  • layouts/shortcodes/cs-lockup.html
  • content/case-studies/template.md
  • layouts/shortcodes/cs-figure.html
  • layouts/shortcodes/cs-stats.html
  • layouts/shortcodes/cs-callout.html
  • layouts/shortcodes/cs-beforeafter.html
  • layouts/shortcodes/cs-pane.html

Comment thread assets/css/custom.scss
// hero + at-a-glance stat strip reuse the `.case-study-modern .cs-*` rules above
// (top is byte-identical to modern). EVERYTHING here is scoped to `.csi-*` —
// never bare element selectors — so it can't touch the modern hero/stats.
//

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve the stylelint errors in the immersive block.

The current changes introduce lint failures (empty comment, missing blank lines before // comments, and currentColor casing). This will keep style checks red.

Also applies to: 5210-5210, 5218-5218, 5337-5337, 5348-5348, 5404-5404, 5415-5415, 5444-5444, 5473-5473, 5560-5560, 5599-5599

🧰 Tools
🪛 Stylelint (17.12.0)

[error] 5189-5189: Unexpected empty comment (scss/comment-no-empty)

(scss/comment-no-empty)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/css/custom.scss` at line 5189, Fix the stylelint failures in
assets/css/custom.scss by removing the stray empty '//' comment lines (delete
the lines that only contain '//'), ensure there is a single blank line before
any remaining '//' comment lines to satisfy the blank-line-before-comment rule,
and normalize the CSS color keyword casing by replacing occurrences of
'currentColor' with the lint-expected 'currentcolor' (search for 'currentColor'
tokens in the immersive block). Apply these fixes for all reported occurrences
(lines referenced in the review) so the immersive block passes stylelint.

Comment thread assets/css/custom.scss
Comment on lines +5441 to +5443
.csi-section__num {
display: none;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

num is currently non-functional because it is always hidden.

csi-section accepts a num parameter, but .csi-section__num { display: none; } prevents it from ever rendering visually.

Suggested fix
-  .csi-section__num {
-    display: none;
-  }
+  .csi-section__num {
+    position: absolute;
+    top: 0;
+    right: 0;
+    font-size: clamp(2.4rem, 7vw, 4.8rem);
+    line-height: 1;
+    font-weight: 900;
+    opacity: 0.1;
+    pointer-events: none;
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.csi-section__num {
display: none;
}
.csi-section__num {
position: absolute;
top: 0;
right: 0;
font-size: clamp(2.4rem, 7vw, 4.8rem);
line-height: 1;
font-weight: 900;
opacity: 0.1;
pointer-events: none;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/css/custom.scss` around lines 5441 - 5443, The .csi-section__num rule
always hides the number so the csi-section's num prop never shows; update the
stylesheet to stop globally hiding it — either remove the ".csi-section__num {
display: none; }" rule or change it to a visible default like ".csi-section__num
{ display: inline-block; }", or make it conditional (e.g.
".csi-section:not([data-num]) .csi-section__num { display: none; }") so the num
renders when csi-section provides a value.

Comment thread assets/css/custom.scss
Comment on lines +5583 to +5591
.csi-media {
margin: 0;
img {
display: block;
width: 100%;
height: auto;
border-radius: 14px;
}
&__caption {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

contain="true" has no effect without a .csi-media--contain rule.

The shortcode emits csi-media--contain, but this stylesheet never defines behavior for it, so media always stays in cover mode.

Suggested fix
   .csi-media {
     margin: 0;
     img {
       display: block;
       width: 100%;
       height: auto;
       border-radius: 14px;
     }
+    &--contain img {
+      object-fit: contain;
+      background: rgba(255, 255, 255, 0.04);
+      padding: 0.6rem;
+    }
     &__caption {
       margin-top: 0.9rem;
       font-size: 0.85rem;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.csi-media {
margin: 0;
img {
display: block;
width: 100%;
height: auto;
border-radius: 14px;
}
&__caption {
.csi-media {
margin: 0;
img {
display: block;
width: 100%;
height: auto;
border-radius: 14px;
}
&--contain img {
object-fit: contain;
background: rgba(255, 255, 255, 0.04);
padding: 0.6rem;
}
&__caption {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/css/custom.scss` around lines 5583 - 5591, The stylesheet defines
.csi-media but never handles the emitted modifier .csi-media--contain, so
contain="true" has no effect; add a rule targeting the modifier (e.g.,
.csi-media--contain or .csi-media.--contain depending on naming) that applies
object-fit: contain (and any necessary width/height settings) to the inner img
(the selector that targets the image inside .csi-media), ensuring the .csi-media
element switches from cover behavior to contain when the shortcode emits
csi-media--contain.

Comment thread content/case-studies/marketspark-article-style.md Outdated
Comment thread content/case-studies/marketspark.md Outdated
# TODO: NEED TO ASK MARKETSPARK FOR PROPER LOGO (dark & light variants)
draft: true # NOT READY FOR RELEASE
# TODO: replace placeholder testimonial with a real MarketSpark quote from the retro
draft: false # NOT READY FOR RELEASE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Contradictory draft status.

The comment says NOT READY FOR RELEASE, but draft: false means this page will be published to production. Per coding guidelines, content that should be hidden from production builds must set draft: true.

🛡️ Proposed fix
-draft: false # NOT READY FOR RELEASE
+draft: true # NOT READY FOR RELEASE

As per coding guidelines: "Set draft: true in front matter to hide content from production builds."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
draft: false # NOT READY FOR RELEASE
draft: true # NOT READY FOR RELEASE
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark.md` at line 4, The front matter has a
contradictory draft flag: change the YAML key draft from false to true in the
marketspark case study so the doc stays hidden from production (update the
front-matter `draft:` value in content/case-studies/marketspark.md to `true`,
leaving the "NOT READY FOR RELEASE" note intact).

Comment on lines +7 to +8
{{- $external := strings.HasPrefix .Destination "http" -}}
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if $external }} target="_blank" rel="noopener noreferrer"{{ end }}>{{ .Text | safeHTML }}</a>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

External-link detection is too narrow.

HasPrefix(..., "http") misses uppercase/protocol-relative forms, so some external links won’t get target/rel.

Suggested fix
-{{- $external := strings.HasPrefix .Destination "http" -}}
+{{- $dest := lower .Destination -}}
+{{- $external := or (strings.HasPrefix $dest "http://") (strings.HasPrefix $dest "https://") (strings.HasPrefix $dest "//") -}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $external := strings.HasPrefix .Destination "http" -}}
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if $external }} target="_blank" rel="noopener noreferrer"{{ end }}>{{ .Text | safeHTML }}</a>
{{- $dest := lower .Destination -}}
{{- $external := or (strings.HasPrefix $dest "http://") (strings.HasPrefix $dest "https://") (strings.HasPrefix $dest "//") -}}
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if $external }} target="_blank" rel="noopener noreferrer"{{ end }}>{{ .Text | safeHTML }}</a>
🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 8-8: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 8-8: Special characters must be escaped : [ > ].

(spec-char-escape)


[error] 8-8: Tag must be paired, no start tag: [ ]

(tag-pair)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/case-studies/_markup/render-link.html` around lines 7 - 8, The
external-link detection using strings.HasPrefix .Destination "http" (variable
$external) is too narrow and misses uppercase schemes and protocol-relative
URLs; update the check in render-link.html to robustly detect external links by
either parsing .Destination with net/url (url.Parse and test parsed.Scheme !=
"") or by normalizing case and matching prefixes "http://", "https://", and "//"
(e.g., strings.HasPrefix(strings.ToLower(.Destination), "http://") ||
strings.HasPrefix(strings.ToLower(.Destination), "https://") ||
strings.HasPrefix(.Destination, "//")); then use that result for adding
target="_blank" rel="noopener noreferrer".

{{ if .Params.client_logo }}
<div class="cs-hero__lockup">
<div class="cs-hero__lockup-mark cs-hero__lockup-mark--client">
<img src="{{ .Params.client_logo }}" alt="{{ .Params.client | default "" }} logo" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rewrite the alt template expression to avoid HTML parser breakage.

This line is currently tripping the formatter/parser (img tag seen as unterminated). The nested default "" expression inside the attribute should be rewritten to a parser-safe template branch.

Suggested fix
-                            <img src="{{ .Params.client_logo }}" alt="{{ .Params.client | default "" }} logo" />
+                            <img src="{{ .Params.client_logo }}" alt="{{ with .Params.client }}{{ . }} logo{{ else }}Client logo{{ end }}" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src="{{ .Params.client_logo }}" alt="{{ .Params.client | default "" }} logo" />
<img src="{{ .Params.client_logo }}" alt="{{ with .Params.client }}{{ . }} logo{{ else }}Client logo{{ end }}" />
🧰 Tools
🪛 GitHub Check: Trunk Check

[failure] 31-31: prettier(SyntaxError)
[new] Opening tag "img" not terminated.

🪛 HTMLHint (1.9.2)

[error] 31-31: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 31-31: Special characters must be escaped : [ > ].

(spec-char-escape)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/case-studies/immersive.html` at line 31, The alt attribute's inline
template alt="{{ .Params.client | default "" }} logo" breaks the HTML parser due
to the nested quotes; update the template to produce the client text safely (for
example use the default function with explicit args or a template branch/printf)
so the attribute string is formed without embedded quote tokens — replace the
current expression that references .Params.client and default "" inside the img
tag with a parser-safe expression such as using default with its argument order
or using printf/{{ with ... }}...{{ end }} to emit "(client) logo".

Comment on lines +18 to +22
{{- if $logo -}}
<div class="cs-about__logo">
<img src="{{ $logo }}" alt="{{ $name }} logo" />
</div>
{{- end -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle empty name parameter in logo alt text.

If the name parameter is not provided or is empty, the alt text on line 20 will render as just " logo" (space + "logo"), which is not descriptive. Consider providing a fallback for the alt attribute.

♿ Proposed fix for accessible alt text
   {{- if $logo -}}
   <div class="cs-about__logo">
-    <img src="{{ $logo }}" alt="{{ $name }} logo" />
+    <img src="{{ $logo }}" alt="{{ cond (ne $name "") (printf "%s logo" $name) "Client logo" }}" />
   </div>
   {{- end -}}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/shortcodes/cs-about.html` around lines 18 - 22, The img alt currently
uses "{{ $name }} logo" which produces " logo" when $name is empty; update the
template that renders the logo (the block using $logo and $name in the
cs-about__logo div) to provide a fallback for $name—e.g., use the template
default for $name (or a conditional) so the alt becomes something like "Site
logo" when $name is missing, ensuring the alt attribute is always descriptive or
intentionally empty for decorative images.

Comment on lines +11 to +13
{{- range $i, $block := $blocks -}}
{{- $b := trim $block " \t\n" -}}
{{- if $b -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Step numbers can skip when empty blocks are present.

Index $i comes from all split blocks, but rendering skips empty ones afterward. That can produce non-contiguous labels.

Suggested fix
 <div class="csi-steps">
-  {{- range $i, $block := $blocks -}}
+  {{- $step := 0 -}}
+  {{- range $block := $blocks -}}
     {{- $b := trim $block " \t\n" -}}
     {{- if $b -}}
+      {{- $step = add $step 1 -}}
       {{- $lines := split $b "\n" -}}
@@
-        <span class="csi-step__num">{{ printf "%02d" (add $i 1) }}</span>
+        <span class="csi-step__num">{{ printf "%02d" $step }}</span>

Also applies to: 28-28

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/shortcodes/csi-steps.html` around lines 11 - 13, The rendering uses
the original index $i from iterating $blocks but skips empty trimmed blocks
($b), causing skipped step numbers; fix by computing the sequence from the
filtered/non-empty blocks instead of $i — e.g., filter out empty blocks before
the range or introduce a render counter (like $step) that you initialize before
the loop and increment only when $b is non-empty, then use that counter for
labels wherever $i was used; update references to $i in the template to use the
new counter or iterate over the filtered list so numbering is contiguous.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
content/case-studies/marketspark.md (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Run Trunk lint for the changed case-study markdown

CI runs trunk checks on PRs via .github/workflows/lint.yaml. For this specific file under content/case-studies/**/*.md, .trunk/trunk.yaml disables markdownlint/prettier checks, so any failures would come from other enabled linters—still run trunk check, and use trunk fmt if you have Trunk available to apply any auto-fixes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark.md` at line 1, Run trunk check against the
changed case study (marketspark.md) to surface any CI lint failures and, if you
have Trunk locally, run trunk fmt on the same file to apply auto-fixes; since
.trunk/trunk.yaml disables markdownlint/prettier for
content/case-studies/**/*.md, expect failures only from other enabled linters
and commit any formatting fixes produced by trunk fmt before pushing.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@content/case-studies/marketspark.md`:
- Line 128: Update the compound modifier in the body text so “customer facing
Production workloads” becomes “customer-facing Production workloads”; edit the
line containing the body: sentence (the phrase starting "A misconfiguration,
runaway process, or compromised credential...") and hyphenate "customer-facing"
to correct the compound adjective usage.

---

Outside diff comments:
In `@content/case-studies/marketspark.md`:
- Line 1: Run trunk check against the changed case study (marketspark.md) to
surface any CI lint failures and, if you have Trunk locally, run trunk fmt on
the same file to apply auto-fixes; since .trunk/trunk.yaml disables
markdownlint/prettier for content/case-studies/**/*.md, expect failures only
from other enabled linters and commit any formatting fixes produced by trunk fmt
before pushing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 35d65d43-b1f7-4420-902e-502d037c9636

📥 Commits

Reviewing files that changed from the base of the PR and between 01cc0e5 and b6e6769.

📒 Files selected for processing (4)
  • content/case-studies/marketspark-article-style.md
  • content/case-studies/marketspark.md
  • docs/case-studies.md
  • layouts/case-studies/immersive.html
🚧 Files skipped from review as they are similar to previous changes (2)
  • content/case-studies/marketspark-article-style.md
  • layouts/case-studies/immersive.html

Comment thread content/case-studies/marketspark.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
assets/css/custom.scss (2)

5529-5530: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add blank line before the comment to satisfy stylelint.

The comment at line 5529 needs a blank line above it per the scss/double-slash-comment-empty-line-before rule.

🧹 Proposed fix
     strong {
       color: $csi-ink;
       font-weight: 800;
     }
+
     // `:not(.csi-list)` — the compact csi-list ul carries its own grid layout;
     // keep the prose bullet/spacing treatment off it

As per coding guidelines, run trunk fmt to auto-fix linting issues in SCSS files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/css/custom.scss` around lines 5529 - 5530, The SCSS linter rule
requires a blank line before the single-line comment that starts with "//
`:not(.csi-list)` — the compact csi-list ul carries its own grid layout;": add a
single empty line immediately above that comment in assets/css/custom.scss (the
comment containing ":not(.csi-list)") so it satisfies
scss/double-slash-comment-empty-line-before, then run trunk fmt to auto-format
and re-run the linter.

Sources: Coding guidelines, Linters/SAST tools


5785-5786: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add blank line before the comment to satisfy stylelint.

The comment at line 5785 needs a blank line above it per the scss/double-slash-comment-empty-line-before rule.

🧹 Proposed fix
       }
     }
   }
+
   // ---------------------------------------------------------------------------
   // LIST — compact two-column icon rows; the space-saving sibling of csi-impact

As per coding guidelines, run trunk fmt to auto-fix linting issues in SCSS files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@assets/css/custom.scss` around lines 5785 - 5786, Add a blank line
immediately above the comment that starts with "//
---------------------------------------------------------------------------" and
the "LIST — compact two-column icon rows" line to satisfy the
scss/double-slash-comment-empty-line-before rule; locate the comment block (the
two consecutive single-line // comments shown in the diff) and insert one empty
line above it, then run the project's SCSS formatter (e.g., trunk fmt) to ensure
the file (assets/css/custom.scss) conforms to stylelint rules.

Sources: Coding guidelines, Linters/SAST tools

content/case-studies/marketspark.md (2)

128-128: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Hyphenate "customer-facing" for correctness.

Use "customer-facing Production workloads" to fix the compound modifier.

📝 Proposed fix
-body: A misconfiguration, runaway process, or compromised credential in a lower environment (e.g. Staging/QA) can no longer reach customer facing Production workloads. Each environment runs in its own AWS account with its own IAM scope and isolated VPC networking.
+body: A misconfiguration, runaway process, or compromised credential in a lower environment (e.g. Staging/QA) can no longer reach customer-facing Production workloads. Each environment runs in its own AWS account with its own IAM scope and isolated VPC networking.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark.md` at line 128, In the frontmatter 'body'
text, change the compound modifier "customer facing Production workloads" to use
a hyphen: "customer-facing Production workloads" so the phrase is grammatically
correct; update the string value that currently reads "A misconfiguration,
runaway process, or compromised credential in a lower environment (e.g.
Staging/QA) can no longer reach customer facing Production workloads." to the
hyphenated form.

4-4: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Contradictory draft status.

The comment says NOT READY FOR RELEASE, but draft: false means this page will be published to production.

🛡️ Proposed fix
-draft: false # NOT READY FOR RELEASE
+draft: true # NOT READY FOR RELEASE

As per coding guidelines: "Set draft: true in front matter to hide content from production builds."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/case-studies/marketspark.md` at line 4, The frontmatter in
marketspark.md incorrectly sets draft: false while the comment indicates "NOT
READY FOR RELEASE"; update the frontmatter key draft to true (change draft:
false to draft: true) so the page is hidden from production builds and aligns
with the comment.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@layouts/shortcodes/csi-list.html`:
- Around line 30-32: The current continuation condition appends any
non-directive line to $body (the clause using "else if and $line $body"),
causing stray/typo lines to be swallowed; change the logic to only append when
the previous parsed key was "body" (introduce and set a flag like $lastKey or
$inBody when you parse "body:" and check it here: only perform "$body = printf
"%s %s" $body $line" if $lastKey == "body"), or alternatively add explicit
validation of recognized directives and emit a warning for unrecognized keys
instead of appending; update the template branch that references $body and $line
accordingly so continuation is restricted to genuine body continuations.

---

Duplicate comments:
In `@assets/css/custom.scss`:
- Around line 5529-5530: The SCSS linter rule requires a blank line before the
single-line comment that starts with "// `:not(.csi-list)` — the compact
csi-list ul carries its own grid layout;": add a single empty line immediately
above that comment in assets/css/custom.scss (the comment containing
":not(.csi-list)") so it satisfies scss/double-slash-comment-empty-line-before,
then run trunk fmt to auto-format and re-run the linter.
- Around line 5785-5786: Add a blank line immediately above the comment that
starts with "//
---------------------------------------------------------------------------" and
the "LIST — compact two-column icon rows" line to satisfy the
scss/double-slash-comment-empty-line-before rule; locate the comment block (the
two consecutive single-line // comments shown in the diff) and insert one empty
line above it, then run the project's SCSS formatter (e.g., trunk fmt) to ensure
the file (assets/css/custom.scss) conforms to stylelint rules.

In `@content/case-studies/marketspark.md`:
- Line 128: In the frontmatter 'body' text, change the compound modifier
"customer facing Production workloads" to use a hyphen: "customer-facing
Production workloads" so the phrase is grammatically correct; update the string
value that currently reads "A misconfiguration, runaway process, or compromised
credential in a lower environment (e.g. Staging/QA) can no longer reach customer
facing Production workloads." to the hyphenated form.
- Line 4: The frontmatter in marketspark.md incorrectly sets draft: false while
the comment indicates "NOT READY FOR RELEASE"; update the frontmatter key draft
to true (change draft: false to draft: true) so the page is hidden from
production builds and aligns with the comment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 613588ee-8bff-4d9a-a0d0-4026d4339eb8

📥 Commits

Reviewing files that changed from the base of the PR and between b6e6769 and 96cecd1.

📒 Files selected for processing (5)
  • assets/css/custom.scss
  • content/case-studies/marketspark.md
  • docs/case-studies.md
  • layouts/shortcodes/csi-list.html
  • layouts/shortcodes/csi-section.html
🚧 Files skipped from review as they are similar to previous changes (2)
  • layouts/shortcodes/csi-section.html
  • docs/case-studies.md

Comment on lines +30 to +32
{{- else if and $line $body -}}
{{- $body = printf "%s %s" $body $line -}}
{{- end -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Line continuation logic may append unintended content.

The template appends any non-directive line to $body once a body exists. If an author adds a blank directive or typo (e.g., icons: instead of icon:), it silently becomes part of the previous item's body instead of failing loudly.

Example:

body: Main text.
icons: fa-typo  ← typo, gets appended to body

Consider restricting line continuation to only lines that immediately follow body: or add validation to warn on unrecognized directives. Alternatively, document this behavior in the comment block so authors know trailing lines are always appended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/shortcodes/csi-list.html` around lines 30 - 32, The current
continuation condition appends any non-directive line to $body (the clause using
"else if and $line $body"), causing stray/typo lines to be swallowed; change the
logic to only append when the previous parsed key was "body" (introduce and set
a flag like $lastKey or $inBody when you parse "body:" and check it here: only
perform "$body = printf "%s %s" $body $line" if $lastKey == "body"), or
alternatively add explicit validation of recognized directives and emit a
warning for unrecognized keys instead of appending; update the template branch
that references $body and $line accordingly so continuation is restricted to
genuine body continuations.

@oycyc oycyc changed the title [WIP] feat: case study success story, immersive styled feat: case study success story, immersive styled + revamped index listing page Jun 15, 2026

@Gowiem Gowiem left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: :shipit: :shipit: :shipit: :shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants