PageSourceSearch

https://toolbreezy.com/_next/static/chunks/77276-d781306c9c5a6f8c.js

js toolbreezy.com collected 2026-10-02 01:50:43 UTC 36,247 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[77276],{77276:(e,t,n)=>{n.r(t),n.d(t,{SHOWER_PAN_OPENING:()=>G,buildReport:()=>ee,buildShowerPanShare:()=>_,default:()=>et,restoreState:()=>Y});var r=n(45993),s=n(75837),a=n(30845),i=n(77771),o=n(73950),l=n(15662),h=n(22925),d=n(95521),u=n(17832);let m=1/4,c=1/4,p=.5/(1/4),f={finishedFloor:"IPC 2024 and 2026 section 417.5.2, IRC 2024 and 2026 section P2709.1, and UPC 2024 and 2026 section 408.5",preSlope:"UPC section 408.7, lining pitched one quarter inch per foot to the weep holes in the subdrain",linerTurnUp:"IPC section 417.5.2 and IRC section P2709.2.1"},b="These are the model code figures. Your city or county can amend any of them, and the research behind this page names a live example: some regional adaptations cut the liner turn-up from three inches above the dam to two. Check the figures with your own building department before you order material or pour anything.";function x(e){return e/12*100}function g(e,t=16){if(!Number.isFinite(e)||!Number.isFinite(t)||t<1)return"";let n=e<0?"-":"",r=Math.round(Math.abs(e)*t),s=Math.floor(r/t),a=r-s*t,i=Math.round(t);for(;a>0&&a%2==0&&i%2==0;)a/=2,i/=2;return 0===a?`${n}${s}`:0===s?`${n}${a}/${i}`:`${n}${s} ${a}/${i}`}let w=["ft","in"];function v(e){return"ft"===e||"in"===e}let y=["mortarBedLiner","bondedMembrane","preformedPan","unknown"];function N(e){return"mortarBedLiner"===e||"bondedMembrane"===e||"preformedPan"===e||"unknown"===e}let j=["sloped","flat","unknown"];function k(e){return"sloped"===e||"flat"===e||"unknown"===e}let M=1/32,F=x(1/32),T=x(6),S=1/32,I=e=>({problem:e,inchesPerFoot:0,percent:0,ratioRun:0,degrees:0,source:"entered",band:"below",headline:e}),$={below:"This fall is under the published minimum of one quarter inch per foot. A floor this flat holds water in the low spots rather than moving it to the drain.",inside:"This fall sits inside the published band of one quarter to one half inch per foot toward the drain.",above:"This fall is over the published maximum of one half inch per foot. A floor this steep is a trip hazard, and a large format tile will not lie flat on it near the drain."},P=["Tile and grout are permeable, so water passes through the finished floor and reaches the liner. That is normal rather than a defect, and every traditional pan is built on the assumption that it happens.","On a flat liner that water has nowhere to travel, so it collects in the bottom of the mortar bed and stays there between showers.","Dry pack mortar wicks it back up like a sponge, which is what produces decaying thinset, dark grout, mold and an odor that cleaning the tile never fixes.","Given long enough the standing water works out through fastener penetrations and component joints and gets into the framing and subfloor outside the wet zone.","None of this shows on the tile, which is why the floor looks correct for years and the damage is only found when somebody opens it up."],C=["The drain body in a traditional pan is two pieces, and the weep holes sit in the lower one, around the clamping ring that grips the liner.","They are the only exit for the water that reaches the liner, so a pre-slope with blocked weep holes drains no better than no pre-slope at all.","Mortar packed straight over them fills them, so pea gravel or purpose made drainage discs go over the holes before the bed goes in.","The liner has to be sealed tight under the clamping ring, because the ring is the joint between the membrane and the drain."],A={bondedMembrane:"A bonded sheet membrane goes over a single sloped bed rather than under a second one, so there is no flat liner to trap water and no pre-slope in the sense the code section describes. The published fall band still applies to the finished floor. Everything else about that assembly comes from the membrane manufacturer, and the research behind this page does not cover it.",preformedPan:"A preformed pan arrives with its fall molded in, so the figures above describe what the pan should already have rather than something you build. Whether the subfloor under it needs to be flat, shimmed or bedded is the pan maker instructions, and the research behind this page does not cover it.",unknown:"Say which assembly this floor is and the pre-slope and liner figures will fill in. They belong to the traditional mortar bed and liner build, and printing them at a bonded membrane or a preformed pan would be describing a floor that is not theirs."},R=e=>({problem:e,applies:!1,minimumAboveDamIn:3,minimumAboveFloorIn:null,plannedAboveDamIn:null,shortfallIn:null,headline:e,fastenerRule:"",governedBy:f.linerTurnUp}),D=e=>({problem:e,runFt:0,shortestRunFt:null,slope:I(e),dropIn:0,dropText:"",codeMinDropIn:0,codeMaxDropIn:0,perimeter:{problem:e,available:!1,lowestHeightIn:0,highestHeightIn:0,runRatio:0,feasible:!1,explanation:""},preSlope:{problem:e,applies:!1,state:"unknown",severity:"unknown",minSlopeInPerFt:c,maxSlopeInPerFt:.5,minRiseIn:0,maxRiseIn:0,headline:"",mechanism:[],governedBy:f.preSlope},liner:R(e),checklist:[],unresolved:[],localAmendmentNotice:b,governedBy:f.finishedFloor});function O(e,t){return"in"===e?t/12:t}var U=n(50792);let B="toolbreezy:shower-pan-slope-calculator",L=e=>""===e.trim()?null:(0,U.jO)(e),E=e=>
1(Math.round(100*e)/100).toLocaleString(void 0,{maximumFractionDigits:2}),q=e=>(Math.round(1e3*e)/1e3).toLocaleString(void 0,{maximumFractionDigits:3}),H=["codeMinimum","codeMaximum","perFoot","percent","measuredDrop"],W=["spsu","spsl","s","sm","sf","sp","sd","spsb","ps","ch","tu","wp","fc"],z={spsu:"u",spsl:"l",spsb:"b"},G={runUnit:"ft",longest:"3",shortest:"",slopeMode:"codeMinimum",perFoot:"0.25",percent:"2.08",measured:"0.75",build:"mortarBedLiner",pre:"unknown",curb:"",turnUp:"",weep:!1,fasteners:!1};function Y(e,t){let n=(0,h.Yc)(e,W)?(t,n,r)=>(e.get(t)??n).slice(0,r):t.found?(e,n,r)=>t.str(z[e]??e,n,r):(e,t)=>t,r=(e,t)=>n(e,t,16),s=(e,t,r)=>{let s=n(e,r,t.reduce((e,t)=>Math.max(e,t.length),0));return t.includes(s)?s:r},a=s("spsu",w,G.runUnit),i=s("sm",H,G.slopeMode),o=s("spsb",y,G.build),l=s("ps",j,G.pre);return{runUnit:v(a)?a:G.runUnit,longest:r("spsl",G.longest),shortest:r("s",G.shortest),slopeMode:"codeMinimum"===i||"codeMaximum"===i||"perFoot"===i||"percent"===i||"measuredDrop"===i?i:G.slopeMode,perFoot:r("sf",G.perFoot),percent:r("sp",G.percent),measured:r("sd",G.measured),build:N(o)?o:G.build,pre:k(l)?l:G.pre,curb:r("ch",G.curb),turnUp:r("tu",G.turnUp),weep:"1"===r("wp",""),fasteners:"1"===r("fc","")}}let _=e=>(0,h.CZ)([{key:"spsu",value:e.runUnit},{key:"spsl",value:e.longest},{key:"s",value:e.shortest||null},{key:"sm",value:e.slopeMode},{key:"sf",value:"perFoot"===e.slopeMode?e.perFoot:null},{key:"sp",value:"percent"===e.slopeMode?e.percent:null},{key:"sd",value:"measuredDrop"===e.slopeMode?e.measured:null},{key:"spsb",value:e.build},{key:"ps",value:e.pre},{key:"ch",value:e.curb||null},{key:"tu",value:e.turnUp||null},{key:"wp",value:e.weep?"1":null},{key:"fc",value:e.fasteners?"1":null}]),J={codeMinimum:"Published minimum",codeMaximum:"Published maximum",perFoot:"My own, in inches per foot",percent:"My own, in percent",measuredDrop:"I measured the drop"},K={ft:"Feet",in:"Inches"},V={mortarBedLiner:"Mortar bed over a liner",bondedMembrane:"Bonded sheet membrane",preformedPan:"Preformed pan",unknown:"Not sure yet"},Z={sloped:"Yes, it is pitched",flat:"No, it is flat",unknown:"I cannot tell"},Q={below:"border border-destructive/40 bg-destructive/5",above:"border border-destructive/40 bg-destructive/5",inside:"border"},X=[{id:"square",label:"Center drain, 3 ft to the corner",unit:"ft",longest:"3",shortest:"",mode:"codeMinimum",build:"mortarBedLiner",pre:"unknown"},{id:"offset",label:"Offset drain, 5 ft far and 2 ft near",unit:"ft",longest:"5",shortest:"2",mode:"codeMinimum",build:"mortarBedLiner",pre:"unknown"},{id:"measured",label:"Checking a floor that is already tiled",unit:"in",longest:"42",shortest:"",mode:"measuredDrop",build:"unknown",pre:"unknown"}];function ee(e){return e.problem?e.problem:["Shower pan slope",`Longest run to drain   ${E(e.runFt)} ft`,`Fall                   ${q(e.slope.inchesPerFoot)} in per foot`,`Same fall in percent   ${E(e.slope.percent)}%`,`Same fall as a ratio   1 in ${E(e.slope.ratioRun)}`,`TOTAL DROP             ${e.dropText} in`,"",`Published band over this run   ${g(e.codeMinDropIn)} in to ${g(e.codeMaxDropIn)} in`,`Where this fall sits           ${e.slope.band}`,"",e.perimeter.available?`Level perimeter   ${e.perimeter.feasible?`set it ${g(e.perimeter.lowestHeightIn)} to ${g(e.perimeter.highestHeightIn)} in above the drain`:"not possible on this layout, the near wall would be over the maximum"}`:"Level perimeter   add the shortest distance to the drain","",`Pre-slope   ${e.preSlope.headline}`,"",`Liner   ${e.liner.headline}`,"",0===e.checklist.length?"There is no checklist for this build. The hidden-failure list on this page covers the mortar bed and liner assembly, so nothing on this report has been checked or confirmed for the build you chose.":e.unresolved.length>0?`Still unconfirmed:
2${e.unresolved.map(e=>`  - ${e}`).join("\n")}`:"Every item on the checklist is confirmed.","",`Sections: ${e.governedBy}`].join("\n")}
2function et(){let[e,t]=(0,s.useState)(G.runUnit),[n,h]=(0,s.useState)(G.longest),[y,j]=(0,s.useState)(G.shortest),[U,W]=(0,s.useState)(G.slopeMode),[z,et]=(0,s.useState)(G.perFoot),[en,er]=(0,s.useState)(G.percent),[es,ea]=(0,s.useState)(G.measured),[ei,eo]=(0,s.useState)(G.build),[el,eh]=(0,s.useState)(G.pre),[ed,eu]=(0,s.useState)(G.curb),[em,ec]=(0,s.useState)(G.turnUp),[ep,ef]=(0,s.useState)(G.weep),[eb,ex]=(0,s.useState)(G.fasteners);(0,s.useEffect)(()=>{let e=Y(new URLSearchParams(window.location.search),(0,d.y5)(B));t(e.runUnit),h(e.longest),j(e.shortest),W(e.slopeMode),et(e.perFoot),er(e.percent),ea(e.measured),eo(e.build),eh(e.pre),eu(e.curb),ec(e.turnUp),ef(e.weep),ex(e.fasteners)},[]),(0,u.Vd)(B,()=>JSON.stringify({u:e,l:n,s:y,sm:U,sf:z,sp:en,sd:es,b:ei,ps:el,ch:ed,tu:em,wp:ep?"1":"0",fc:eb?"1":"0"}),[e,n,y,U,z,en,es,ei,el,ed,em,ep,eb],{debounceMs:250});let eg=(0,s.useMemo)(()=>{let t="codeMinimum"===U?{kind:"codeMinimum"}:"codeMaximum"===U?{kind:"codeMaximum"}:"perFoot"===U?{kind:"perFoot",inchesPerFoot:L(z)??NaN}:"percent"===U?{kind:"percent",percent:L(en)??NaN}:{kind:"measuredDrop",dropIn:L(es)??NaN};return function(e){if(!e||"object"!=typeof e)return D("Enter the distance from the drain to the furthest perimeter point to get started.");if(!v(e.runUnit))return D("Say whether the distance to the drain is in feet or in inches. Forty two of one is a different shower from forty two of the other, so there is no default to fall back on.");let t=e.longestRun;if(!Number.isFinite(t))return D("Enter the distance from the drain to the furthest perimeter point as a number.");let n=O(e.runUnit,t);if(n<.25)return D("A run under 0.25 feet is shorter than any drain to wall distance in a real shower. Check whether the measurement is in the unit you picked.");if(n>30)return D("A run over 30 feet is past what this page is for. At that distance the minimum fall alone is over seven inches, which is a designed floor drain layout rather than a shower pan.");let r=null,s=e.shortestRun;if(null!=s){if(!Number.isFinite(s))return D("Enter the shortest distance to the drain as a number, or leave it blank.");if((r=O(e.runUnit,s))<.25||r>30)return D("The shortest distance to the drain has to sit between 0.25 and 30 feet, in the same unit as the longest one.");if(r>n)return D("The shortest distance to the drain came in larger than the longest one. Check which measurement is which.")}let a=function(e,t){var n,r;let s,a;if(!e||"object"!=typeof e||"string"!=typeof e.kind)return I("Say how you want the fall set, either from the published band or from a figure of your own.");switch(e.kind){case"codeMinimum":s=m,a="codeMinimum";break;case"codeMaximum":s=.5,a="codeMaximum";break;case"perFoot":if(s=e.inchesPerFoot,a="entered",!Number.isFinite(s))return I("Enter the fall as a number, in inches per foot.");if(s<M||s>6)return I(`A fall outside ${M} to 6 inches per foot is not a shower floor. Check whether you have entered the total drop rather than the fall per foot.`);break;case"percent":{let t=e.percent;if(a="entered",!Number.isFinite(t))return I("Enter the grade as a number, in percent.");if(t<F||t>T)return I(`A grade outside ${F.toFixed(2)} to ${T.toFixed(2)} percent is not a shower floor. Check whether your level is reading in degrees rather than percent.`);s=t/100*12;break}case"measuredDrop":{let n=e.dropIn;if(a="measured",!Number.isFinite(n))return I("Enter the drop you measured as a number, in inches.");if(n<S||n>36)return I(`A measured drop outside ${S} to 36 inches is past what this page is for. Check the units on the reading.`);if(!Number.isFinite(t)||t<=0)return I("A measured drop needs the run it was measured over, so enter the distance first.");if((s=n/t)<M||s>6)return I("That drop over that run works out to a fall no shower floor has. Check that both measurements describe the same wall.");break}default:return I("That is not a way of setting the fall that this page recognizes. Pick the published minimum, the published maximum, or a figure of your own.")}let i=(n=s)<m-1e-9?"below":n>.5+1e-9?"above":"inside",o={inchesPerFoot:r=s,percent:x(r),ratioRun:12/r,degrees:180*Math.atan(r/12)/Math.PI};return{problem:null,inchesPerFoot:s,percent:o.percent,ratioRun:o.ratioRun,degrees:o.degrees,source:a,band:i,headline:$[i]}}(e.slope,n);if(a.problem)return{...D(a.problem),runFt:n,shortestRunFt:r,slope:a};let i=a.inchesPerFoot*n,o=m*n,l=.5*n,h=function(e,t){let n={lowestHeightIn:0,highestHeightIn:0,runRatio:0,feasible:!1};if(!Number.isFinite(e)||e<=0)return{problem:"The longest distance from the drain has to be a positive number before a perimeter height means anything.",available:!1,...n,explanation:""};if(null==t)return{problem:null,available:!1,...n,explanation:"Add the SHORTEST distance from the drain to a perimeter point and this page will tell you whether one level line around the whole perimeter can serve every wall, or whether the closest wall would end up steeper than the published maximum."};if(!Number.isFinite(t)||t<=0)return{problem:"Enter the shortest distance from the drain as a positive number, or leave it blank.",available:!1,...n,explanation:""};if(t>e)return{problem:"The shortest distance to the drain came in larger than the longest one. Check which measurement is 
2which.",available:!1,...n,explanation:""};let r=m*e,s=.5*t,a=e/t,i=r<=s,o=i?`One level line around the perimeter works on this layout. Set the finished floor at the perimeter between ${g(r)} and ${g(s)} inches above the top of the drain, and every wall falls somewhere inside the published band.`:`One level line around the perimeter cannot serve this layout. The longest run is ${a.toFixed(2)} times the shortest, and the published band only stretches to ${p} times. Giving the far wall its minimum fall puts the near wall over the maximum. Either the perimeter steps down toward the closer walls, or the drain moves toward the middle of the floor.`;return{problem:null,available:!0,lowestHeightIn:r,highestHeightIn:s,runRatio:a,feasible:i,explanation:o}}(n,r);if(h.problem)return{...D(h.problem),runFt:n,shortestRunFt:r,slope:a};let d=N(e.buildType)?e.buildType:"unknown",u=function(e,t,n){let r=N(e)?e:"unknown",s=k(t)?t:"unknown",a=c*n,i=.5*n;if("mortarBedLiner"!==r)return{problem:null,applies:!1,state:s,severity:"unknown",minSlopeInPerFt:c,maxSlopeInPerFt:.5,minRiseIn:0,maxRiseIn:0,headline:A[r],mechanism:[],governedBy:f.preSlope};let o="sloped"===s?"ok":"flat"===s?"failing":"unknown",l="failing"===o?`A liner sitting on a flat surface is the failure this page exists for. The fill under the membrane has to be pitched to the drain at the same fall as the finished floor, which over your longest run means the pre-slope stands ${g(a)} to ${g(i)} inches higher at the perimeter than it is at the drain.`:"unknown"===o?`Nobody can tell from the finished tile whether there is a pre-slope under the liner, and this page cannot either. If the floor is being built now, pitch the fill under the membrane to the drain before the liner goes down: over your longest run that is a rise of ${g(a)} to ${g(i)} inches at the perimeter.`:`With the fill under the liner already pitched to the drain, water that comes through the tile reaches the membrane and runs to the weep holes. Over your longest run that pre-slope stands ${g(a)} to ${g(i)} inches higher at the perimeter than it is at the drain.`;return{problem:null,applies:!0,state:s,severity:o,minSlopeInPerFt:c,maxSlopeInPerFt:.5,minRiseIn:a,maxRiseIn:i,headline:l,mechanism:P,governedBy:f.preSlope}}(d,k(e.preSlope)?e.preSlope:"unknown",n),w=function(e,t,n){let r=N(e)?e:"unknown";if("mortarBedLiner"!==r)return{...R(A[r]),problem:null};let s=null;if(null!=t){if(!Number.isFinite(t))return R("Enter the finished curb height as a number, in inches, or leave it blank.");if(t<=0)return R("A curbless entry has no dam, and the published turn-up is measured from the top of the finished dam. Without that datum this page will not put a number on it, because the height for a curbless shower comes from the waterproofing method and the linear drain layout rather than from the section quoted here.");if(t<1||t>24)return R("A finished curb outside 1 to 24 inches is past what this page is for. Check the units on that measurement.");s=t+3}let a=null,i=null;if(null!=n){if(!Number.isFinite(n))return R("Enter the liner turn-up as a number, in inches above the finished dam, or leave it blank.");if(n<0||n>48)return R("A turn-up outside 0 to 48 inches above the dam is past what this page is for.");a=n,i=Math.max(0,3-n)}let o=null===s?"":` Measured from the shower floor at the curb, that puts the top of the liner at ${g(s)} inches.`,l=null===a?`The published minimum is 3 inches of liner above the top of the finished dam, up the rough walls and jambs.${o}`:null!==i&&i>0?`A turn-up of ${g(a)} inches above the dam is ${g(i)} inches under the published minimum of 3 inches. A liner that stops low lets water travel sideways into framing outside the wet zone, and like the pre-slope, nothing on the finished tile shows it.${o}`:`A turn-up of ${g(a)} inches above the dam reaches the published minimum of 3 inches.${o}`;return{problem:null,applies:!0,minimumAboveDamIn:3,minimumAboveFloorIn:s,plannedAboveDamIn:a,shortfallIn:i,headline:l,fastenerRule:"No nail, screw or staple may pierce the liner anywhere below a line 3 inches above the finished dam. That applies however high the liner runs, so turning it up further does not buy you room to fasten through the bottom of it.",governedBy:f.linerTurnUp}}(d,e.curbHeightIn??null,e.plannedTurnUpIn??null);if(w.problem)return{...D(w.problem),runFt:n,shortestRunFt:r,slope:a};let y=[];"mortarBedLiner"===d&&(y.push({id:"preSlope",label:"The fill under the liner is pitched to the drain",confirmed:"ok"===u.severity,detail:"ok"===u.severity?"You answered that the pre-slope is in.":"This is the one that rots framing while the tile looks perfect."}),y.push({id:"weepHoles",label:"Gravel or drainage discs went over the weep holes before the mortar",confirmed:!0===e.weepHolesProtected,detail:"Mortar packed straight over the weep holes seals the only exit the water under the tile has, so a pan with a perfect pre-slope and clogged weep holes drains no better than a flat one."}),y.push({id:"fasteners",label:"No fastener pierces the liner below 3 inches above the dam",confirmed:!0===e.fastenersClearOfLiner,detail:w.fastenerRule}),y.push({id:"turnUp",label:"The liner runs at least 3 inches above the finished dam",confirmed:null!==w.plannedAboveDamIn&&(w.shortfallIn??1)===0,detail:null===w.plannedAboveDamIn?"Enter the turn-up height above the dam and this page will compare it with the published figure.":w.headline}));let j=y.filter(e=>!e.confirmed).map(e=>e.label);return{problem:null,runFt:n,shortestRunFt:r,slope:a,dropIn:i,dropText:g(i),codeMinDropIn:o,codeMaxDropIn:l,perimeter:h,preSlope:u,liner:w,checklist:y,unresolved:j,localAmendmentNotice:b,governedBy:f.finishedFloor}}({runUnit:e,longestRun:L(n)??NaN,shortestRun:L(y),slope:t,buildType:ei,preSlope:el,curbHeightIn:L(ed),plannedTurnUpIn:L(em),weepHolesProtected:ep,fastenersClearOfLiner:eb})},[e,n,y,U,z,en,es,ei,el,ed,em,ep,eb]),ew=(0,s.useMemo)(()=>[{label:"Minimum fall as a percent grade",published:2,exact:x(m),ratio:2/x(m),reproduces:!1,consequence:"A digital level set to 2.00 percent is under one quarter inch per foot, which is the wrong side of a minimum."},{label:"Maximum fall as a percent grade",published:4,exact:x(.5),ratio:4/x(.5),reproduces:!1,consequence:"A level set to 4.00 percent stops short of one half inch per foot, so it is inside the band rather than at the top of it."},{label:"Minimum fall as a dimensionless factor",published:.0208,exact:m/12,ratio:.0208/(m/12),reproduces:!1,consequence:"Over the three foot run in the worked example in the research this factor returns 0.7488 inches where the same answer states 0.75."},{label:"Maximum fall as a dimensionless factor",published:.0417,exact:.041666666666666664,ratio:1.0008000000000001,reproduces:!1,consequence:"Over the same three foot run it returns 1.5012 inches where the answer states 1.50."}].map(e=>({...e,reproduces:1e-9>=Math.abs(e.ratio-1)})),[]),ev=ee(eg),ey=(e,t,n,s)=>(0,r.jsx)(i.$,{size:"sm",variant:t===e?"default":"outline",onClick:()=>n(e),children:s},e);return(0,r.jsxs)("div",{className:"space-y-5",children:[(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"Start from an example"}),(0,r.jsx)("div",{className:"flex flex-wrap gap-2",children:X.map(e=>(0,r.jsx)(i.$,{size:"sm",variant:"outline",onClick:()=>{t(e.unit),h(e.longest),j(e.shortest),W(e.mode),eo(e.build),eh(e.pre)},children:e.label},e.id))})]}),(0,r.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"Distance to the drain"}),(0,r.jsx)("div",{className:"flex flex-wrap gap-2",children:w.map(n=>ey(n,e,t,K[n]))}),(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"l",children:"Furthest perimeter point"}),(0,r.jsx)(a.p,{id:"l",inputMode:"decimal",value:n,onChange:e=>h(e.target.value),className:"font-mono"}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"Measured flat across the floor from the drain to the furthest point the water has to travel from."})]}),(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"s",children:"Closest perimeter point"}),(0,r.jsx)(a.p,{id:"s",inputMode:"decimal",value:y,onChange:e=>j(e.target.value),placeholder:"optional",className:"font-mono"}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"Optional, in the same unit. Give it and the page works out whether one level line can run around the whole perimeter."})]})]}),(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"The fall you are working to"}),(0,r.jsx)("div",{className:"flex flex-wrap gap-2",children:H.map(e=>ey(e,U,W,J[e]))}),"perFoot"===U&&(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"sf",children:"Inches of fall per foot"}),(0,r.jsx)(a.p,{id:"sf",inputMode:"decimal",value:z,onChange:e=>et(e.target.value),className:"font-mono"})]}),"percent"===U&&(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"sp",children:"Grade in percent"}),(0,r.jsx)(a.p,{id:"sp",inputMode:"decimal",value:en,onChange:e=>er(e.target.value),className:"font-mono"}),(0,r.jsxs)("p",{className:"text-xs text-muted-foreground",children:["What a digital level reads. One quarter inch per foot is ",q(m/12*100),"percent rather than 2, so 2.00 on the screen is under the published minimum."]})]}),"measuredDrop"===U&&(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"sd",children:"Drop you measured, in inches"}),(0,r.jsx)(a.p,{id:"sd",inputMode:"decimal",value:es,onChange:e=>ea(e.target.value),className:"font-mono"}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"The height difference between the drain and that furthest point, over the distance above."})]}),("codeMinimum"===U||"codeMaximum"===U)&&(0,r.jsxs)("p",{className:"text-xs text-muted-foreground",children:["The published band is ",m," to ",.5," inches of fall per foot toward the drain, set by ",f.finishedFloor,"."]})]})]}),(0,r.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"Which build is this"}),(0,r.jsx)("div",{className:"flex flex-wrap gap-2",children:Object.keys(V).map(e=>ey(e,ei,eo,V[e]))}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"The pre-slope and liner figures below belong to the traditional mortar bed over a liner. The fall band applies to the finished floor whichever build it is."})]}),(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"Is the fill under the liner pitched to the drain"}),(0,r.jsx)("div",{className:"flex flex-wrap gap-2",children:Object.keys(Z).map(e=>ey(e,el,eh,Z[e]))}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"Nothing on a finished tile floor shows the answer, so if the pan is already built and you did not lay it yourself, the honest answer is the third one."})]})]}),(0,r.jsxs)("div",{className:"grid gap-4 sm:grid-cols-2",children:[(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"ch",children:"Finished curb height"}),(0,r.jsx)(a.p,{id:"ch",inputMode:"decimal",value:ed,onChange:e=>eu(e.target.value),placeholder:"optional, inches",className:"font-mono"}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"Optional. It only restates the liner height from the shower floor, and it never changes what the published figure asks for."})]}),(0,r.jsxs)("div",{className:"space-y-1.5",children:[(0,r.jsx)("label",{className:"text-sm font-medium",htmlFor:"tu",children:"Liner turn-up above the curb"}),(0,r.jsx)(a.p,{id:"tu",inputMode:"decimal",value:em,onChange:e=>ec(e.target.value),placeholder:"optional, inches",className:"font-mono"}),(0,r.jsx)("p",{className:"text-xs text-muted-foreground",children:"Optional. Measured from the top of the finished curb up the wall, which is the datum the published figure uses."})]})]}
2),"mortarBedLiner"===ei&&(0,r.jsxs)("div",{className:"space-y-2",children:[(0,r.jsx)("span",{className:"text-sm font-medium",children:"Two things only you can confirm"}),(0,r.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,r.jsx)(i.$,{size:"sm",variant:ep?"default":"outline",onClick:()=>ef(!ep),children:"Weep holes protected before the mortar"}),(0,r.jsx)(i.$,{size:"sm",variant:eb?"default":"outline",onClick:()=>ex(!eb),children:"No fastener through the bottom of the liner"})]})]}),eg.problem?(0,r.jsx)("p",{className:"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm",children:eg.problem}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:`rounded-lg p-4 ${Q[eg.slope.band]}`,children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"The fall and the drop"}),(0,r.jsxs)("div",{className:"mt-3 space-y-1 font-mono text-sm",children:[(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsx)("span",{className:"text-muted-foreground",children:"Fall per foot"}),(0,r.jsxs)("span",{className:"tabular-nums",children:[q(eg.slope.inchesPerFoot)," in"]})]}),(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsx)("span",{className:"text-muted-foreground",children:"The same fall in percent"}),(0,r.jsxs)("span",{className:"tabular-nums",children:[E(eg.slope.percent),"%"]})]}),(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsx)("span",{className:"text-muted-foreground",children:"The same fall as a ratio"}),(0,r.jsxs)("span",{className:"tabular-nums",children:["1 in ",E(eg.slope.ratioRun)]})]}),(0,r.jsxs)("div",{className:"flex justify-between border-t pt-1 text-base font-medium",children:[(0,r.jsxs)("span",{children:["Total drop over ",E(eg.runFt)," ft"]}),(0,r.jsxs)("span",{className:"tabular-nums",children:[eg.dropText," in"]})]}),(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsx)("span",{className:"text-muted-foreground",children:"Published band over this run"}),(0,r.jsxs)("span",{className:"tabular-nums",children:[g(eg.codeMinDropIn)," to ",g(eg.codeMaxDropIn)," in"]})]})]}),(0,r.jsx)("p",{className:"mt-3 text-sm",children:eg.slope.headline}),(0,r.jsx)("p",{className:"mt-2 text-xs text-muted-foreground",children:eg.governedBy})]}),(0,r.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"One level line around the perimeter"}),(0,r.jsx)("p",{className:"mt-2 text-sm",children:eg.perimeter.explanation}),eg.perimeter.available&&(0,r.jsxs)("p",{className:"mt-2 text-xs text-muted-foreground",children:["A single height around the perimeter gives the far wall the shallowest fall and the near wall the steepest, so both ends of the band bind at once. That works while the far run is no more than"," ",p," times the near one, which is the published maximum divided by the published minimum. Yours is ",E(eg.perimeter.runRatio)," times."]})]}),(0,r.jsxs)("div",{className:`rounded-lg p-4 ${"failing"===eg.preSlope.severity?"border border-destructive/40 bg-destructive/5":"border"}`,children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"The pre-slope under the liner"}),(0,r.jsx)("p",{className:"mt-2 text-sm",children:eg.preSlope.headline}),eg.preSlope.mechanism.length>0&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("p",{className:"mt-3 text-sm font-medium",children:"What happens when it is missing"}),(0,r.jsx)("ol",{className:"mt-1 list-decimal space-y-1 pl-5 text-sm text-muted-foreground",children:eg.preSlope.mechanism.map(e=>(0,r.jsx)("li",{children:e},e))}),(0,r.jsx)("p",{className:"mt-3 text-xs text-muted-foreground",children:eg.preSlope.governedBy})]})]}),(0,r.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"The liner turn-up and the fastener line"}),(0,r.jsx)("p",{className:"mt-2 text-sm",children:eg.liner.headline}),eg.liner.applies&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:eg.liner.fastenerRule}),(0,r.jsx)("p",{className:"mt-2 text-xs text-muted-foreground",children:eg.liner.governedBy})]})]}),eg.checklist.length>0&&(0,r.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"The things that fail out of sight"}),(0,r.jsx)("ul",{className:"mt-2 space-y-2 text-sm",children:eg.checklist.map(e=>(0,r.jsxs)("li",{className:"flex gap-2",children:[(0,r.jsx)("span",{className:e.confirmed?"font-medium":"font-medium text-destructive",children:e.confirmed?"Confirmed":"Open"}),(0,r.jsxs)("span",{children:[(0,r.jsxs)("span",{className:"font-medium",children:[e.label,"."]})," ",(0,r.jsx)("span",{className:"text-muted-foreground",children:e.detail})]})]},e.id))}),eg.unresolved.length>0&&(0,r.jsx)("p",{className:"mt-3 text-sm text-muted-foreground",children:"An open item is one you have not told this page about. It is not a finding about your floor, because this page cannot see your floor."})]})]}),(0,r.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"Keeping the weep holes working"}),(0,r.jsx)("ul",{className:"mt-2 list-disc space-y-1 pl-5 text-sm text-muted-foreground",children:C.map(e=>(0,r.jsx)("li",{children:e},e))})]}),(0,r.jsxs)("div",{className:"rounded-lg border p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"Three ways of writing one fall, recomputed"}),(0,r.jsx)("p",{className:"mt-2 text-sm text-muted-foreground",children:"A fall in inches per foot, in percent and as a decimal factor are one quantity in three spellings, so they have to reconstruct each other. In the widely repeated set below, none of the four decimal spellings comes back to the ratio it is meant to represent. The ratio is the figure the code section states, so the ratio is what this page computes with."}),(0,r.jsx)("div",{className:"mt-3 overflow-x-auto",children:(0,r.jsxs)("table",{className:"w-full text-sm",children:[(0,r.jsx)("thead",{children:(0,r.jsxs)("tr",{className:"border-b text-left",children:[(0,r.jsx)("th",{className:"py-1 pr-3 font-medium",children:"Spelling"}),(0,r.jsx)("th",{className:"py-1 pr-3 font-medium",children:"Commonly printed"}),(0,r.jsx)("th",{className:"py-1 pr-3 font-medium",children:"Exact"}),(0,r.jsx)("th",{className:"py-1 font-medium",children:"What it costs you"})]})}),(0,r.jsx)("tbody",{children:ew.map(e=>(0,r.jsxs)("tr",{className:"border-b align-top",children:[(0,r.jsx)("td",{className:"py-1 pr-3",children:e.label}),(0,r.jsx)("td",{className:"py-1 pr-3 font-mono tabular-nums",children:e.published}),(0,r.jsx)("td",{className:"py-1 pr-3 font-mono tabular-nums",children:q(e.exact)}),(0,r.jsx)("td",{className:"py-1 text-muted-foreground",children:e.consequence})]},e.label))})]})})]}),(0,r.jsxs)("div",{className:"rounded-lg border border-destructive/40 bg-destructive/5 p-4",children:[(0,r.jsx)("h3",{className:"text-sm font-medium",children:"Your local authority has the last word"}),(0,r.jsx)("p",{className:"mt-2 text-sm",children:eg.localAmendmentNotice}),(0,r.jsxs)("p",{className:"mt-2 text-sm text-muted-foreground",children:["The national baseline turn-up is ",3," inches above the finished dam and the fastener exclusion runs to the same ",3," inches. At least one state code cuts the turn-up to ",2," inches, which is exactly why this page reports the published figures beside what you entered instead of grading your floor."]})]}),!eg.problem&&(0,r.jsx)(l.i,{value:ev,label:"Copy the figures"}),(0,r.jsx)("p",{className:"text-sm text-muted-foreground",children:"This page reports what the published figures require against what you entered, and it never says an installation is code compliant, because that is a call an inspector makes on your floor with a level in their hand. The fall band, the pre-slope pitch, the three inch liner turn-up and the fastener exclusion all come from the model codes, and your city or county can amend any of them, so the figures here are a starting point for that conversation rather than the end of it. One figure is a step further out than the rest and it is worth naming: the research puts the pre-slope band at one quarter to one half inch per foot, but the section it cites for the pre-slope itself publishes only the one quarter inch per foot minimum, so the upper end of that band is carried down from the finished floor rule rather than quoted from a section that sets it. It cannot see your floor, so whether there is a pre-slope under the liner, whether the weep holes are clear and whether anything pierced the membrane are your answers, and an answer you have not given is reported as unconfirmed rather than assumed good. It will not put a number on the mortar bed thickness, the drain body, the liner material or a curbless entry, because none of those is in the research behind it and a calculator that invents a code figure is 
2worse than no calculator. The limits that make it refuse an entry, on the run, on the fall, on the curb and on the turn-up, are set here rather than published anywhere, and they exist to catch a typo before it becomes a floor."}),(0,r.jsx)(o.ToolActions,{share:()=>_({runUnit:e,longest:n,shortest:y,slopeMode:U,perFoot:z,percent:en,measured:es,build:ei,pre:el,curb:ed,turnUp:em,weep:ep,fasteners:eb}),title:"Shower Pan Slope Calculator",queryIsImpersonal:"the distances, fall and build details you entered"})]})}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.