diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Change log
+
+## 0.1.0
+
+* Initial release: utilityCost, annualSessions, sessionCost, breakEvenSessions.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,28 @@
+# sauna-vs-gym-cost
+
+Cost-per-session math for home recovery gear.
+
+A home sauna's real price is not the sticker. It is the gear price
+spread over the sessions a habit accrues, plus the
+electricity each session draws. A $2,500 unit run four times a week at
+$0.17 per kilowatt-hour lands at $25.34 a session by session 100 and
+$2.84 by session 1,000, electricity included both times.
+
+The package follows the cost-per-session method used on
+[HackedSelf](https://hackedself.com). It depends only on base.
+
+## Example
+
+A $2,500 sauna, a $22 gym visit across town, and $0.34 of power per
+session:
+
+* per-session electricity: `utilityCost 2.0 0.17` = $0.34
+* session 100 all-in: `sessionCost 2500 100 0.34` = $25.34
+* session 1,000 all-in: `sessionCost 2500 1000 0.34` = $2.84
+* break-even: `breakEvenSessions 2500 22 0.34` = 115.4 visits
+
+At four sessions a week, 115.4 visits is about 6.6 months. Every gym
+trip after that costs more than the power bill for a home session. If
+the alternative were a $0.30 day pass, cheaper than the electricity
+alone, the break-even count goes infinite: no amount of usage closes a
+gap that opens the wrong way.
diff --git a/sauna-vs-gym-cost.cabal b/sauna-vs-gym-cost.cabal
new file mode 100644
--- /dev/null
+++ b/sauna-vs-gym-cost.cabal
@@ -0,0 +1,36 @@
+cabal-version:      2.2
+name:               sauna-vs-gym-cost
+version:            0.1.0
+synopsis:           Cost-per-session math for home recovery gear
+description:
+  A home sauna or cold plunge is a gear price, a usage habit, and an
+  electricity line. These functions spread the gear price over the
+  sessions a habit accrues, add the electricity per session,
+  and count the visits until the gear beats a per-visit alternative
+  like a gym membership. The break-even count goes infinite when the
+  alternative costs less than the electricity alone.
+  .
+  Companion to HackedSelf, which prices home recovery gear by
+  cost-per-session math. Three pure functions on Doubles, no
+  dependencies beyond base.
+license:            MIT
+author:             Poket Dev
+maintainer:         hello@poketdev.com
+homepage:           https://hackedself.com
+bug-reports:        https://github.com/scrapertweeter3-prog/sauna-vs-gym-cost-hs/issues
+copyright:          2026 Poket Dev LLC
+category:           Math
+build-type:         Simple
+extra-doc-files:    README.md
+                  , CHANGELOG.md
+
+source-repository head
+  type:     git
+  location: https://github.com/scrapertweeter3-prog/sauna-vs-gym-cost-hs
+
+library
+  exposed-modules:  SaunaVsGym.Cost
+  hs-source-dirs:   src
+  build-depends:    base >=4 && <5
+  default-language: Haskell2010
+  ghc-options:      -Wall
diff --git a/src/SaunaVsGym/Cost.hs b/src/SaunaVsGym/Cost.hs
new file mode 100644
--- /dev/null
+++ b/src/SaunaVsGym/Cost.hs
@@ -0,0 +1,45 @@
+-- | Cost-per-session math for home recovery gear.
+--
+-- A home sauna or cold plunge is a gear price, a usage habit, and an
+-- electricity line. The sticker price says nothing until usage spreads
+-- it over sessions and the electricity lands on each one. This module
+-- restates a purchase into dollars per session and counts the visits
+-- until the gear has paid for itself against a per-visit alternative
+-- like a gym membership or a day pass.
+module SaunaVsGym.Cost
+  ( utilityCost
+  , annualSessions
+  , sessionCost
+  , breakEvenSessions
+  ) where
+
+-- | Per-session utility cost from kilowatt-hours and the meter rate.
+-- A 2 kW heater run 1 hour at $0.17/kWh is 0.34 dollars a session.
+utilityCost :: Double -> Double -> Double
+utilityCost kwhPerSession ratePerKwh = kwhPerSession * ratePerKwh
+
+-- | Sessions a weekly habit adds up to over a year.
+-- Four a week is 208.
+annualSessions :: Double -> Double
+annualSessions sessionsPerWeek = sessionsPerWeek * 52
+
+-- | Amortized cost of one session: the gear price spread over total
+-- sessions plus the electricity line. Sessions accrue as the habit
+-- runs, so the same $2,500 unit lands at $25.34 by session 100 and
+-- $2.84 by session 1,000 before electricity. No sessions means no
+-- denominator, so the cost is infinite rather than zero.
+sessionCost :: Double -> Double -> Double -> Double
+sessionCost gearCost totalSessions utilityPerSession
+  | totalSessions <= 0 = 1 / 0
+  | otherwise          = gearCost / totalSessions + utilityPerSession
+
+-- | Visits until the gear has paid for itself against a per-visit
+-- alternative. Infinite when the alternative is cheaper than the
+-- electricity alone, because usage then never closes the gap. A $22
+-- gym visit against $0.34 of power needs 115.4 sessions, about 6.6
+-- months at four a week, before every visit after that is free.
+breakEvenSessions :: Double -> Double -> Double -> Double
+breakEvenSessions gearCost alternativePerVisit utilityPerSession
+  | gap <= 0  = 1 / 0
+  | otherwise = gearCost / gap
+  where gap   = alternativePerVisit - utilityPerSession
