/* roicp-nature-microsaas.css v1.0.4 (2026-10-22; 1.0.1 = demo banner inside header.top; 1.0.2 = lake-dawn hero art; 1.0.3 = hero 'Try the demo' .rn-try hidden while in demo; 1.0.4 = status colours on rn tokens for contrast) - adapter that maps the shared ROICP micro-SaaS markup
   (header.top, .hero, .btn, .card, .pill, .band, .stat, #drop, .tabs, .disc, .tbl) onto roicp-nature.css tokens.
   Load AFTER the app's own <style> and after roicp-nature.css. Requires class="rn" on <html>. */
.rn body{background:var(--rn-paper)}
.rn a{font-weight:600}
.rn .wrap{max-width:var(--rn-max)}
.rn header.top{position:sticky;top:0;z-index:50;border-bottom:1px solid var(--rn-line);background:rgba(251,248,241,.9);-webkit-backdrop-filter:blur(12px) saturate(1.3);backdrop-filter:blur(12px) saturate(1.3)}
.rn header.top .rn-demo{position:static}
.rn header.top .brand{font-family:var(--rn-serif);font-weight:700;color:var(--rn-ink)}
.rn header.top .brand span{color:var(--rn-moss)}
.rn header.top .brand{display:block;padding-block:6px;margin-block:-6px}
.rn details>summary{padding-block:9px}
.rn header.top nav a{display:inline-flex;align-items:center;min-height:var(--rn-tap);padding:0 10px;margin-left:4px;border-radius:10px;color:var(--rn-ink);text-decoration:none}
.rn header.top nav a:hover{background:rgba(79,138,91,.12)}
.rn .hero{border-bottom:1px solid var(--rn-line);background:radial-gradient(90% 120% at 85% 0%,rgba(31,111,139,.14),transparent 60%),radial-gradient(70% 100% at 0% 100%,rgba(79,138,91,.16),transparent 60%),linear-gradient(180deg,#f4f1e6,var(--rn-paper))}
.rn .hero::before{content:"";position:absolute;inset:auto 0 0 0;height:4px;background:var(--rn-hairline);opacity:.8}
.rn .hero svg.scene{width:min(560px,46%);height:auto;max-height:100%;opacity:1;border-radius:var(--rn-r-xl) 0 0 0;-webkit-mask-image:linear-gradient(90deg,transparent,#000 22%);mask-image:linear-gradient(90deg,transparent,#000 22%)}
@media(max-width:1100px){.rn .hero svg.scene{position:static;display:block;width:100%;height:120px;border-radius:0;-webkit-mask-image:none;mask-image:none}}
.rn h1{font-size:var(--rn-fs-h1)}
.rn .lead{color:var(--rn-ink-2);font-weight:500}
.rn .note{color:var(--rn-mut);font-size:var(--rn-fs-sm,.875rem)}
.rn .pill{border:1px solid rgba(47,93,70,.25);border-radius:var(--rn-r-pill);background:rgba(79,138,91,.12);color:var(--rn-moss);letter-spacing:.12em;padding:6px 12px;font-size:.7rem}
.rn .btn{display:inline-flex;align-items:center;justify-content:center;min-height:var(--rn-tap);padding:0 20px;border:1px solid rgba(20,32,26,.25);border-radius:var(--rn-r-md);background:linear-gradient(180deg,var(--rn-moss-2),var(--rn-moss));color:#fff;font-weight:650;box-shadow:0 1px 0 rgba(255,255,255,.25) inset,0 10px 22px -12px rgba(47,93,70,.9);transition:box-shadow var(--rn-t) var(--rn-ease),filter var(--rn-t) var(--rn-ease)}
.rn .btn:hover{box-shadow:0 1px 0 rgba(255,255,255,.25) inset,0 14px 28px -12px rgba(47,93,70,.95);filter:brightness(1.06)}
.rn .btn.alt{background:transparent;color:var(--rn-moss);border-color:rgba(47,93,70,.45);box-shadow:none}
.rn .btn.alt:hover{background:rgba(79,138,91,.08)}
.rn .card{border:1px solid var(--rn-line);border-radius:var(--rn-r-lg);background:linear-gradient(180deg,var(--rn-surface),var(--rn-paper));box-shadow:var(--rn-sh-2)}
.rn #drop{border:2px dashed rgba(31,111,139,.5);border-radius:var(--rn-r-lg);background:var(--rn-info-soft)}
.rn #drop.over{background:#d5e8ef}
.rn select,.rn input[type=number],.rn input[type=email],.rn input[type=text],.rn textarea{border:1px solid rgba(20,32,26,.28);border-radius:var(--rn-r-md)}
.rn .stat{border:1px solid var(--rn-line);border-radius:var(--rn-r-lg);background:var(--rn-surface);box-shadow:var(--rn-sh-1)}
.rn .stat b{font-family:var(--rn-serif);font-weight:600}
.rn .tbl,.rn pre#summary{border:1px solid var(--rn-line);border-radius:var(--rn-r-md)}
.rn .tabs button{border:1px solid rgba(47,93,70,.35);border-radius:var(--rn-r-pill);min-height:var(--rn-tap,44px);padding:6px 14px}
.rn .tabs button.on{background:var(--rn-moss);border-color:var(--rn-moss);color:#fff}
.rn .bar{background:linear-gradient(90deg,var(--rn-fern),var(--rn-lake));border:0;border-radius:var(--rn-r-pill)}
.rn .disc{border:1px solid rgba(146,64,14,.3);border-left:6px solid var(--rn-gold);background:var(--rn-warn-soft);border-radius:var(--rn-r-md)}
.rn .band{border:1px solid rgba(255,255,255,.08);border-radius:var(--rn-r-xl);background:radial-gradient(120% 140% at 15% 0%,#3f7a5a 0%,#1f4a3a 55%,var(--rn-night) 100%);box-shadow:var(--rn-sh-3)}
.rn .band h2,.rn .band label{color:var(--rn-paper)}
.rn .band .note{color:#e8efe9}
.rn .band a:not(.btn){color:var(--rn-paper)}
.rn .band .btn{background:linear-gradient(180deg,#e6c27a,var(--rn-gold));color:var(--rn-ink)}
.rn .band input,.rn .band select{border-color:rgba(255,255,255,.4)}
.rn footer{border-top:1px solid var(--rn-line)}
.rn footer .wrap{font-size:var(--rn-fs-sm,.875rem)}
/* run 49: keep footer links whole (no mid-link split) from 390px; tighter word gaps on 390-479 phones keep the line count (<390 unchanged: nowrap added a line @375/380) */
@media(min-width:390px){.rn footer a{white-space:nowrap}}
@media(min-width:390px) and (max-width:479px){.rn footer .wrap{word-spacing:-.12em}}
/* run 50: same fix for 360-389px phones; nowrap + -.12em alone still added a line here, so add -.02em tracking (proven 0 added lines 360-389 x9). <360 untouched */
@media(min-width:360px) and (max-width:389px){.rn footer a{white-space:nowrap}.rn footer .wrap{word-spacing:-.12em;letter-spacing:-.02em}}
.rn .s-keep,.rn .s-ON_TIME{color:var(--rn-ok)}
.rn .stat.keep b,.rn .stat.ok b{color:var(--rn-ok)}
@media(max-width:600px){.rn .btn{width:100%;margin-right:0}.rn[data-demo] header.top{position:relative}}
.rn[data-demo] .rn-try{display:none}
.rn .s-BILLABLE{color:var(--rn-ok)}
.rn .s-review,.rn .s-LATE{color:var(--rn-warn)}
.rn .s-exclude,.rn .s-NO_CONTACT,.rn .s-NOT_BILLABLE{color:var(--rn-bad)}
.rn .tbl:focus-visible,.rn pre#summary:focus-visible{outline:none;box-shadow:var(--rn-focus)}
/* unify run 45 (2026-10-26): themed 16px checkbox/radio + label hit area; odd last stat spans the row on 2-col phones */
.rn input[type=checkbox],.rn input[type=radio]{width:16px;height:16px;margin:0 4px 0 0;flex:none;vertical-align:-3px;accent-color:var(--rn-moss);cursor:pointer}
.rn label:has(>input[type=checkbox]),.rn label:has(>input[type=radio]){cursor:pointer}
.rn input[type=checkbox]:focus-visible,.rn input[type=radio]:focus-visible{outline:none;box-shadow:var(--rn-focus)}
@media(max-width:480px){.rn .stats>.stat:last-child:nth-child(odd){grid-column:1/-1}}
/* unify run 46 (2026-10-26): balanced option grids, no orphan last row (6 -> 3+3, 5 -> 3+2 full rows, 4 -> 2+2 on tablets) */
@media(min-width:720px){.rn .opts:has(>:nth-child(6):last-child){grid-template-columns:repeat(3,minmax(0,1fr))}
.rn .opts:has(>:nth-child(5):last-child){grid-template-columns:repeat(6,minmax(0,1fr))}
.rn .opts:has(>:nth-child(5):last-child)>*{grid-column:span 2}
.rn .opts:has(>:nth-child(5):last-child)>:nth-child(n+4){grid-column:span 3}}
@media(min-width:600px) and (max-width:1023px){.rn .opts:has(>:nth-child(4):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}}
/* unify run 48 (2026-10-27): type near-duplicates snapped to the scale, line boxes kept (pre 14.08->14, drop prompt 17.6->16, pill 11.2->12 = th, tracking .12->.06em so width stays <= old and nothing rewraps at 390) */
.rn pre#summary{font-size:var(--rn-fs-sm,.875rem)}
.rn #drop strong{font-size:1rem;line-height:1.76}
.rn .pill{font-size:.75rem;line-height:1.4933;letter-spacing:.06em}
/* unify run 51 (2026-10-27): type snap with line boxes kept - labels 15.2->14px (--rn-fs-sm), lead 16.8-19.2 fluid -> 16px (<1024) / 18px --rn-fs-lg (>=1024, = rn-lead) */
.rn label{font-size:var(--rn-fs-sm,.875rem);line-height:1.7372}
@media(max-width:1023px){.rn .lead{font-size:var(--rn-fs-md,1rem);line-height:1.68}}
@media(min-width:1024px){.rn .lead{font-size:var(--rn-fs-lg,1.125rem);line-height:1.70667;margin-block:1.2rem}}

/* unify run 52 (2026-10-27): wrapped tab rows fill the width on phones <600px (flex-wrap + column-gap, content-sized flex:1 1 auto so no label wraps; no orphan half-row) */
@media(max-width:599px){.rn .tabs{display:flex;flex-wrap:wrap;column-gap:6px}.rn .tabs>button{flex:1 1 auto;margin-right:0}}
/* run53 heading snap: sizes on the scale (h1 28/32/40/48, h2 24/28/32, stat 28, amt small 24); line boxes + em margins pinned to the old fluid values (-.02px keeps LayoutUnit rounding at or under the old box) */
.rn{--rn-fs-h1:1.75rem;--rn-fs-h2:1.5rem}
@media(min-width:800px){.rn{--rn-fs-h1:2rem}}
@media(min-width:1000px){.rn{--rn-fs-h1:2.5rem}}
@media(min-width:1077px){.rn{--rn-fs-h2:1.75rem}}
@media(min-width:1200px){.rn{--rn-fs-h1:3rem}}
@media(min-width:1231px){.rn{--rn-fs-h2:2rem}}
.rn h1{line-height:calc(1.08*clamp(1.9rem,4vw,3.2rem) - .02px);margin:calc(.2*clamp(1.9rem,4vw,3.2rem)) 0 calc(.3*clamp(1.9rem,4vw,3.2rem))}
.rn h2{line-height:calc(1.15*clamp(1.5rem,2.6vw,2.2rem) - .02px);margin:calc(1.6*clamp(1.5rem,2.6vw,2.2rem)) 0 calc(.5*clamp(1.5rem,2.6vw,2.2rem))}
.rn .band h2{margin-top:0}
.rn .stat b{font-size:1.75rem;line-height:1.13143}
.rn .amt small{font-size:1.5rem;line-height:1.77778}

/* run54 (2026-10-27): balanced wrap. 4-link header nav on phones <600px wraps 2+2 instead of 3+1 (lone "Early access"); h1-h3 balance their lines so no one-word last line. text-wrap:balance never adds a line, only redistributes words. */
@media(max-width:599px){.rn header.top nav:has(>a:nth-child(4):last-child){text-wrap:balance}}
.rn h1,.rn h2,.rn h3{text-wrap:balance}

/* run55 (2026-10-27): pretty wrap for body text, inherited from .rn (h1-h3 keep balance, run54). Field labels directly followed by their control become their own block, so pretty can see their last line (inline, the control was the paragraph's last line); avoids one-word last lines like "(optional)". Chromium's pretty only re-breaks the last lines and never adds a line. */
.rn{text-wrap:pretty}
.rn label:has(+input,+select,+textarea){display:inline-block;width:100%}
/* run55 (2026-10-27), change 2: align wrapped header nav text with the brand. The first link of each nav row has margin-left 4 + padding 10, so on phones (nav below the brand) its text sat 14px right of the brand. nav -14px + brand +14px right margin = net 0 while they share a row (same wrap point), and the text lines up with the brand once the nav wraps below. */
.rn header.top .brand{margin-right:14px}
.rn header.top nav{margin-left:-14px}
/* unify run 56 (2026-10-27): hero pill on <390px phones: one line at 360-377 (tracking .06->.02em; it fits untracked from 378), balanced + centred two-line split below 360 (no runt line) */
@media(min-width:360px) and (max-width:377px){.rn .hero .pill{letter-spacing:.02em}}
@media(max-width:389px){.rn .hero .pill{text-wrap:balance;text-align:center}}

/* run57: balance stat-card label lines (2-col phone grids wrapped "value of late / orders") */
.rn .stat{text-wrap:balance}

/* run58: even tab rows on phones where they already wrap (4 tabs 3+1 -> 2+2 at <=390; 5 tabs 4+1 -> 3+2 at 415-540): fill row 1, the rest flow as before */
@media(max-width:390px){.rn .tabs:has(>button:nth-child(4):last-child)>button:nth-child(-n+2){flex-basis:calc(50% - 3px)}}
@media(min-width:415px) and (max-width:540px){.rn .tabs:has(>button:nth-child(5):last-child)>button:nth-child(-n+3){flex-basis:calc(33.333% - 4px)}}
/* run60: app-scoped tab rows 3+1 -> 2+2 just above 390 (feeddoctor 391-431 via data-t=IMPROVE, callverdict 391-399 via data-t=NOT_BILLABLE) */
@media(min-width:391px) and (max-width:431px){.rn .tabs:has(>button[data-t="IMPROVE"]):has(>button:nth-child(4):last-child)>button:nth-child(-n+2){flex-basis:calc(50% - 3px)}}
@media(min-width:391px) and (max-width:399px){.rn .tabs:has(>button[data-t="NOT_BILLABLE"]):has(>button:nth-child(4):last-child)>button:nth-child(-n+2){flex-basis:calc(50% - 3px)}}
/* v1.0.5 (Unify run 71, Nov 2 2026): .btn/.btn.alt own box-shadows hid the shared :focus-visible ring (WCAG 2.4.7) */
.rn .btn:focus-visible,.rn .btn.alt:focus-visible{box-shadow:var(--rn-focus)}
/* unify run 74 (2026-11-02): tablet card-grid balance. 2-col band 540-799: an odd last card (3,5,7..) spans the row, text capped at 66ch. 3-col band 800-1059: 4/7 cards -> rows of 3 then 2+2, 5/8 cards -> last two share the row. 1-col and 4-col unchanged. */
@media(min-width:540px) and (max-width:799px){.rn .grid>:last-child:nth-child(2n+3){grid-column:1/-1}
.rn .grid>:last-child:nth-child(2n+3)>p{max-width:66ch}}
@media(min-width:800px) and (max-width:1059px){.rn .grid:has(>:nth-child(4)):has(>:last-child:nth-child(3n+1)),.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(3n+2)){grid-template-columns:repeat(6,minmax(0,1fr))}
.rn .grid:has(>:nth-child(4)):has(>:last-child:nth-child(3n+1))>*,.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(3n+2))>*{grid-column:span 2}
.rn .grid:has(>:nth-child(4)):has(>:last-child:nth-child(3n+1))>:nth-last-child(-n+4),.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(3n+2))>:nth-last-child(-n+2){grid-column:span 3}}
/* unify run 75 (2026-11-02): 4-col band balance (>=1060). Grids of 5+ cards whose last row would hold 1 or 2 cards switch to 12 columns (span 3 = the same 4-up track). 4n+1 (5, 9..): last five -> 3 + 2. 4n+2 (6, 10..): last two share the row. 360-1059 untouched. */
@media(min-width:1060px){.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+1)),.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+2)){grid-template-columns:repeat(12,minmax(0,1fr))}
.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+1))>*,.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+2))>*{grid-column:span 3}
.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+1))>:nth-last-child(-n+5){grid-column:span 4}
.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+1))>:nth-last-child(-n+2),.rn .grid:has(>:nth-child(5)):has(>:last-child:nth-child(4n+2))>:nth-last-child(-n+2){grid-column:span 6}}
