1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212(** Prose typography utilities
Complete implementation of Tailwind Typography plugin with:
- All HTML elements styled with :where() for low specificity
- not-prose exclusion mechanism
- Full CSS variable theming
- Size and color variants *)moduleCss=Cascade.CssopenCsstypevariant=[`Base|`Sm|`Lg|`Xl|`Xl2|`Gray|`Slate|`Zinc|`Neutral|`Stone](* Create prose variables using the new API *)letprose_body_var=Var.channelColor"tw-prose-body"letprose_headings_var=Var.channelColor"tw-prose-headings"letprose_lead_var=Var.channelColor"tw-prose-lead"letprose_links_var=Var.channelColor"tw-prose-links"letprose_bold_var=Var.channelColor"tw-prose-bold"letprose_counters_var=Var.channelColor"tw-prose-counters"letprose_bullets_var=Var.channelColor"tw-prose-bullets"letprose_hr_var=Var.channelColor"tw-prose-hr"letprose_quotes_var=Var.channelColor"tw-prose-quotes"letprose_quote_borders_var=Var.channelColor"tw-prose-quote-borders"letprose_captions_var=Var.channelColor"tw-prose-captions"letprose_kbd_var=Var.channelColor"tw-prose-kbd"letprose_kbd_shadows_var=Var.channelColor"tw-prose-kbd-shadows"letprose_code_var=Var.channelColor"tw-prose-code"letprose_pre_code_var=Var.channelColor"tw-prose-pre-code"letprose_pre_bg_var=Var.channelColor"tw-prose-pre-bg"letprose_th_borders_var=Var.channelColor"tw-prose-th-borders"letprose_td_borders_var=Var.channelColor"tw-prose-td-borders"(* Invert variants for dark mode *)letprose_invert_body_var=Var.channelColor"tw-prose-invert-body"letprose_invert_headings_var=Var.channelColor"tw-prose-invert-headings"letprose_invert_lead_var=Var.channelColor"tw-prose-invert-lead"letprose_invert_links_var=Var.channelColor"tw-prose-invert-links"letprose_invert_bold_var=Var.channelColor"tw-prose-invert-bold"letprose_invert_counters_var=Var.channelColor"tw-prose-invert-counters"letprose_invert_bullets_var=Var.channelColor"tw-prose-invert-bullets"letprose_invert_hr_var=Var.channelColor"tw-prose-invert-hr"letprose_invert_quotes_var=Var.channelColor"tw-prose-invert-quotes"letprose_invert_quote_borders_var=Var.channelColor"tw-prose-invert-quote-borders"letprose_invert_captions_var=Var.channelColor"tw-prose-invert-captions"letprose_invert_kbd_var=Var.channelColor"tw-prose-invert-kbd"letprose_invert_kbd_shadows_var=Var.channelColor"tw-prose-invert-kbd-shadows"letprose_invert_code_var=Var.channelColor"tw-prose-invert-code"letprose_invert_pre_code_var=Var.channelColor"tw-prose-invert-pre-code"letprose_invert_pre_bg_var=Var.channelColor"tw-prose-invert-pre-bg"letprose_invert_th_borders_var=Var.channelColor"tw-prose-invert-th-borders"letprose_invert_td_borders_var=Var.channelColor"tw-prose-invert-td-borders"(* ======================================================================== *)(* Selector Helper Functions *)(* ======================================================================== *)let(++)=Css.Selector.(++)let(>>)=Css.Selector.(>>)let(&&)=Css.Selector.(&&)(* let ( || ) = Css.Selector.( || ) -- Not used anymore, using list instead *)(* Shorthand for attribute selectors *)letattrnamematch_type=Css.Selector.attributenamematch_typeletclass_attrvalue=attr"class"(Whitespace_listvalue)lettype_attrvalue=attr"type"(Exactvalue)(* The [:not(:where(...))] that keeps a prose rule off an element opted out with
[not-prose], and off its descendants. *)letnot_prose_selector=letopenCss.Selectorinletnot_prose_class=attribute"class"(Whitespace_list"not-prose")inletnot_prose_descendant=combinenot_prose_classDescendantuniversalinnot[where[not_prose_class;not_prose_descendant]](* Helper to create a prose element selector with :where() and :not()
exclusion *)letprose_where_elementelement_selector=letopenCss.Selectorin(* Create :where(element):not(:where(...)) structure *)compound[where[element_selector];not_prose_selector](* Helper to create a typed selector with :where() and :not() for prose *)letwherebase_classelt=letopenCss.Selectorin(* For now, just use the new helper *)class_base_class++prose_where_elementelt(* Helper for child selectors in prose size variants like prose-sm *)letprose_child_selectorparent_selectorchild_element=(* Create selector like: .prose-sm :where(.prose-sm>child):not(...) *)letopenCss.Selectorinletparent_child=combineparent_selectorChildchild_elementin(* Wrap the parent>child in :where() then add :not() *)parent_selector++compound[where[parent_child];not_prose_selector]letli=Css.Selector.element"li"letol=Css.Selector.element"ol"letul=Css.Selector.element"ul"letdd=Css.Selector.element"dd"letdl=Css.Selector.element"dl"lethr=Css.Selector.element"hr"leth1=Css.Selector.element"h1"leth2=Css.Selector.element"h2"leth3=Css.Selector.element"h3"leth4=Css.Selector.element"h4"letthead=Css.Selector.element"thead"lettbody=Css.Selector.element"tbody"lettfoot=Css.Selector.element"tfoot"letfigure=Css.Selector.element"figure"letp=Css.Selector.element"p"letth=Css.Selector.element"th"lettd=Css.Selector.element"td"letfirst_child=Css.Selector.First_childletlast_child=Css.Selector.Last_childletsiblinge=Css.Selector.(combineeNext_siblinguniversal)leta=Css.Selector.element"a"letcode=Css.Selector.element"code"letpre=Css.Selector.element"pre"letblockquote=Css.Selector.element"blockquote"lettr=Css.Selector.element"tr"lettable=Css.Selector.element"table"letfigcaption=Css.Selector.element"figcaption"letpicture=Css.Selector.element"picture"letimg=Css.Selector.element"img"letdt=Css.Selector.element"dt"letstrong=Css.Selector.element"strong"letvideo=Css.Selector.element"video"(* kbd selector no longer needed; size rules use direct element selectors *)(* Lead paragraph selector - now unused since prose_where_element is used
directly *)(* Compound selectors for ol with type attributes *)(* ol type selectors were only used in removed duplicate rules *)(* Pseudo-element helpers that apply pseudo AFTER the where clause *)letwith_beforeselector=Css.Selector.compound[selector;Css.Selector.BeforeCss.Selector.Single]letwith_afterselector=Css.Selector.compound[selector;Css.Selector.AfterCss.Selector.Single]letradiuslen=Css.Radius{horizontal=[Css.Lengthlen];vertical=None}(* blockquote paragraph pseudo-element selectors were only used in removed
duplicates *)letblockquote_code=blockquote++codeletthead_th_code=thead++th++codeletpre_code=pre++codeletthead_th=thead++thlettbody_tr=tbody++trlettbody_tr_last_child=tbody++(tr&&last_child)(* tbody_td and tfoot_td now constructed inline *)(* picture_img now constructed inline *)(* ol_li and ul_li now constructed inline *)(* h2_code and h3_code now constructed inline in typography_rules *)letnested_lists=Css.Selector.list[ul++ul;ul++ol;ol++ul;ol++ol](* These compound selectors are now constructed inline in typography_rules *)(* Theme record for all prose color variables *)typeprose_theme={body:Css.declaration*Css.colorCss.var;headings:Css.declaration*Css.colorCss.var;lead:Css.declaration*Css.colorCss.var;links:Css.declaration*Css.colorCss.var;bold:Css.declaration*Css.colorCss.var;counters:Css.declaration*Css.colorCss.var;bullets:Css.declaration*Css.colorCss.var;hr:Css.declaration*Css.colorCss.var;quotes:Css.declaration*Css.colorCss.var;quote_borders:Css.declaration*Css.colorCss.var;captions:Css.declaration*Css.colorCss.var;kbd:Css.declaration*Css.colorCss.var;kbd_shadows:Css.declaration*Css.colorCss.var;code:Css.declaration*Css.colorCss.var;pre_code:Css.declaration*Css.colorCss.var;pre_bg:Css.declaration*Css.colorCss.var;th_borders:Css.declaration*Css.colorCss.var;td_borders:Css.declaration*Css.colorCss.var;(* Invert variants *)invert_body:Css.declaration*Css.colorCss.var;invert_headings:Css.declaration*Css.colorCss.var;invert_lead:Css.declaration*Css.colorCss.var;invert_links:Css.declaration*Css.colorCss.var;invert_bold:Css.declaration*Css.colorCss.var;invert_counters:Css.declaration*Css.colorCss.var;invert_bullets:Css.declaration*Css.colorCss.var;invert_hr:Css.declaration*Css.colorCss.var;invert_quotes:Css.declaration*Css.colorCss.var;invert_quote_borders:Css.declaration*Css.colorCss.var;invert_captions:Css.declaration*Css.colorCss.var;invert_kbd:Css.declaration*Css.colorCss.var;invert_kbd_shadows:Css.declaration*Css.colorCss.var;invert_code:Css.declaration*Css.colorCss.var;invert_pre_code:Css.declaration*Css.colorCss.var;invert_pre_bg:Css.declaration*Css.colorCss.var;invert_th_borders:Css.declaration*Css.colorCss.var;invert_td_borders:Css.declaration*Css.colorCss.var;}(* The eighteen colour slots a prose palette fills. Each theme below is one
record, so a slot added here is a compile error in every theme rather than a
declaration that silently goes missing from one of them. *)typepalette={body:Css.color;headings:Css.color;lead:Css.color;links:Css.color;bold:Css.color;counters:Css.color;bullets:Css.color;hr:Css.color;quotes:Css.color;quote_borders:Css.color;captions:Css.color;kbd:Css.color;kbd_shadows:Css.color;code:Css.color;pre_code:Css.color;pre_bg:Css.color;th_borders:Css.color;td_borders:Css.color;}letgray_normal={body=Css.oklch37.30.034259.733;headings=Css.oklch21.00.034264.665;lead=Css.oklch44.60.030256.802;links=Css.oklch21.00.034264.665;bold=Css.oklch21.00.034264.665;counters=Css.oklch55.10.027264.364;bullets=Css.oklch87.20.010258.338;hr=Css.oklch92.80.006264.531;quotes=Css.oklch21.00.034264.665;quote_borders=Css.oklch92.80.006264.531;captions=Css.oklch55.10.027264.364;kbd=Css.oklch21.00.034264.665;kbd_shadows=Css.oklaba21.0(-0.00316127)(-0.0338527)0.1;code=Css.oklch21.00.034264.665;pre_code=Css.oklch92.80.006264.531;pre_bg=Css.oklch27.80.033256.848;th_borders=Css.oklch87.20.010258.338;td_borders=Css.oklch92.80.006264.531;}letgray_invert={body=Css.oklch87.20.010258.338;headings=Css.hex"fff";lead=Css.oklch70.70.022261.325;links=Css.hex"fff";bold=Css.hex"fff";counters=Css.oklch70.70.022261.325;bullets=Css.oklch44.60.030256.802;hr=Css.oklch37.30.034259.733;quotes=Css.oklch96.70.003264.542;quote_borders=Css.oklch37.30.034259.733;captions=Css.oklch70.70.022261.325;kbd=Css.hex"fff";kbd_shadows=Css.hex"#ffffff1a";code=Css.hex"fff";pre_code=Css.oklch87.20.010258.338;pre_bg=Css.hex"00000080";th_borders=Css.oklch44.60.030256.802;td_borders=Css.oklch37.30.034259.733;}letslate_normal={body=Css.oklch37.20.044257.287;headings=Css.oklch20.80.042265.755;lead=Css.oklch44.60.043257.281;links=Css.oklch20.80.042265.755;bold=Css.oklch20.80.042265.755;counters=Css.oklch55.40.046257.417;bullets=Css.oklch86.90.022252.894;hr=Css.oklch92.90.013255.508;quotes=Css.oklch20.80.042265.755;quote_borders=Css.oklch92.90.013255.508;captions=Css.oklch55.40.046257.417;kbd=Css.oklch20.80.042265.755;kbd_shadows=Css.oklaba20.8(-0.00310889)(-0.0418848)0.1;code=Css.oklch20.80.042265.755;pre_code=Css.oklch92.90.013255.508;pre_bg=Css.oklch27.90.041260.031;th_borders=Css.oklch86.90.022252.894;td_borders=Css.oklch92.90.013255.508;}letslate_invert={body=Css.oklch86.90.022252.894;headings=Css.hex"fff";lead=Css.oklch70.40.040256.788;links=Css.hex"fff";bold=Css.hex"fff";counters=Css.oklch70.40.040256.788;bullets=Css.oklch44.60.043257.281;hr=Css.oklch37.20.044257.287;quotes=Css.oklch96.80.007247.896;quote_borders=Css.oklch37.20.044257.287;captions=Css.oklch70.40.040256.788;kbd=Css.hex"fff";kbd_shadows=Css.hex"#ffffff1a";code=Css.hex"fff";pre_code=Css.oklch86.90.022252.894;pre_bg=Css.hex"00000080";th_borders=Css.oklch44.60.043257.281;td_borders=Css.oklch37.20.044257.287;}letzinc_normal={body=Css.oklch37.00.013285.805;headings=Css.oklch21.00.006285.885;lead=Css.oklch44.20.017285.786;links=Css.oklch21.00.006285.885;bold=Css.oklch21.00.006285.885;counters=Css.oklch55.20.016285.938;bullets=Css.oklch87.10.006286.286;hr=Css.oklch92.00.004286.32;quotes=Css.oklch21.00.006285.885;quote_borders=Css.oklch92.00.004286.32;captions=Css.oklch55.20.016285.938;kbd=Css.oklch21.00.006285.885;kbd_shadows=Css.oklaba21.00.00164225(-0.00577088)0.1;code=Css.oklch21.00.006285.885;pre_code=Css.oklch92.00.004286.32;pre_bg=Css.oklch27.40.006286.033;th_borders=Css.oklch87.10.006286.286;td_borders=Css.oklch92.00.004286.32;}letzinc_invert={body=Css.oklch87.10.006286.286;headings=Css.hex"fff";lead=Css.oklch70.50.015286.067;links=Css.hex"fff";bold=Css.hex"fff";counters=Css.oklch70.50.015286.067;bullets=Css.oklch44.20.017285.786;hr=Css.oklch37.00.013285.805;quotes=Css.oklch96.70.001286.375;quote_borders=Css.oklch37.00.013285.805;captions=Css.oklch70.50.015286.067;kbd=Css.hex"fff";kbd_shadows=Css.hex"#ffffff1a";code=Css.hex"fff";pre_code=Css.oklch87.10.006286.286;pre_bg=Css.hex"00000080";th_borders=Css.oklch44.20.017285.786;td_borders=Css.oklch37.00.013285.805;}letneutral_normal={body=Css.oklch_none_hue37.10.0;headings=Css.oklch_none_hue20.50.0;lead=Css.oklch_none_hue43.90.0;links=Css.oklch_none_hue20.50.0;bold=Css.oklch_none_hue20.50.0;counters=Css.oklch_none_hue55.60.0;bullets=Css.oklch_none_hue87.00.0;hr=Css.oklch_none_hue92.20.0;quotes=Css.oklch_none_hue20.50.0;quote_borders=Css.oklch_none_hue92.20.0;captions=Css.oklch_none_hue55.60.0;kbd=Css.oklch_none_hue20.50.0;kbd_shadows=Css.oklaba20.50.00.00.1;code=Css.oklch_none_hue20.50.0;pre_code=Css.oklch_none_hue92.20.0;pre_bg=Css.oklch_none_hue26.90.0;th_borders=Css.oklch_none_hue87.00.0;td_borders=Css.oklch_none_hue92.20.0;}letneutral_invert={body=Css.oklch_none_hue87.00.0;headings=Css.hex"fff";lead=Css.oklch_none_hue70.80.0;links=Css.hex"fff";bold=Css.hex"fff";counters=Css.oklch_none_hue70.80.0;bullets=Css.oklch_none_hue43.90.0;hr=Css.oklch_none_hue37.10.0;quotes=Css.oklch_none_hue97.00.0;quote_borders=Css.oklch_none_hue37.10.0;captions=Css.oklch_none_hue70.80.0;kbd=Css.hex"fff";kbd_shadows=Css.hex"#ffffff1a";code=Css.hex"fff";pre_code=Css.oklch_none_hue87.00.0;pre_bg=Css.hex"00000080";th_borders=Css.oklch_none_hue43.90.0;td_borders=Css.oklch_none_hue37.10.0;}letstone_normal={body=Css.oklch37.40.0167.558;headings=Css.oklch21.60.00656.043;lead=Css.oklch44.40.01173.639;links=Css.oklch21.60.00656.043;bold=Css.oklch21.60.00656.043;counters=Css.oklch55.30.01358.071;bullets=Css.oklch86.90.00556.366;hr=Css.oklch92.30.00348.717;quotes=Css.oklch21.60.00656.043;quote_borders=Css.oklch92.30.00348.717;captions=Css.oklch55.30.01358.071;kbd=Css.oklch21.60.00656.043;kbd_shadows=Css.oklaba21.60.003351420.004976740.1;code=Css.oklch21.60.00656.043;pre_code=Css.oklch92.30.00348.717;pre_bg=Css.oklch26.80.00734.298;th_borders=Css.oklch86.90.00556.366;td_borders=Css.oklch92.30.00348.717;}letstone_invert={body=Css.oklch86.90.00556.366;headings=Css.hex"fff";lead=Css.oklch70.90.0156.259;links=Css.hex"fff";bold=Css.hex"fff";counters=Css.oklch70.90.0156.259;bullets=Css.oklch44.40.01173.639;hr=Css.oklch37.40.0167.558;quotes=Css.oklch97.00.001106.424;quote_borders=Css.oklch37.40.0167.558;captions=Css.oklch70.90.0156.259;kbd=Css.hex"fff";kbd_shadows=Css.hex"#ffffff1a";code=Css.hex"fff";pre_code=Css.oklch86.90.00556.366;pre_bg=Css.hex"00000080";th_borders=Css.oklch44.40.01173.639;td_borders=Css.oklch37.40.0167.558;}(* Default prose theme - the gray palette bound to the prose variables, created
once and shared across all utilities. Each field is the (declaration,
reference) pair returned by [Var.binding]. *)letdefault_prose_theme:prose_theme=letnormal=gray_normalandinvert=gray_invertin{body=Var.bindingprose_body_varnormal.body;headings=Var.bindingprose_headings_varnormal.headings;lead=Var.bindingprose_lead_varnormal.lead;links=Var.bindingprose_links_varnormal.links;bold=Var.bindingprose_bold_varnormal.bold;counters=Var.bindingprose_counters_varnormal.counters;bullets=Var.bindingprose_bullets_varnormal.bullets;hr=Var.bindingprose_hr_varnormal.hr;quotes=Var.bindingprose_quotes_varnormal.quotes;quote_borders=Var.bindingprose_quote_borders_varnormal.quote_borders;captions=Var.bindingprose_captions_varnormal.captions;kbd=Var.bindingprose_kbd_varnormal.kbd;kbd_shadows=Var.bindingprose_kbd_shadows_varnormal.kbd_shadows;code=Var.bindingprose_code_varnormal.code;pre_code=Var.bindingprose_pre_code_varnormal.pre_code;pre_bg=Var.bindingprose_pre_bg_varnormal.pre_bg;th_borders=Var.bindingprose_th_borders_varnormal.th_borders;td_borders=Var.bindingprose_td_borders_varnormal.td_borders;(* Invert variants *)invert_body=Var.bindingprose_invert_body_varinvert.body;invert_headings=Var.bindingprose_invert_headings_varinvert.headings;invert_lead=Var.bindingprose_invert_lead_varinvert.lead;invert_links=Var.bindingprose_invert_links_varinvert.links;invert_bold=Var.bindingprose_invert_bold_varinvert.bold;invert_counters=Var.bindingprose_invert_counters_varinvert.counters;invert_bullets=Var.bindingprose_invert_bullets_varinvert.bullets;invert_hr=Var.bindingprose_invert_hr_varinvert.hr;invert_quotes=Var.bindingprose_invert_quotes_varinvert.quotes;invert_quote_borders=Var.bindingprose_invert_quote_borders_varinvert.quote_borders;invert_captions=Var.bindingprose_invert_captions_varinvert.captions;invert_kbd=Var.bindingprose_invert_kbd_varinvert.kbd;invert_kbd_shadows=Var.bindingprose_invert_kbd_shadows_varinvert.kbd_shadows;invert_code=Var.bindingprose_invert_code_varinvert.code;invert_pre_code=Var.bindingprose_invert_pre_code_varinvert.pre_code;invert_pre_bg=Var.bindingprose_invert_pre_bg_varinvert.pre_bg;invert_th_borders=Var.bindingprose_invert_th_borders_varinvert.th_borders;invert_td_borders=Var.bindingprose_invert_td_borders_varinvert.td_borders;}(** Access theme record variables *)lettheme=default_prose_theme(* Extract individual variables from theme record for backward compatibility *)letprose_body_d,prose_body_v=theme.bodyletprose_headings_d,prose_headings_v=theme.headingsletprose_lead_d,prose_lead_v=theme.leadletprose_links_d,prose_links_v=theme.linksletprose_bold_d,prose_bold_v=theme.boldletprose_counters_d,prose_counters_v=theme.countersletprose_bullets_d,prose_bullets_v=theme.bulletsletprose_hr_d,prose_hr_v=theme.hrletprose_quotes_d,prose_quotes_v=theme.quotesletprose_quote_borders_d,prose_quote_borders_v=theme.quote_bordersletprose_captions_d,prose_captions_v=theme.captionsletprose_kbd_d,prose_kbd_v=theme.kbdletprose_kbd_shadows_d,prose_kbd_shadows_v=theme.kbd_shadowsletprose_code_d,prose_code_v=theme.codeletprose_pre_code_d,prose_pre_code_v=theme.pre_codeletprose_pre_bg_d,prose_pre_bg_v=theme.pre_bgletprose_th_borders_d,prose_th_borders_v=theme.th_bordersletprose_td_borders_d,prose_td_borders_v=theme.td_borders(* Invert variants *)letprose_invert_body_d,_prose_invert_body_v=theme.invert_bodyletprose_invert_headings_d,_prose_invert_headings_v=theme.invert_headingsletprose_invert_lead_d,_prose_invert_lead_v=theme.invert_leadletprose_invert_links_d,_prose_invert_links_v=theme.invert_linksletprose_invert_bold_d,_prose_invert_bold_v=theme.invert_boldletprose_invert_counters_d,_prose_invert_counters_v=theme.invert_countersletprose_invert_bullets_d,_prose_invert_bullets_v=theme.invert_bulletsletprose_invert_hr_d,_prose_invert_hr_v=theme.invert_hrletprose_invert_quotes_d,_prose_invert_quotes_v=theme.invert_quotesletprose_invert_quote_borders_d,_invert_quote_borders_v=theme.invert_quote_bordersletprose_invert_captions_d,_prose_invert_captions_v=theme.invert_captionsletprose_invert_kbd_d,_prose_invert_kbd_v=theme.invert_kbdletprose_invert_kbd_shadows_d,_invert_kbd_shadows_v=theme.invert_kbd_shadowsletprose_invert_code_d,_prose_invert_code_v=theme.invert_codeletprose_invert_pre_code_d,_invert_pre_code_v=theme.invert_pre_codeletprose_invert_pre_bg_d,_invert_pre_bg_v=theme.invert_pre_bgletprose_invert_th_borders_d,_invert_th_borders_v=theme.invert_th_bordersletprose_invert_td_borders_d,_invert_td_borders_v=theme.invert_td_borders(** Collect all CSS variable declarations *)letcss_variables=[prose_body_d;prose_headings_d;prose_lead_d;prose_links_d;prose_bold_d;prose_counters_d;prose_bullets_d;prose_hr_d;prose_quotes_d;prose_quote_borders_d;prose_captions_d;prose_kbd_d;prose_kbd_shadows_d;prose_code_d;prose_pre_code_d;prose_pre_bg_d;prose_th_borders_d;prose_td_borders_d;prose_invert_body_d;prose_invert_headings_d;prose_invert_lead_d;prose_invert_links_d;prose_invert_bold_d;prose_invert_counters_d;prose_invert_bullets_d;prose_invert_hr_d;prose_invert_quotes_d;prose_invert_quote_borders_d;prose_invert_captions_d;prose_invert_kbd_d;prose_invert_kbd_shadows_d;prose_invert_code_d;prose_invert_pre_code_d;prose_invert_pre_bg_d;prose_invert_th_borders_d;prose_invert_td_borders_d;]letto_class=function|`Base->"prose"|`Sm->"prose-sm"|`Lg->"prose-lg"|`Xl->"prose-xl"|`Xl2->"prose-2xl"|`Gray->"prose-gray"|`Slate->"prose-slate"|`Zinc->"prose-zinc"|`Neutral->"prose-neutral"|`Stone->"prose-stone"(** Generate CSS rules for prose elements *)(* Paragraph and lead styles are defined inline in base_prose_rules *)(* Link styles are defined inline in base_prose_rules *)(* Strong styles are defined inline in base_prose_rules *)(* List styles are defined inline in base_prose_rules *)(* Heading styles *)letheading_rulesbase=[Css.rule~selector:(wherebaseh1)[Css.color(Css.Varprose_headings_v);Css.margin_topZero;Css.margin_bottom(Em0.888889);Css.font_size(Em2.25);Css.font_weight(Weight800.);Css.line_height(Num1.11111);];Css.rule~selector:(wherebase(h1++strong))[Css.colorCss.Inherit;Css.font_weight(Css.Weight900.)];Css.rule~selector:(wherebaseh2)[Css.color(Css.Varprose_headings_v);Css.margin_top(Em2.0);Css.margin_bottom(Em1.0);Css.font_size(Em1.5);Css.font_weight(Weight700.);Css.line_height(Num1.33333);];Css.rule~selector:(wherebase(h2++strong))[Css.colorCss.Inherit;Css.font_weight(Css.Weight800.)];Css.rule~selector:(wherebaseh3)[Css.color(Css.Varprose_headings_v);Css.margin_top(Em1.6);Css.margin_bottom(Em0.6);Css.font_size(Em1.25);Css.font_weight(Weight600.);Css.line_height(Num1.6);];Css.rule~selector:(wherebase(h3++strong))[Css.colorInherit;Css.font_weight(Weight700.)];Css.rule~selector:(wherebaseh4)[Css.color(Css.Varprose_headings_v);Css.margin_top(Em1.5);Css.margin_bottom(Em0.5);Css.font_weight(Weight600.);Css.line_height(Num1.5);];Css.rule~selector:(wherebase(h4++strong))[Css.colorInherit;Css.font_weight(Weight700.)];](* Horizontal rule styles are defined inline in base_prose_rules *)(* Blockquote styles are defined inline in base_prose_rules *)(* Media element styles *)letmedia_rulesbase=[Css.rule~selector:(wherebaseimg)[Css.margin_top(Em2.0);Css.margin_bottom(Em2.0)];Css.rule~selector:(wherebasepicture)[Css.margin_top(Em2.0);Css.margin_bottom(Em2.0);Css.displayBlock];Css.rule~selector:(wherebasevideo)[Css.margin_top(Em2.0);Css.margin_bottom(Em2.0)];](* Keyboard styles *)letkbd_rulesbase=[Css.rule~selector:(wherebase(Css.Selector.element"kbd"))[Css.color(Css.Varprose_kbd_v);Css.box_shadows[Css.Shadow{h_offset=Zero;v_offset=Zero;blur=SomeZero;spread=Some(Px1.0);color=Some(Css.Varprose_kbd_shadows_v);};Css.Shadow{h_offset=Zero;v_offset=Px3.0;blur=SomeZero;spread=None;color=Some(Css.Varprose_kbd_shadows_v);};];Css.padding_top(Em0.1875);Css.padding_inline_end(Em0.375);Css.padding_bottom(Em0.1875);border_radius(radius(Rem0.3125));Css.padding_inline_start(Em0.375);font_familyInherit;Css.font_size(Em0.875);Css.font_weight(Weight500.);];](* Pre code block styles *)letpre_code_rulesbase=[Css.rule~selector:(wherebasepre)[Css.color(Css.Varprose_pre_code_v);Css.background_color(Css.Varprose_pre_bg_v);Css.padding_top(Em0.857143);Css.padding_inline_end(Em1.14286);Css.padding_bottom(Em0.857143);border_radius(radius(Rem0.375));Css.margin_top(Em1.71429);Css.margin_bottom(Em1.71429);Css.padding_inline_start(Em1.14286);Css.font_size(Em0.875);Css.font_weight(Weight400.);Css.line_height(Num1.71429);overflow_xAuto;];Css.rule~selector:(wherebasepre_code)[Css.font_weightInherit;Css.colorCss.Inherit;Css.font_sizeInherit;font_familyInherit;Css.line_heightInherit;Css.background_color(hex"#0000");border_widthZero;border_radius(radiusZero);padding[Zero];];(* Pre code pseudo-elements come AFTER pre code rule *)Css.rule~selector:(Css.Selector.list[with_before(wherebasepre_code);with_after(wherebasepre_code);])[contentNone];](* Code styles *)letcode_rulesbase=[Css.rule~selector:(wherebasecode)[Css.color(Css.Varprose_code_v);Css.font_size(Em0.875);Css.font_weight(Weight600.);];(* Code pseudo-elements come AFTER code rule to match Tailwind *)Css.rule~selector:(Css.Selector.list[with_before(wherebasecode);with_after(wherebasecode)])[content(String"`")];(* Code inherits color in certain contexts *)Css.rule~selector:(Css.Selector.list[wherebase(a++code);wherebase(h1++code)])[Css.colorInherit];Css.rule~selector:(wherebase(h2++code))[Css.colorInherit;Css.font_size(Em0.875)];Css.rule~selector:(wherebase(h3++code))[Css.colorInherit;Css.font_size(Em0.9)];Css.rule~selector:(Css.Selector.list[wherebase(h4++code);wherebaseblockquote_code;wherebasethead_th_code;])[Css.colorInherit];]@pre_code_rulesbase(* Table styles *)lettable_rulesbase=[Css.rule~selector:(wherebasetable)[table_layoutAuto;width(Pct100.0);Css.margin_top(Em2.0);Css.margin_bottom(Em2.0);Css.font_size(Em0.875);Css.line_height(Num1.71429);];Css.rule~selector:(wherebase(Css.Selector.element"thead"))[Css.border_bottom_width(Px1.);Css.border_bottom_color(Css.Varprose_th_borders_v);];Css.rule~selector:(wherebasethead_th)[Css.color(Css.Varprose_headings_v);Css.vertical_alignBottom;Css.padding_inline_end(Em0.571429);Css.padding_bottom(Em0.571429);Css.padding_inline_start(Em0.571429);Css.font_weight(Weight600.);];Css.rule~selector:(wherebasetbody_tr)[Css.border_bottom_width(Px1.);Css.border_bottom_color(Css.Varprose_td_borders_v);];Css.rule~selector:(wherebasetbody_tr_last_child)[border_bottom_widthZero];Css.rule~selector:(wherebase(tbody++td))[vertical_alignBaseline];Css.rule~selector:(wherebasetfoot)[border_top_width(Px1.);border_top_color(Css.Varprose_th_borders_v);];Css.rule~selector:(wherebase(tfoot++td))[vertical_alignTop];Css.rule~selector:(wherebase(Css.Selector.list[th;td]))[text_alignStart];](* Figure and figcaption styles *)letfigure_rulesbase=[Css.rule~selector:(wherebaseCss.Selector.(combinefigureChilduniversal))[Css.margin_topZero;Css.margin_bottomZero];Css.rule~selector:(wherebasefigcaption)[Css.color(Css.Varprose_captions_v);Css.margin_top(Em0.857143);Css.font_size(Em0.875);Css.line_height(Num1.42857);];](* Nested list paragraph first/last child spacing *)letnested_list_paragraph_rulesbase=[Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Child(ul>>li++p)))[Css.margin_top(Em0.75);Css.margin_bottom(Em0.75)];Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Child(ul>>(li>>(p&&first_child)))))[Css.margin_top(Em1.25)];Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Child(ul>>(li>>(p&&last_child)))))[Css.margin_bottom(Em1.25)];Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Child(ol>>(li>>(p&&first_child)))))[Css.margin_top(Em1.25)];Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Child(ol>>(li>>(p&&last_child)))))[Css.margin_bottom(Em1.25)];](* List spacing rules *)letlist_spacing_rulesbase=[(* Picture img special handling *)Css.rule~selector:(wherebase(picture>>img))[Css.margin_topZero;Css.margin_bottomZero];(* List item styles *)Css.rule~selector:(wherebaseli)[Css.margin_top(Em0.5);Css.margin_bottom(Em0.5)];Css.rule~selector:(Css.Selector.list[wherebase(ol>>li);wherebase(ul>>li)])[Css.padding_inline_start(Em0.375)];]@nested_list_paragraph_rulesbase@[(* Nested lists *)Css.rule~selector:(wherebasenested_lists)[Css.margin_top(Em0.75);Css.margin_bottom(Em0.75)];(* Definition lists *)Css.rule~selector:(wherebasedl)[Css.margin_top(Em1.25);Css.margin_bottom(Em1.25)];Css.rule~selector:(wherebasedd)[Css.margin_top(Em0.5);padding_inline_start(Em1.625)];](* Table spacing rules *)lettable_spacing_rulesbase=[Css.rule~selector:(wherebase(thead++(th&&first_child)))[Css.padding_inline_startZero];Css.rule~selector:(wherebase(thead++(th&&last_child)))[Css.padding_inline_endZero];Css.rule~selector:(wherebase(Css.Selector.list[tbody++td;tfoot++td]))[Css.padding_top(Em0.571429);Css.padding_inline_end(Em0.571429);Css.padding_bottom(Em0.571429);Css.padding_inline_start(Em0.571429);];Css.rule~selector:(wherebase(Css.Selector.list[tbody++(td&&first_child);tfoot++(td&&first_child)]))[Css.padding_inline_startZero];Css.rule~selector:(wherebase(Css.Selector.list[tbody++(td&&last_child);tfoot++(td&&last_child)]))[Css.padding_inline_endZero];](* Adjacent element spacing rules *)letadjacent_element_spacing_rulesbase=[Css.rule~selector:(Css.Selector.list[wherebase(siblinghr);wherebase(siblingh2);wherebase(siblingh3);wherebase(siblingh4);])[Css.margin_topZero];](* Figure and boundary rules *)letfigure_and_boundary_rulesbase=[Css.rule~selector:(wherebasefigure)[Css.margin_top(Em2.0);Css.margin_bottom(Em2.0)];(* First and last child margins *)Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Css.Selector.Childfirst_child))[Css.margin_topZero];Css.rule~selector:(wherebase(Css.Selector.combine(Css.Selector.class_"prose")Css.Selector.Childlast_child))[Css.margin_bottomZero];](* Additional list and spacing rules *)letadditional_rulesbase=list_spacing_rulesbase@adjacent_element_spacing_rulesbase@table_spacing_rulesbase@figure_and_boundary_rulesbase(* Paragraph and text rules *)letparagraph_and_text_rulesbase=[(* Paragraphs *)Css.rule~selector:(wherebasep)[Css.margin_top(Em1.25);Css.margin_bottom(Em1.25)];(* Lead text *)Css.rule~selector:(wherebase(class_attr"lead"))[color(Css.Varprose_lead_v);margin_top(Em1.2);margin_bottom(Em1.2);font_size(Em1.25);line_height(Num1.6);];](* Link and strong rules *)letlink_and_strong_rulesbase=[(* Links *)Css.rule~selector:(wherebasea)[color(Css.Varprose_links_v);Css.font_weight(Weight500.);text_decoration(Shorthand{lines=[Underline];style=None;color=None;thickness=None;});];(* Strong *)Css.rule~selector:(wherebasestrong)[Css.color(Css.Varprose_bold_v);Css.font_weight(Weight600.)];(* Strong inherit rules - group multiple selectors *)Css.rule~selector:(Css.Selector.list[wherebase(Css.Selector.combineaCss.Selector.Descendantstrong);wherebase(Css.Selector.combineblockquoteCss.Selector.Descendantstrong);wherebase(Css.Selector.combine(Css.Selector.combinetheadCss.Selector.Descendantth)Css.Selector.Descendantstrong);])[Css.colorInherit];](* Case-insensitive ol[type] rule *)letol_type_cibaseletterstyle=Css.rule~selector:(wherebase(Css.Selector.compound[ol;type_attrletter]))[list_style_typestyle](* Case-sensitive ol[type] rule *)letol_type_csbaseletterstyle=letcs_attr=Css.Selector.attribute~flag:Sensitive"type"(Exactletter)inCss.rule~selector:(wherebase(Css.Selector.compound[ol;cs_attr]))[list_style_typestyle](* Ordered list type variant rules *)letol_type_variant_rulesbase=[ol_type_cibase"A"Upper_alpha;ol_type_cibase"a"Lower_alpha;ol_type_csbase"A"Upper_alpha;ol_type_csbase"a"Lower_alpha;ol_type_cibase"I"Upper_roman;ol_type_cibase"i"Lower_roman;ol_type_csbase"I"Upper_roman;ol_type_csbase"i"Lower_roman;ol_type_cibase"1"Decimal;](* List marker rules *)letlist_marker_rulesbase=[Css.rule~selector:(Css.Selector.compound[wherebase(Css.Selector.combineolCss.Selector.Childli);Css.Selector.Marker;])[Css.color(Css.Varprose_counters_v);Css.font_weight(Weight400.)];Css.rule~selector:(Css.Selector.compound[wherebase(Css.Selector.combineulCss.Selector.Childli);Css.Selector.Marker;])[Css.color(Css.Varprose_bullets_v)];](* Lists with markers (markers come AFTER the ul rule like Tailwind) *)letlist_and_marker_rulesbase=[(* Lists *)Css.rule~selector:(wherebaseol)[margin_top(Em1.25);margin_bottom(Em1.25);padding_inline_start(Em1.625);list_style_typeDecimal;];]@ol_type_variant_rulesbase@[Css.rule~selector:(wherebaseul)[margin_top(Em1.25);margin_bottom(Em1.25);padding_inline_start(Em1.625);list_style_typeDisc;];](* Markers come AFTER ul rule to match Tailwind *)@list_marker_rulesbase(* Blockquote and pseudo-element rules *)letblockquote_rulesbase=[Css.rule~selector:(wherebaseblockquote)[color(Css.Varprose_quotes_v);border_inline_start_width(Rem0.25);border_inline_start_color(Css.Varprose_quote_borders_v);quotes(Pairs[(* " and " - left/right double quotes *)("\xe2\x80\x9c","\xe2\x80\x9d");(* ' and ' - left/right single quotes *)("\xe2\x80\x98","\xe2\x80\x99");]);margin_top(Em1.6);margin_bottom(Em1.6);padding_inline_start(Em1.0);font_styleItalic;Css.font_weight(Weight500.);];(* Blockquote pseudo-elements come AFTER blockquote rule *)Css.rule~selector:(with_before(wherebase(Css.Selector.compound[Css.Selector.combineblockquoteCss.Selector.Descendantp;Css.Selector.First_of_type;])))[contentOpen_quote];Css.rule~selector:(with_after(wherebase(Css.Selector.compound[Css.Selector.combineblockquoteCss.Selector.Descendantp;Css.Selector.Last_of_type;])))[contentClose_quote];](* Structural elements with blockquote pseudo-elements interleaved *)letstructural_element_rulesbase=[(* Definition terms *)Css.rule~selector:(wherebasedt)[color(Css.Varprose_headings_v);margin_top(Em1.25);Css.font_weight(Weight600.);];(* Horizontal rules *)Css.rule~selector:(wherebasehr)[border_color(Css.Varprose_hr_v);border_top_width(Px1.0);margin_top(Em3.0);margin_bottom(Em3.0);];]@blockquote_rulesbase(* Base prose rules - combines all element rules *)letbase_prose_rules()=letbase="prose"inletmain_rule=Css.rule~selector:(Css.Selector.class_"prose")[Css.color(Css.Varprose_body_v);Css.max_width(Ch65.0)]inletvariables_rule=Css.rule~selector:(Css.Selector.class_"prose")(css_variables@[Css.font_size(Rem1.0);Css.line_height(Num1.75)])in[main_rule]@paragraph_and_text_rulesbase@link_and_strong_rulesbase@list_and_marker_rulesbase@structural_element_rulesbase@heading_rulesbase@media_rulesbase@kbd_rulesbase@code_rulesbase@table_rulesbase@figure_rulesbase@[variables_rule]@additional_rulesbase(* Configuration type for typography sizes *)typesize_config={base_font_size:Css.length;base_line_height:float;p_margin_y:Css.length;lead_margin_top:Css.length;lead_margin_bottom:Css.length;lead_font_size:Css.length;lead_line_height:float;blockquote_margin_y:Css.length;blockquote_padding_start:Css.length;h1_margin_top:Css.length;h1_margin_bottom:Css.length;h1_font_size:Css.length;h1_line_height:float;h2_margin_top:Css.length;h2_margin_bottom:Css.length;h2_font_size:Css.length;h2_line_height:float;h3_margin_top:Css.length;h3_margin_bottom:Css.length;h3_font_size:Css.length;h3_line_height:float;h4_margin_top:Css.length;h4_margin_bottom:Css.length;h4_line_height:float;img_margin_y:Css.length;kbd_padding_y:Css.length;kbd_padding_x:Css.length;kbd_font_size:Css.length;kbd_border_radius:Css.length;code_font_size:Css.length;h2_code_font_size:Css.length;h3_code_font_size:Css.length;pre_padding_y:Css.length;pre_padding_x:Css.length;pre_border_radius:Css.length;pre_margin_top:Css.length;pre_margin_bottom:Css.length;pre_font_size:Css.length;pre_line_height:float;list_margin_y:Css.length;list_padding_start:Css.length;li_margin_y:Css.length;li_padding_start:Css.length;li_p_margin_y:Css.length;li_p_first_margin_top:Css.length;li_p_last_margin_bottom:Css.length;nested_list_margin_y:Css.length;dl_margin_y:Css.length;dt_margin_top:Css.length;dd_margin_top:Css.length;dd_padding_start:Css.length;hr_margin_y:Css.length;table_font_size:Css.length;table_line_height:float;thead_th_padding_x:Css.length;thead_th_padding_bottom:Css.length;tbody_td_padding_y:Css.length;tbody_td_padding_x:Css.length;figure_margin_y:Css.length;figcaption_margin_top:Css.length;figcaption_font_size:Css.length;figcaption_line_height:float;}(* Typography heading rules for size variants *)lettypography_heading_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_elementh1)[Css.margin_topc.h1_margin_top;Css.margin_bottomc.h1_margin_bottom;Css.font_sizec.h1_font_size;Css.line_height(Numc.h1_line_height);];Css.rule~selector:(selector++prose_where_elementh2)[Css.margin_topc.h2_margin_top;Css.margin_bottomc.h2_margin_bottom;Css.font_sizec.h2_font_size;Css.line_height(Numc.h2_line_height);];Css.rule~selector:(selector++prose_where_elementh3)[Css.margin_topc.h3_margin_top;Css.margin_bottomc.h3_margin_bottom;Css.font_sizec.h3_font_size;Css.line_height(Numc.h3_line_height);];Css.rule~selector:(selector++prose_where_elementh4)[Css.margin_topc.h4_margin_top;Css.margin_bottomc.h4_margin_bottom;Css.line_height(Numc.h4_line_height);];](* Typography nested list paragraph and definition list rules *)lettypography_list_nested_rulesselectorc=letopenSelectorin[(* Nested list paragraphs *)Css.rule~selector:(prose_child_selectorselector(ul>>li++p))[Css.margin_topc.li_p_margin_y;Css.margin_bottomc.li_p_margin_y];Css.rule~selector:(prose_child_selectorselector(ul>>li>>(p&&first_child)))[Css.margin_topc.li_p_first_margin_top];Css.rule~selector:(prose_child_selectorselector(ul>>li>>(p&&last_child)))[Css.margin_bottomc.li_p_last_margin_bottom];Css.rule~selector:(prose_child_selectorselector(ol>>li>>(p&&first_child)))[Css.margin_topc.li_p_first_margin_top];Css.rule~selector:(prose_child_selectorselector(ol>>li>>(p&&last_child)))[Css.margin_bottomc.li_p_last_margin_bottom];(* Nested lists *)Css.rule~selector:(selector++prose_where_elementnested_lists)[Css.margin_topc.nested_list_margin_y;Css.margin_bottomc.nested_list_margin_y;];(* Definition lists *)Css.rule~selector:(selector++prose_where_elementdl)[Css.margin_topc.dl_margin_y;Css.margin_bottomc.dl_margin_y];Css.rule~selector:(selector++prose_where_elementdt)[Css.margin_topc.dt_margin_top];Css.rule~selector:(selector++prose_where_elementdd)[Css.margin_topc.dd_margin_top;padding_inline_startc.dd_padding_start;];](* Typography list rules for size variants *)lettypography_list_rulesselectorc=letopenSelectorin[Css.rule~selector:(Css.Selector.list[selector++prose_where_elementol;selector++prose_where_elementul;])[Css.margin_topc.list_margin_y;Css.margin_bottomc.list_margin_y;Css.padding_inline_startc.list_padding_start;];Css.rule~selector:(selector++prose_where_elementli)[Css.margin_topc.li_margin_y;Css.margin_bottomc.li_margin_y];(* List items with padding *)Css.rule~selector:(Css.Selector.list[selector++prose_where_element(ol>>li);selector++prose_where_element(ul>>li);])[Css.padding_inline_startc.li_padding_start];]@typography_list_nested_rulesselectorc(* Typography table body and footer cell rules *)lettypography_table_cell_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_element(Css.Selector.list[tbody++td;tfoot++td]))[Css.padding_topc.tbody_td_padding_y;Css.padding_inline_endc.tbody_td_padding_x;Css.padding_bottomc.tbody_td_padding_y;Css.padding_inline_startc.tbody_td_padding_x;];(* First and last table cells *)Css.rule~selector:(selector++prose_where_element(Css.Selector.list[tbody++(td&&first_child);tfoot++(td&&first_child)]))[Css.padding_inline_startZero];Css.rule~selector:(selector++prose_where_element(Css.Selector.list[tbody++(td&&last_child);tfoot++(td&&last_child)]))[Css.padding_inline_endZero];](* Typography table rules for size variants *)lettypography_table_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_elementtable)[Css.font_sizec.table_font_size;Css.line_height(Numc.table_line_height);];Css.rule~selector:(selector++prose_where_element(thead++th))[Css.padding_inline_endc.thead_th_padding_x;Css.padding_bottomc.thead_th_padding_bottom;Css.padding_inline_startc.thead_th_padding_x;];Css.rule~selector:(selector++prose_where_element(thead++(th&&first_child)))[Css.padding_inline_startZero];Css.rule~selector:(selector++prose_where_element(thead++(th&&last_child)))[Css.padding_inline_endZero];]@typography_table_cell_rulesselectorc(* Typography figure and boundary rules for size variants *)lettypography_figure_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_elementfigure)[Css.margin_topc.figure_margin_y;Css.margin_bottomc.figure_margin_y];Css.rule~selector:(selector++prose_where_element(combinefigureChilduniversal))[Css.margin_topZero;Css.margin_bottomZero];Css.rule~selector:(selector++prose_where_elementfigcaption)[Css.margin_topc.figcaption_margin_top;Css.font_sizec.figcaption_font_size;Css.line_height(Numc.figcaption_line_height);];(* First and last child margins *)Css.rule~selector:(prose_child_selectorselectorfirst_child)[Css.margin_topZero];Css.rule~selector:(prose_child_selectorselectorlast_child)[Css.margin_bottomZero];](* Typography image and media rules for size variants *)lettypography_media_rulesselectorc=letopenSelectorin[Css.rule~selector:(Css.Selector.list[selector++prose_where_elementimg;selector++prose_where_elementpicture;])[Css.margin_topc.img_margin_y;Css.margin_bottomc.img_margin_y];Css.rule~selector:(selector++prose_where_element(picture>>img))[Css.margin_topZero;Css.margin_bottomZero];Css.rule~selector:(selector++prose_where_elementvideo)[Css.margin_topc.img_margin_y;Css.margin_bottomc.img_margin_y];](* Typography code element rules for size variants *)lettypography_code_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_element(element"kbd"))[Css.padding_topc.kbd_padding_y;Css.padding_inline_endc.kbd_padding_x;Css.padding_bottomc.kbd_padding_y;border_radius(radiusc.kbd_border_radius);Css.padding_inline_startc.kbd_padding_x;Css.font_sizec.kbd_font_size;];Css.rule~selector:(selector++prose_where_elementcode)[Css.font_sizec.code_font_size];Css.rule~selector:(selector++prose_where_element(h2++code))[Css.font_sizec.h2_code_font_size];Css.rule~selector:(selector++prose_where_element(h3++code))[Css.font_sizec.h3_code_font_size];Css.rule~selector:(selector++prose_where_elementpre)[Css.padding_topc.pre_padding_y;Css.padding_inline_endc.pre_padding_x;Css.padding_bottomc.pre_padding_y;border_radius(radiusc.pre_border_radius);Css.margin_topc.pre_margin_top;Css.margin_bottomc.pre_margin_bottom;Css.padding_inline_startc.pre_padding_x;Css.font_sizec.pre_font_size;Css.line_height(Numc.pre_line_height);];](* Typography horizontal rule and following element rules *)lettypography_hr_rulesselectorc=letopenSelectorin[Css.rule~selector:(selector++prose_where_elementhr)[Css.margin_topc.hr_margin_y;Css.margin_bottomc.hr_margin_y];(* Following elements *)Css.rule~selector:(Css.Selector.list[selector++prose_where_element(siblinghr);selector++prose_where_element(siblingh2);selector++prose_where_element(siblingh3);selector++prose_where_element(siblingh4);])[Css.margin_topZero];](* Helper function to generate typography rules for different sizes *)lettypography_rulesselectorc=letopenSelectorin[(* Base rule *)Css.rule~selector[Css.font_sizec.base_font_size;Css.line_height(Numc.base_line_height);];(* Paragraph *)Css.rule~selector:(selector++prose_where_elementp)[Css.margin_topc.p_margin_y;Css.margin_bottomc.p_margin_y];(* Lead paragraph *)Css.rule~selector:(selector++prose_where_element(class_attr"lead"))[Css.margin_topc.lead_margin_top;Css.margin_bottomc.lead_margin_bottom;Css.font_sizec.lead_font_size;Css.line_height(Numc.lead_line_height);];(* Blockquote *)Css.rule~selector:(selector++prose_where_elementblockquote)[Css.margin_topc.blockquote_margin_y;Css.margin_bottomc.blockquote_margin_y;Css.padding_inline_startc.blockquote_padding_start;];]@typography_heading_rulesselectorc@typography_media_rulesselectorc@typography_code_rulesselectorc@typography_list_rulesselectorc@typography_hr_rulesselectorc@typography_table_rulesselectorc@typography_figure_rulesselectorc(* Size configuration for prose-sm *)letsm_config={base_font_size=Rem0.875;base_line_height=1.71429;p_margin_y=Em1.14286;lead_margin_top=Em0.888889;lead_margin_bottom=Em0.888889;lead_font_size=Em1.28571;lead_line_height=1.55556;blockquote_margin_y=Em1.33333;blockquote_padding_start=Em1.11111;h1_margin_top=Zero;h1_margin_bottom=Em0.8;h1_font_size=Em2.14286;h1_line_height=1.2;h2_margin_top=Em1.6;h2_margin_bottom=Em0.8;h2_font_size=Em1.42857;h2_line_height=1.4;h3_margin_top=Em1.55556;h3_margin_bottom=Em0.444444;h3_font_size=Em1.28571;h3_line_height=1.55556;h4_margin_top=Em1.42857;h4_margin_bottom=Em0.571429;h4_line_height=1.42857;img_margin_y=Em1.71429;kbd_padding_y=Em0.142857;kbd_padding_x=Em0.357143;kbd_font_size=Em0.857143;kbd_border_radius=Rem0.3125;code_font_size=Em0.857143;h2_code_font_size=Em0.9;h3_code_font_size=Em0.888889;pre_padding_y=Em0.666667;pre_padding_x=Em1.0;pre_border_radius=Rem0.25;pre_margin_top=Em1.66667;pre_margin_bottom=Em1.66667;pre_font_size=Em0.857143;pre_line_height=1.66667;list_margin_y=Em1.14286;list_padding_start=Em1.57143;li_margin_y=Em0.285714;li_padding_start=Em0.428571;li_p_margin_y=Em0.571429;li_p_first_margin_top=Em1.14286;li_p_last_margin_bottom=Em1.14286;nested_list_margin_y=Em0.571429;dl_margin_y=Em1.14286;dt_margin_top=Em1.14286;dd_margin_top=Em0.285714;dd_padding_start=Em1.57143;hr_margin_y=Em2.85714;table_font_size=Em0.857143;table_line_height=1.5;thead_th_padding_x=Em1.0;thead_th_padding_bottom=Em0.666667;tbody_td_padding_y=Em0.666667;tbody_td_padding_x=Em1.0;figure_margin_y=Em1.71429;figcaption_margin_top=Em0.666667;figcaption_font_size=Em0.857143;figcaption_line_height=1.33333;}(* Size configuration for prose-lg *)letlg_config={base_font_size=Rem1.125;base_line_height=1.77778;p_margin_y=Em1.33333;lead_margin_top=Em1.09091;lead_margin_bottom=Em1.09091;lead_font_size=Em1.22222;lead_line_height=1.45455;blockquote_margin_y=Em1.66667;blockquote_padding_start=Em1.0;h1_margin_top=Zero;h1_margin_bottom=Em0.833333;h1_font_size=Em2.66667;h1_line_height=1.0;h2_margin_top=Em1.86667;h2_margin_bottom=Em1.06667;h2_font_size=Em1.66667;h2_line_height=1.33333;h3_margin_top=Em1.66667;h3_margin_bottom=Em0.666667;h3_font_size=Em1.33333;h3_line_height=1.5;h4_margin_top=Em1.77778;h4_margin_bottom=Em0.444444;h4_line_height=1.55556;img_margin_y=Em1.77778;kbd_padding_y=Em0.222222;kbd_padding_x=Em0.444444;kbd_font_size=Em0.888889;kbd_border_radius=Rem0.3125;code_font_size=Em0.888889;h2_code_font_size=Em0.866667;h3_code_font_size=Em0.875;pre_padding_y=Em1.0;pre_padding_x=Em1.5;pre_border_radius=Rem0.375;pre_margin_top=Em2.0;pre_margin_bottom=Em2.0;pre_font_size=Em0.888889;pre_line_height=1.75;list_margin_y=Em1.33333;list_padding_start=Em1.55556;li_margin_y=Em0.666667;li_padding_start=Em0.444444;li_p_margin_y=Em0.888889;li_p_first_margin_top=Em1.33333;li_p_last_margin_bottom=Em1.33333;nested_list_margin_y=Em0.888889;dl_margin_y=Em1.33333;dt_margin_top=Em1.33333;dd_margin_top=Em0.666667;dd_padding_start=Em1.55556;hr_margin_y=Em3.11111;table_font_size=Em0.888889;table_line_height=1.5;thead_th_padding_x=Em0.75;thead_th_padding_bottom=Em0.75;tbody_td_padding_y=Em0.75;tbody_td_padding_x=Em0.75;figure_margin_y=Em1.77778;figcaption_margin_top=Em1.0;figcaption_font_size=Em0.888889;figcaption_line_height=1.5;}(* Size configuration for prose-xl *)letxl_config={base_font_size=Rem1.25;base_line_height=1.8;p_margin_y=Em1.2;lead_margin_top=Em1.0;lead_margin_bottom=Em1.0;lead_font_size=Em1.2;lead_line_height=1.5;blockquote_margin_y=Em1.6;blockquote_padding_start=Em1.06667;h1_margin_top=Zero;h1_margin_bottom=Em0.857143;h1_font_size=Em2.8;h1_line_height=1.0;h2_margin_top=Em1.55556;h2_margin_bottom=Em0.888889;h2_font_size=Em1.8;h2_line_height=1.11111;h3_margin_top=Em1.6;h3_margin_bottom=Em0.666667;h3_font_size=Em1.5;h3_line_height=1.33333;h4_margin_top=Em1.8;h4_margin_bottom=Em0.6;h4_line_height=1.6;img_margin_y=Em2.0;kbd_padding_y=Em0.25;kbd_padding_x=Em0.4;kbd_font_size=Em0.9;kbd_border_radius=Rem0.3125;code_font_size=Em0.9;h2_code_font_size=Em0.861111;h3_code_font_size=Em0.9;pre_padding_y=Em1.11111;pre_padding_x=Em1.33333;pre_border_radius=Rem0.5;pre_margin_top=Em2.0;pre_margin_bottom=Em2.0;pre_font_size=Em0.9;pre_line_height=1.77778;list_margin_y=Em1.2;list_padding_start=Em1.6;li_margin_y=Em0.6;li_padding_start=Em0.4;li_p_margin_y=Em0.8;li_p_first_margin_top=Em1.2;li_p_last_margin_bottom=Em1.2;nested_list_margin_y=Em0.8;dl_margin_y=Em1.2;dt_margin_top=Em1.2;dd_margin_top=Em0.6;dd_padding_start=Em1.6;hr_margin_y=Em2.8;table_font_size=Em0.9;table_line_height=1.55556;thead_th_padding_x=Em0.666667;thead_th_padding_bottom=Em0.888889;tbody_td_padding_y=Em0.888889;tbody_td_padding_x=Em0.666667;figure_margin_y=Em2.0;figcaption_margin_top=Em1.0;figcaption_font_size=Em0.9;figcaption_line_height=1.55556;}(* Size configuration for prose-2xl *)letxl2_config={base_font_size=Rem1.5;base_line_height=1.66667;p_margin_y=Em1.33333;lead_margin_top=Em1.06667;lead_margin_bottom=Em1.06667;lead_font_size=Em1.25;lead_line_height=1.46667;blockquote_margin_y=Em1.77778;blockquote_padding_start=Em1.11111;h1_margin_top=Zero;h1_margin_bottom=Em0.875;h1_font_size=Em2.66667;h1_line_height=1.0;h2_margin_top=Em1.5;h2_margin_bottom=Em0.833333;h2_font_size=Em2.0;h2_line_height=1.08333;h3_margin_top=Em1.55556;h3_margin_bottom=Em0.666667;h3_font_size=Em1.5;h3_line_height=1.22222;h4_margin_top=Em1.66667;h4_margin_bottom=Em0.666667;h4_line_height=1.5;img_margin_y=Em2.0;kbd_padding_y=Em0.25;kbd_padding_x=Em0.333333;kbd_font_size=Em0.833333;kbd_border_radius=Rem0.375;code_font_size=Em0.833333;h2_code_font_size=Em0.875;h3_code_font_size=Em0.888889;pre_padding_y=Em1.2;pre_padding_x=Em1.6;pre_border_radius=Rem0.5;pre_margin_top=Em2.0;pre_margin_bottom=Em2.0;pre_font_size=Em0.833333;pre_line_height=1.8;list_margin_y=Em1.33333;list_padding_start=Em1.58333;li_margin_y=Em0.5;li_padding_start=Em0.416667;li_p_margin_y=Em0.833333;li_p_first_margin_top=Em1.33333;li_p_last_margin_bottom=Em1.33333;nested_list_margin_y=Em0.666667;dl_margin_y=Em1.33333;dt_margin_top=Em1.33333;dd_margin_top=Em0.5;dd_padding_start=Em1.58333;hr_margin_y=Em3.0;table_font_size=Em0.833333;table_line_height=1.4;thead_th_padding_x=Em0.6;thead_th_padding_bottom=Em0.8;tbody_td_padding_y=Em0.8;tbody_td_padding_x=Em0.6;figure_margin_y=Em2.0;figcaption_margin_top=Em1.0;figcaption_font_size=Em0.833333;figcaption_line_height=1.6;}letsm_size_rulesselector=typography_rules(Css.Selector.class_selector)sm_configletlg_size_rulesselector=typography_rules(Css.Selector.class_selector)lg_configletxl_size_rulesselector=typography_rules(Css.Selector.class_selector)xl_configletxl2_size_rulesselector=typography_rules(Css.Selector.class_selector)xl2_config(* Helper to create declarations from a list of (var, value) pairs *)letbind_prose_varsbindings=List.map(fun(var,value)->Var.setvarvalue)bindings(* The two ways a palette reaches the sheet: as the prose colours themselves,
and as the inverted set [.prose-invert] swaps in. *)letnormal_bindingsp=bind_prose_vars[(prose_body_var,p.body);(prose_headings_var,p.headings);(prose_lead_var,p.lead);(prose_links_var,p.links);(prose_bold_var,p.bold);(prose_counters_var,p.counters);(prose_bullets_var,p.bullets);(prose_hr_var,p.hr);(prose_quotes_var,p.quotes);(prose_quote_borders_var,p.quote_borders);(prose_captions_var,p.captions);(prose_kbd_var,p.kbd);(prose_kbd_shadows_var,p.kbd_shadows);(prose_code_var,p.code);(prose_pre_code_var,p.pre_code);(prose_pre_bg_var,p.pre_bg);(prose_th_borders_var,p.th_borders);(prose_td_borders_var,p.td_borders);]letinvert_bindingsp=bind_prose_vars[(prose_invert_body_var,p.body);(prose_invert_headings_var,p.headings);(prose_invert_lead_var,p.lead);(prose_invert_links_var,p.links);(prose_invert_bold_var,p.bold);(prose_invert_counters_var,p.counters);(prose_invert_bullets_var,p.bullets);(prose_invert_hr_var,p.hr);(prose_invert_quotes_var,p.quotes);(prose_invert_quote_borders_var,p.quote_borders);(prose_invert_captions_var,p.captions);(prose_invert_kbd_var,p.kbd);(prose_invert_kbd_shadows_var,p.kbd_shadows);(prose_invert_code_var,p.code);(prose_invert_pre_code_var,p.pre_code);(prose_invert_pre_bg_var,p.pre_bg);(prose_invert_th_borders_var,p.th_borders);(prose_invert_td_borders_var,p.td_borders);](* Helper to create color variable bindings for color themes - returns
declarations *)letcolor_theme_bindingstheme_name=matchtheme_namewith|"gray"->normal_bindingsgray_normal@invert_bindingsgray_invert|"slate"->normal_bindingsslate_normal@invert_bindingsslate_invert|"zinc"->normal_bindingszinc_normal@invert_bindingszinc_invert|"neutral"->normal_bindingsneutral_normal@invert_bindingsneutral_invert|"stone"->normal_bindingsstone_normal@invert_bindingsstone_invert|_->[](* prose-invert remaps every --tw-prose-* to its --tw-prose-invert-*
counterpart, the way Tailwind's [.prose-invert] does. *)letinvert_remap_bindings=normal_bindings{body=Css.Var(sndtheme.invert_body);headings=Css.Var(sndtheme.invert_headings);lead=Css.Var(sndtheme.invert_lead);links=Css.Var(sndtheme.invert_links);bold=Css.Var(sndtheme.invert_bold);counters=Css.Var(sndtheme.invert_counters);bullets=Css.Var(sndtheme.invert_bullets);hr=Css.Var(sndtheme.invert_hr);quotes=Css.Var(sndtheme.invert_quotes);quote_borders=Css.Var(sndtheme.invert_quote_borders);captions=Css.Var(sndtheme.invert_captions);kbd=Css.Var(sndtheme.invert_kbd);kbd_shadows=Css.Var(sndtheme.invert_kbd_shadows);code=Css.Var(sndtheme.invert_code);pre_code=Css.Var(sndtheme.invert_pre_code);pre_bg=Css.Var(sndtheme.invert_pre_bg);th_borders=Css.Var(sndtheme.invert_th_borders);td_borders=Css.Var(sndtheme.invert_td_borders);}(* Accent colour themes (prose-orange, ...) only override the link colours,
normal and inverted. Values taken from the Tailwind typography plugin. *)letaccent_color_bindings=function|"orange"->bind_prose_vars[(prose_links_var,Css.oklch64.60.22241.116);(prose_invert_links_var,Css.oklch70.50.21347.604);]|_->[]letto_css_rulesvariant=matchvariantwith|`Base->base_prose_rules()|`Sm->sm_size_rules"prose-sm"|`Lg->lg_size_rules"prose-lg"|`Xl->xl_size_rules"prose-xl"|`Xl2->xl2_size_rules"prose-2xl"|`Gray->[Css.rule~selector:(Css.Selector.class_"prose-gray")(color_theme_bindings"gray");]|`Slate->[Css.rule~selector:(Css.Selector.class_"prose-slate")(color_theme_bindings"slate");]|`Zinc->[Css.rule~selector:(Css.Selector.class_"prose-zinc")(color_theme_bindings"zinc");]|`Neutral->[Css.rule~selector:(Css.Selector.class_"prose-neutral")(color_theme_bindings"neutral");]|`Stone->[Css.rule~selector:(Css.Selector.class_"prose-stone")(color_theme_bindings"stone");]|`Invert->[Css.rule~selector:(Css.Selector.class_"prose-invert")invert_remap_bindings;]|`Orange->[Css.rule~selector:(Css.Selector.class_"prose-orange")(accent_color_bindings"orange");]letpp=function|`Base->"Base"|`Sm->"Sm"|`Lg->"Lg"|`Xl->"Xl"|`Xl2->"Xl2"|`Gray->"Gray"|`Slate->"Slate"|`Zinc->"Zinc"|`Neutral->"Neutral"|`Stone->"Stone"|`Invert->"Invert"|`Orange->"Orange"(** Prose utility constructors *)letprose_stylevariant=letrules=to_css_rulesvariantinStyle.style~rules:(Somerules)[](** Generate complete prose stylesheet *)letstylesheet()=(* Generate CSS for all prose variants *)letbase_rules=to_css_rules`Baseinletsm_rules=to_css_rules`Sminletlg_rules=to_css_rules`Lginletxl_rules=to_css_rules`Xlinletxl2_rules=to_css_rules`Xl2inletgray_rules=to_css_rules`Grayinletslate_rules=to_css_rules`Slatein(* Combine all rules *)letall_rules=List.concat[base_rules;sm_rules;lg_rules;xl_rules;xl2_rules;gray_rules;slate_rules;]in(* Return raw rules; caller composes into a stylesheet if needed *)all_rulesletniet=Style.style~rules:(Some[])[](* Handler for prose size variants - priority 2 *)moduleHandler=struct(** Local prose utility type for size variants *)typet=|Prose|Prose_sm|Prose_lg|Prose_xl|Prose_2xl|Lead|Not_prose(** Extensible variant for prose utilities *)(** Priority for prose size utilities *)letname="prose"letpriority_=2(* Same as margin to allow interleaving by suborder *)(** {1 Utility Conversion Functions} *)letto_style_theme=function|Prose->prose_style`Base|Prose_sm->prose_style`Sm|Prose_lg->prose_style`Lg|Prose_xl->prose_style`Xl|Prose_2xl->prose_style`Xl2|Lead->niet|Not_prose->nietletto_class=function|Prose->"prose"|Prose_sm->"prose-sm"|Prose_lg->"prose-lg"|Prose_xl->"prose-xl"|Prose_2xl->"prose-2xl"|Lead->"lead"|Not_prose->"not-prose"letof_class_themeclass_name=letparts=Parse.split_classclass_nameinmatchpartswith|["prose"]->OkProse|["prose";"sm"]->OkProse_sm|["prose";"lg"]->OkProse_lg|["prose";"xl"]->OkProse_xl|["prose";"2xl"]->OkProse_2xl|["lead"]->OkLead|["not";"prose"]->OkNot_prose|_->Error(`Msg"Not a prose size utility")letsuborder=function(* Prose sorts among the priority-2 margin utilities exactly where Tailwind
puts it: after the inline-end margins (me-*, ~4.2-4.3M) and before the
top margins (mt-*, negatives at 5.0M). *)|Prose->4650000|Prose_2xl->4650001(* Alphabetical: 2xl before lg, sm, xl *)|Prose_lg->4650002|Prose_sm->4650003|Prose_xl->4650004|Lead->4650005|Not_prose->4650006letexamples=[]end(* Handler for prose color variants - priority 21 *)moduleColor_Handler=structtypet=[`Gray|`Slate|`Zinc|`Neutral|`Stone|`Invert|`Orange](** The prose colour variants, as {!prose_style} names them. *)(** Extensible variant for prose color utilities *)(** Priority for prose color utilities *)letname="prose-color"letpriority_=25(* Same as color utilities *)(** {1 Utility Conversion Functions} *)letto_style_themevariant=prose_stylevariantletto_class=function|`Gray->"prose-gray"|`Slate->"prose-slate"|`Zinc->"prose-zinc"|`Neutral->"prose-neutral"|`Stone->"prose-stone"|`Invert->"prose-invert"|`Orange->"prose-orange"letof_class_themeclass_name=letparts=Parse.split_classclass_nameinmatchpartswith|["prose";"gray"]->Ok`Gray|["prose";"slate"]->Ok`Slate|["prose";"zinc"]->Ok`Zinc|["prose";"neutral"]->Ok`Neutral|["prose";"stone"]->Ok`Stone|["prose";"invert"]->Ok`Invert|["prose";"orange"]->Ok`Orange|_->Error(`Msg"Not a prose color utility")letsuborder=function(* Prose color utilities come after text colors (20000-29999). The gray
ramps sort alphabetically by class name, matching Tailwind's order (gray,
neutral, slate, stone, zinc), then invert and orange. *)|`Gray->30000|`Neutral->30001|`Slate->30002|`Stone->30003|`Zinc->30004|`Invert->30005|`Orange->30006letexamples=[]endmoduleUtility_factory=Utility.Make(Handler)(** Register both handlers with Utility system *)moduleColor_utility=Utility.Make(Color_Handler)(** Public API *)letutility=Utility_factory.vletcolor_utility=Color_utility.vletprose=utilityHandler.Proseletprose_sm=utilityHandler.Prose_smletprose_lg=utilityHandler.Prose_lgletprose_xl=utilityHandler.Prose_xlletprose_2xl=utilityHandler.Prose_2xlletprose_gray=color_utility`Grayletprose_slate=color_utility`Slateletprose_zinc=color_utility`Zincletprose_neutral=color_utility`Neutralletprose_stone=color_utility`Stoneletprose_invert=color_utility`Invertletprose_orange=color_utility`Orangeletprose_lead=utilityHandler.Leadletnot_prose=utilityHandler.Not_prose