Autoflow rule: bare-image-position-variation
Priority 70 · A bare  varies position across the deck: inline → left → right → ...
This is the only rule that uses cross-slide state. Every other rule treats each slide independently. This one looks at the position used for the previous bare image in the deck and picks the next position in the cycle.
The name says “position variation” because it varies the image position across slides — it doesn’t rotate the image itself.
When it fires
Section titled “When it fires”- The slide has exactly 1 image with no layout modifier
(no
right/left/inline/qr/fit/filtered/bg) - The slide also has at least 1 non-image content line (heading or text)
What it does
Section titled “What it does”The rule reads ctx.state.lastBareImagePosition and picks the next
position in the cycle:
1st bare image in deck → inline (image in flow, text above)2nd bare image in deck → left (split, image left + text right)3rd bare image in deck → right (split, image right + text left)4th → inline, 5th → left, 6th → right, ...All three are existing parser primitives — the rule rewrites the bare
 into one of  /  / 
and the parser handles the rest.
The variation persists across the entire deck via ctx.state, not
just within the current slide. Even if other rules fire between two
bare-image slides, the variation continues from where it left off.
Cross-slide observation: explicit images count too
Section titled “Cross-slide observation: explicit images count too”The autoflow also observes explicit ![left] / ![right] / ![inline]
images on every slide — even on slides that the autoflow itself skips
(because of #[fit], code blocks, etc). The state is updated as if the
variation had picked that position.
Why: a user-placed  and a bare 
on the next slide should not both end up on the left. Without this
observation, the bare-image variation would happily ignore the explicit
one and could pick the same position. With it, the rule treats explicit
and bare images as one continuous variation history.
Concrete example:
slide 1:  → rule rewrites to  (lastPosition = inline)slide 2:  → autoflow skips (explicit), but observes (lastPosition = left)slide 3:  → rule picks NEXT after left = right (lastPosition = right)Slide 3 would have been left again without the observation step.
Why this rule
Section titled “Why this rule”Without it, an author with several plain  slides would have to
manually decide a position for each one. Forgetting to vary results in
every photo on the same side, which feels mechanical. The variation gives
natural rhythm without any thinking from the author.
Live fixture
Section titled “Live fixture”The fixture below has 4 bare-image slides in a row. Watch the position cycle through inline → left → right → inline as you flip through.
Source
Section titled “Source”footer: autoflow rules · bare-image-position-variationslidenumbers: trueautoflow: truetheme: nordicscheme: 1
# Cover
(slide 0 — sets up the deck before the variation begins)
---
<!--RULE: bare-image-position-variation (priority 70)TRIGGERS WHEN: - The slide has exactly 1 image with NO layout modifier (no right/left/inline/qr/fit/filtered/bg) - The slide also has at least 1 non-image content lineEFFECT (the only history-based rule): - Picks position by varying across deck: inline → left → right → ... - The position is based on ctx.state.lastBareImagePosition, NOT slide index - All three rewrite the bare  into a parser primitive: , ,  - State is also updated when an EXPLICIT ![left]/![right]/![inline] image appears on a skipped slide, so the variation never repeats the same position as the previous slide.
The name says "position variation" because it varies the IMAGE POSITIONacross slides — it doesn't rotate the image itself.
The 4 slides below show one full cycle + wrap: slide 1: 1st bare image → inline (variation starts) slide 2: 2nd bare image → left slide 3: 3rd bare image → right slide 4: 4th bare image → inline (cycle wraps)-->

# First image of the deck
This one becomes inline (image in flow, text above).
---

# Second image
This one varies to left split.
---

# Third image
And this one varies to right split.
---

# Fourth image
Cycle wraps: back to inline.Future enhancement
Section titled “Future enhancement”A planned upgrade: measure the image at render time (naturalWidth/Height)
and prefer portrait → split vs landscape → inline hero instead of
strict round-robin variation. The CSS classes would be applied via a small
JS helper in js/render.js, not in autoflow itself (which is sync
markdown→markdown). Tracked in the roadmap.