feat: Renames quick calc routes / views to ductulator. Adds button to home page for using ductulator, needs added to navbar still.
This commit is contained in:
@@ -8,8 +8,6 @@
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
|
||||
monospace;
|
||||
--color-green-400: oklch(79.2% 0.209 151.711);
|
||||
--color-sky-600: oklch(58.8% 0.158 241.966);
|
||||
--color-violet-600: oklch(54.1% 0.281 293.009);
|
||||
--color-gray-200: oklch(92.8% 0.006 264.531);
|
||||
--color-gray-400: oklch(70.7% 0.022 261.325);
|
||||
--color-black: #000;
|
||||
@@ -5304,6 +5302,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.-mx-2 {
|
||||
margin-inline: calc(var(--spacing) * -2);
|
||||
}
|
||||
.-mx-4 {
|
||||
margin-inline: calc(var(--spacing) * -4);
|
||||
}
|
||||
.mx-10 {
|
||||
margin-inline: calc(var(--spacing) * 10);
|
||||
}
|
||||
@@ -5399,12 +5403,18 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.-my-4 {
|
||||
margin-block: calc(var(--spacing) * -4);
|
||||
}
|
||||
.my-1\.5 {
|
||||
margin-block: calc(var(--spacing) * 1.5);
|
||||
}
|
||||
.my-6 {
|
||||
margin-block: calc(var(--spacing) * 6);
|
||||
}
|
||||
.my-8 {
|
||||
margin-block: calc(var(--spacing) * 8);
|
||||
}
|
||||
.my-auto {
|
||||
margin-block: auto;
|
||||
}
|
||||
@@ -5620,9 +5630,6 @@
|
||||
.me-4 {
|
||||
margin-inline-end: calc(var(--spacing) * 4);
|
||||
}
|
||||
.me-6 {
|
||||
margin-inline-end: calc(var(--spacing) * 6);
|
||||
}
|
||||
.me-10 {
|
||||
margin-inline-end: calc(var(--spacing) * 10);
|
||||
}
|
||||
@@ -5686,6 +5693,12 @@
|
||||
.mt-10 {
|
||||
margin-top: calc(var(--spacing) * 10);
|
||||
}
|
||||
.mt-20 {
|
||||
margin-top: calc(var(--spacing) * 20);
|
||||
}
|
||||
.mt-30 {
|
||||
margin-top: calc(var(--spacing) * 30);
|
||||
}
|
||||
.breadcrumbs {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
max-width: 100%;
|
||||
@@ -6707,12 +6720,6 @@
|
||||
.w-px {
|
||||
width: 1px;
|
||||
}
|
||||
.max-w-lg {
|
||||
max-width: var(--container-lg);
|
||||
}
|
||||
.max-w-xl {
|
||||
max-width: var(--container-xl);
|
||||
}
|
||||
.min-w-0 {
|
||||
min-width: calc(var(--spacing) * 0);
|
||||
}
|
||||
@@ -6990,13 +6997,6 @@
|
||||
.gap-4 {
|
||||
gap: calc(var(--spacing) * 4);
|
||||
}
|
||||
.space-y-1 {
|
||||
:where(& > :not(:last-child)) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
|
||||
margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
|
||||
}
|
||||
}
|
||||
.space-y-2 {
|
||||
:where(& > :not(:last-child)) {
|
||||
--tw-space-y-reverse: 0;
|
||||
@@ -7642,9 +7642,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.bg-base-100 {
|
||||
background-color: var(--color-base-100);
|
||||
}
|
||||
.bg-base-200 {
|
||||
background-color: var(--color-base-200);
|
||||
}
|
||||
@@ -8779,9 +8776,6 @@
|
||||
color: var(--color-warning);
|
||||
}
|
||||
}
|
||||
.text-accent {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
.text-base-content {
|
||||
color: var(--color-base-content);
|
||||
}
|
||||
@@ -9751,16 +9745,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.md\:mt-6 {
|
||||
@media (width >= 48rem) {
|
||||
margin-top: calc(var(--spacing) * 6);
|
||||
}
|
||||
}
|
||||
.md\:mt-15 {
|
||||
@media (width >= 48rem) {
|
||||
margin-top: calc(var(--spacing) * 15);
|
||||
}
|
||||
}
|
||||
.md\:grid-cols-2 {
|
||||
@media (width >= 48rem) {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
.md\:grid-cols-3 {
|
||||
@media (width >= 48rem) {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
.lg\:drawer-open {
|
||||
@media (width >= 64rem) {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
@@ -9814,9 +9813,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.lg\:grid-cols-4 {
|
||||
.lg\:mx-20 {
|
||||
@media (width >= 64rem) {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
margin-inline: calc(var(--spacing) * 20);
|
||||
}
|
||||
}
|
||||
.lg\:mt-6 {
|
||||
@media (width >= 64rem) {
|
||||
margin-top: calc(var(--spacing) * 6);
|
||||
}
|
||||
}
|
||||
.is-drawer-close\:mx-auto {
|
||||
@@ -9858,11 +9862,6 @@
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
.is-drawer-close\:text-green-400 {
|
||||
&:where(.drawer-toggle:not(:checked) ~ .drawer-side, .drawer-toggle:not(:checked) ~ .drawer-side *) {
|
||||
color: var(--color-green-400);
|
||||
}
|
||||
}
|
||||
.is-drawer-open\:flex {
|
||||
&:where(.drawer-toggle:checked ~ .drawer-side, .drawer-toggle:checked ~ .drawer-side *) {
|
||||
display: flex;
|
||||
|
||||
@@ -14,7 +14,7 @@ private let viewRouteMiddleware: [any Middleware] = [
|
||||
extension SiteRoute.View {
|
||||
var middleware: [any Middleware]? {
|
||||
switch self {
|
||||
case .home, .login, .signup, .test, .quickCalc:
|
||||
case .home, .login, .signup, .test, .ductulator:
|
||||
return nil
|
||||
case .project, .user:
|
||||
return viewRouteMiddleware
|
||||
|
||||
@@ -12,7 +12,7 @@ extension SiteRoute {
|
||||
case login(LoginRoute)
|
||||
case signup(SignupRoute)
|
||||
case project(ProjectRoute)
|
||||
case quickCalc(QuickCalcRoute)
|
||||
case ductulator(DuctulatorRoute)
|
||||
case user(UserRoute)
|
||||
//FIX: Remove.
|
||||
case test
|
||||
@@ -34,8 +34,8 @@ extension SiteRoute {
|
||||
Route(.case(Self.project)) {
|
||||
SiteRoute.View.ProjectRoute.router
|
||||
}
|
||||
Route(.case(Self.quickCalc)) {
|
||||
SiteRoute.View.QuickCalcRoute.router
|
||||
Route(.case(Self.ductulator)) {
|
||||
SiteRoute.View.DuctulatorRoute.router
|
||||
}
|
||||
Route(.case(Self.user)) {
|
||||
SiteRoute.View.UserRoute.router
|
||||
@@ -991,7 +991,7 @@ extension SiteRoute.View.UserRoute {
|
||||
}
|
||||
|
||||
extension SiteRoute.View {
|
||||
public enum QuickCalcRoute: Equatable, Sendable {
|
||||
public enum DuctulatorRoute: Equatable, Sendable {
|
||||
case index
|
||||
case submit(Form)
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import ManualDCore
|
||||
|
||||
public struct SubmitButton: HTML, Sendable {
|
||||
let title: String
|
||||
@@ -74,3 +76,17 @@ public struct TrashButton: HTML, Sendable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct DuctulatorButton: HTML, Sendable {
|
||||
public init() {}
|
||||
|
||||
public var body: some HTML<HTMLTag.a> {
|
||||
a(
|
||||
.class("btn"),
|
||||
.href(route: .ductulator(.index)),
|
||||
.target(.blank)
|
||||
) {
|
||||
"Ductulator"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ extension ViewController.Request {
|
||||
case .project(let route):
|
||||
return await route.renderView(on: self)
|
||||
|
||||
case .quickCalc(let route):
|
||||
case .ductulator(let route):
|
||||
return await route.renderView(on: self)
|
||||
|
||||
case .user(let route):
|
||||
@@ -712,7 +712,7 @@ extension SiteRoute.View.UserRoute.Profile {
|
||||
}
|
||||
}
|
||||
|
||||
extension SiteRoute.View.QuickCalcRoute {
|
||||
extension SiteRoute.View.DuctulatorRoute {
|
||||
|
||||
func renderView(
|
||||
on request: ViewController.Request
|
||||
@@ -722,7 +722,7 @@ extension SiteRoute.View.QuickCalcRoute {
|
||||
switch self {
|
||||
case .index:
|
||||
return await request.view {
|
||||
QuickCalcView(
|
||||
DuctulatorView(
|
||||
isLoggedIn: request.isLoggedIn
|
||||
)
|
||||
}
|
||||
@@ -736,7 +736,7 @@ extension SiteRoute.View.QuickCalcRoute {
|
||||
}
|
||||
return (ductSize, rectangularSize)
|
||||
} onSuccess: { (ductSize, rectangularSize) in
|
||||
QuickCalcView.Result(ductSize: ductSize, rectangularSize: rectangularSize)
|
||||
DuctulatorView.Result(ductSize: ductSize, rectangularSize: rectangularSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import ManualDClient
|
||||
import ManualDCore
|
||||
import Styleguide
|
||||
|
||||
struct QuickCalcView: HTML, Sendable {
|
||||
struct DuctulatorView: HTML, Sendable {
|
||||
|
||||
let isLoggedIn: Bool
|
||||
|
||||
@@ -32,7 +32,7 @@ struct QuickCalcView: HTML, Sendable {
|
||||
div(.class("flex space-x-6 items-center text-4xl")) {
|
||||
SVG(.calculator)
|
||||
h1(.class("text-4xl font-bold me-10")) {
|
||||
"Duct Size"
|
||||
"Ductulator"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ struct QuickCalcView: HTML, Sendable {
|
||||
|
||||
form(
|
||||
.class("space-y-4 mt-6"),
|
||||
.hx.post(route: .quickCalc(.index)),
|
||||
.hx.post(route: .ductulator(.index)),
|
||||
.hx.target("#\(Result.id)"),
|
||||
.hx.swap(.outerHTML)
|
||||
) {
|
||||
@@ -103,7 +103,7 @@ struct QuickCalcView: HTML, Sendable {
|
||||
h2(.class("text-3xl font-bold")) { "Result" }
|
||||
button(
|
||||
.class("btn btn-primary"),
|
||||
.hx.get(route: .quickCalc(.index)),
|
||||
.hx.get(route: .ductulator(.index)),
|
||||
.hx.target("body"),
|
||||
.hx.swap(.outerHTML)
|
||||
) {
|
||||
@@ -1,15 +1,19 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import Styleguide
|
||||
|
||||
struct HomeView: HTML, Sendable {
|
||||
|
||||
var body: some HTML {
|
||||
div( // Uncomment to test different theme's.
|
||||
// .data("theme", value: "cyberpunk")
|
||||
// NOTE: Footer background color will follow system theme, it will actually be the
|
||||
// same as the `hero` background in reality.
|
||||
// NOTE: Footer background color will follow system theme.
|
||||
) {
|
||||
div(.class("flex justify-end m-4")) {
|
||||
div(.class("flex justify-end space-x-4 m-4")) {
|
||||
DuctulatorButton()
|
||||
.attributes(.class("btn-ghost btn-accent text-lg"))
|
||||
.tooltip("Duct size calculator", position: .left)
|
||||
|
||||
button(
|
||||
.class("btn btn-ghost btn-secondary text-lg"),
|
||||
.hx.get(route: .login(.index())),
|
||||
@@ -20,12 +24,13 @@ struct HomeView: HTML, Sendable {
|
||||
"Login"
|
||||
}
|
||||
}
|
||||
div(.class("hero")) {
|
||||
|
||||
div(.class("mx-10 lg:mx-20")) {
|
||||
div(
|
||||
.class(
|
||||
"""
|
||||
relative hero-content text-center bg-base-300
|
||||
w-full min-h-[400px] rounded-3xl shadow-3xl overflow-hidden
|
||||
relative text-center bg-base-300
|
||||
rounded-3xl shadow-3xl overflow-hidden
|
||||
"""
|
||||
)
|
||||
) {
|
||||
@@ -62,7 +67,7 @@ struct HomeView: HTML, Sendable {
|
||||
) {
|
||||
"Get Started"
|
||||
}
|
||||
p(.class("text-xs italic mt-8")) {
|
||||
p(.class("text-xs italic my-6")) {
|
||||
"""
|
||||
Manual-D™ is a trademark of Air Conditioning Contractors of America (ACCA).
|
||||
|
||||
@@ -72,46 +77,45 @@ struct HomeView: HTML, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
div(.class("grid grid-cols-1 md:grid-cols-2 gap-4 mx-20 my-6")) {
|
||||
div(.class("border-3 border-accent rounded-lg shadow-lg p-4")) {
|
||||
div(.class("flex items-center space-x-4")) {
|
||||
div(.class("text-5xl text-primary font-bold")) {
|
||||
"Features"
|
||||
}
|
||||
}
|
||||
div(.class("text-xl ms-10 mt-10")) {
|
||||
ul(.class("list-disc")) {
|
||||
li {
|
||||
div(
|
||||
.class("font-bold italic bg-secondary rounded-lg shadow-lg px-4 w-fit")
|
||||
) {
|
||||
"Built by humans"
|
||||
}
|
||||
div(.class("grid grid-cols-1 md:grid-cols-2 gap-4 my-6")) {
|
||||
div(.class("border-3 border-accent rounded-lg shadow-lg p-4")) {
|
||||
div(.class("flex items-center space-x-4")) {
|
||||
div(.class("text-5xl text-primary font-bold")) {
|
||||
"Features"
|
||||
}
|
||||
}
|
||||
div(.class("text-xl ms-10 mt-10")) {
|
||||
ul(.class("list-disc")) {
|
||||
li {
|
||||
div(
|
||||
.class("font-bold italic bg-secondary rounded-lg shadow-lg px-4 w-fit")
|
||||
) {
|
||||
"Built by humans"
|
||||
}
|
||||
}
|
||||
li { "Fully open source." }
|
||||
li { "Great replacement for speed sheet users." }
|
||||
li { "Great for classrooms." }
|
||||
li { "Store your projects in one place." }
|
||||
li { "Export final project to pdf." }
|
||||
li { "Import room loads via CSV file." }
|
||||
li { "Web based." }
|
||||
li { "Self host (run on your own infrastructure)." }
|
||||
}
|
||||
li { "Fully open source." }
|
||||
li { "Great replacement for speed sheet users." }
|
||||
li { "Great for classrooms." }
|
||||
li { "Store your projects in one place." }
|
||||
li { "Export final project to pdf." }
|
||||
li { "Import room loads via CSV file." }
|
||||
li { "Web based." }
|
||||
li { "Self host (run on your own infrastructure)." }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div(.class("border-3 border-accent rounded-lg shadow-lg p-4")) {
|
||||
div(.class("text-5xl text-primary font-bold")) {
|
||||
"Coming Soon"
|
||||
}
|
||||
div(.class("text-xl ms-10 mt-10")) {
|
||||
ul(.class("list-disc")) {
|
||||
li { "API integration." }
|
||||
li { "Command line interface." }
|
||||
li { "Fitting selection tool." }
|
||||
li { "Room load import from PDF." }
|
||||
div(.class("border-3 border-accent rounded-lg shadow-lg p-4")) {
|
||||
div(.class("text-5xl text-primary font-bold")) {
|
||||
"Coming Soon"
|
||||
}
|
||||
div(.class("text-xl ms-10 mt-10")) {
|
||||
ul(.class("list-disc")) {
|
||||
li { "API integration." }
|
||||
li { "Command line interface." }
|
||||
li { "Fitting selection tool." }
|
||||
li { "Room load import from PDF." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,23 +123,24 @@ struct HomeView: HTML, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: When beta flag is gone, then remove the responsive margin of the header.
|
||||
var header: some HTML<HTMLTag.div> {
|
||||
div(.class("flex justify-center items-center")) {
|
||||
div(.class("flex justify-center mt-30 md:mt-15 lg:mt-6")) {
|
||||
div(
|
||||
.class(
|
||||
"""
|
||||
flex border-b-6 border-accent
|
||||
flex items-end border-b-6 border-accent
|
||||
text-8xl font-bold my-auto space-2
|
||||
"""
|
||||
)
|
||||
) {
|
||||
h1(.class("me-2")) { "Duct Calc" }
|
||||
div(.class("")) {
|
||||
div {
|
||||
span(
|
||||
.class(
|
||||
"""
|
||||
bg-secondary rounded-md
|
||||
text-5xl rotate-180 p-2
|
||||
text-5xl rotate-180 p-2 -mx-2
|
||||
"""
|
||||
),
|
||||
.style("writing-mode: vertical-rl")
|
||||
|
||||
@@ -28,13 +28,13 @@ struct ViewControllerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func quickCalc() async throws {
|
||||
func ductulator() async throws {
|
||||
try await withDependencies {
|
||||
$0.viewController = .liveValue
|
||||
$0.auth = .failing
|
||||
} operation: {
|
||||
@Dependency(\.viewController) var viewController
|
||||
let view = try await viewController.view(.test(.quickCalc(.index)))
|
||||
let view = try await viewController.view(.test(.ductulator(.index)))
|
||||
assertSnapshot(of: view, as: .html)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Duct Calc</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta content="ductcalc.com" name="og:site_name">
|
||||
<meta content="Duct Calc" name="og:title">
|
||||
<meta content="Duct sizing based on ACCA, Manual-D." name="description">
|
||||
<meta content="Duct sizing based on ACCA, Manual-D." name="og:description">
|
||||
<meta content="/images/mand_logo.png" name="og:image">
|
||||
<meta content="/images/mand_logo.png" name="twitter:image">
|
||||
<meta content="Duct Calc" name="twitter:image:alt">
|
||||
<meta content="summary_large_image" name="twitter:card">
|
||||
<meta content="1536" name="og:image:width">
|
||||
<meta content="1024" name="og:image:height">
|
||||
<meta content="duct, hvac, duct-design, duct design, manual-d, manual d, design" name="keywords">
|
||||
<script src="https://unpkg.com/htmx.org@2.0.8"></script>
|
||||
<script src="/js/htmx-download.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||
<link rel="stylesheet" href="/css/output.css">
|
||||
<link rel="stylesheet" href="/css/htmx.css">
|
||||
<link rel="icon" href="/images/favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="/images/favicon-32x32.png" type="image/png">
|
||||
<link rel="icon" href="/images/favicon-16x16.png" type="image/png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<script src="https://unpkg.com/htmx-remove@latest" crossorigin="anonymous" integrity="sha384-NwB2Xh66PNEYfVki0ao13UAFmdNtMIdBKZ8sNGRT6hKfCPaINuZ4ScxS6vVAycPT"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex flex-col min-h-screen min-w-full justify-between" data-theme="default">
|
||||
<main class="flex flex-col min-h-screen min-w-full grow mb-auto">
|
||||
<div>
|
||||
<nav class="navbar w-full bg-base-300 text-base-content shadow-sm mb-4">
|
||||
<div class="flex flex-1 space-x-4 items-center">
|
||||
<div class="tooltip tooltip-right" data-tip="Home">
|
||||
<a class="flex w-fit h-fit text-xl items-end px-4 py-2 btn btn-square btn-ghost hover:bg-neutral hover:text-white" href="/">
|
||||
<img src="/images/mand_logo_sm.webp">
|
||||
Duct Calc<span></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="flex justify-center items-center px-10">
|
||||
<div class="bg-base-300 rounded-3xl shadow-3xl
|
||||
p-6 w-full">
|
||||
<div class="flex space-x-6 items-center text-4xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-calculator-icon lucide-calculator"><rect width="16" height="20" x="4" y="2" rx="2"/><line x1="8" x2="16" y1="6" y2="6"/><line x1="16" x2="16" y1="14" y2="18"/><path d="M16 10h.01"/><path d="M12 10h.01"/><path d="M8 10h.01"/><path d="M12 14h.01"/><path d="M8 14h.01"/><path d="M12 18h.01"/><path d="M8 18h.01"/></svg>
|
||||
<h1 class="text-4xl font-bold me-10">Ductulator</h1>
|
||||
</div>
|
||||
<p class="text-primary font-bold italic">Calculate duct size for the given parameters</p>
|
||||
<form class="space-y-4 mt-6" hx-post="/duct-size" hx-target="#resultView" hx-swap="outerHTML">
|
||||
<label class="input w-full"><span class="label">CFM</span>
|
||||
<input name="cfm" type="number" placeholder="1000" required autofocus>
|
||||
Friction Rate</label><label class="input w-full"><span class="label"></span>
|
||||
<input name="frictionRate" value="0.06" required type="number" min="0.01" step="0.01">
|
||||
Height</label><label class="input w-full"><span class="label"></span>
|
||||
<input name="height" type="number" placeholder="Height (Optional)"></label>
|
||||
<button class="btn btn-secondary btn-block mt-6" type="submit">Submit</button>
|
||||
</form>
|
||||
<div id="resultView"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<div class="bottom-0 left-0 bg-error">
|
||||
<footer class="footer sm:footer-horizontal footer-center
|
||||
bg-base-300 text-base-content p-4">
|
||||
<aside>
|
||||
<p>Copyright © 2026 - All rights reserved by Michael Housh</p>
|
||||
Openly licensed via CC-BY-NC-SA 4.0<a class="btn btn-ghost" href="https://git.housh.dev/michael/swift-duct-calc/src/branch/main/LICENSE" target="_blank"></a>
|
||||
</aside>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -32,67 +32,68 @@
|
||||
<div class="flex flex-col min-h-screen min-w-full justify-between" data-theme="default">
|
||||
<main class="flex flex-col min-h-screen min-w-full grow mb-auto">
|
||||
<div>
|
||||
<div class="flex justify-end m-4">
|
||||
<div class="flex justify-end space-x-4 m-4">
|
||||
<div class="tooltip tooltip-left" data-tip="Duct size calculator"><a class="btn btn-ghost btn-accent text-lg" href="/duct-size" target="_blank">Ductulator</a></div>
|
||||
<button class="btn btn-ghost btn-secondary text-lg" hx-get="/login" hx-target="body" hx-swap="outerHTML" hx-push-url="true">Login</button>
|
||||
</div>
|
||||
<div class="hero">
|
||||
<div class="relative hero-content text-center bg-base-300
|
||||
w-full min-h-[400px] rounded-3xl shadow-3xl overflow-hidden">
|
||||
<div class="mx-10 lg:mx-20">
|
||||
<div class="relative text-center bg-base-300
|
||||
rounded-3xl shadow-3xl overflow-hidden">
|
||||
<div class="bg-secondary text-xl font-bold
|
||||
absolute top-10 -left-15
|
||||
px-6 py-2 w-[250px] -rotate-45">BETA</div>
|
||||
<div>
|
||||
<div class="flex justify-center items-center">
|
||||
<div class="flex border-b-6 border-accent
|
||||
<div class="flex justify-center mt-30 md:mt-15 lg:mt-6">
|
||||
<div class="flex items-end border-b-6 border-accent
|
||||
text-8xl font-bold my-auto space-2">
|
||||
<h1 class="me-2">Duct Calc</h1>
|
||||
<div class="">
|
||||
<div>
|
||||
<span class="bg-secondary rounded-md
|
||||
text-5xl rotate-180 p-2" style="writing-mode: vertical-rl">Pro</span>
|
||||
text-5xl rotate-180 p-2 -mx-2" style="writing-mode: vertical-rl">Pro</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Open source residential duct design program<a class="btn btn-ghost text-md text-primary font-bold italic" href="https://git.housh.dev/michael/swift-duct-calc" target="_blank"></a>
|
||||
<p class="text-3xl py-6">Manual-D™ speed sheet, but on the web!</p>
|
||||
<button class="btn btn-xl btn-primary mt-6" hx-get="/signup" hx-target="body" hx-swap="outerHTML">Get Started</button>
|
||||
<p class="text-xs italic mt-8">
|
||||
<p class="text-xs italic my-6">
|
||||
Manual-D™ is a trademark of Air Conditioning Contractors of America (ACCA).
|
||||
|
||||
This site is not designed by or affiliated with ACCA.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mx-20 my-6">
|
||||
<div class="border-3 border-accent rounded-lg shadow-lg p-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="text-5xl text-primary font-bold">Features</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 my-6">
|
||||
<div class="border-3 border-accent rounded-lg shadow-lg p-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="text-5xl text-primary font-bold">Features</div>
|
||||
</div>
|
||||
<div class="text-xl ms-10 mt-10">
|
||||
<ul class="list-disc">
|
||||
<li>
|
||||
<div class="font-bold italic bg-secondary rounded-lg shadow-lg px-4 w-fit">Built by humans</div>
|
||||
</li>
|
||||
<li>Fully open source.</li>
|
||||
<li>Great replacement for speed sheet users.</li>
|
||||
<li>Great for classrooms.</li>
|
||||
<li>Store your projects in one place.</li>
|
||||
<li>Export final project to pdf.</li>
|
||||
<li>Import room loads via CSV file.</li>
|
||||
<li>Web based.</li>
|
||||
<li>Self host (run on your own infrastructure).</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-xl ms-10 mt-10">
|
||||
<ul class="list-disc">
|
||||
<li>
|
||||
<div class="font-bold italic bg-secondary rounded-lg shadow-lg px-4 w-fit">Built by humans</div>
|
||||
</li>
|
||||
<li>Fully open source.</li>
|
||||
<li>Great replacement for speed sheet users.</li>
|
||||
<li>Great for classrooms.</li>
|
||||
<li>Store your projects in one place.</li>
|
||||
<li>Export final project to pdf.</li>
|
||||
<li>Import room loads via CSV file.</li>
|
||||
<li>Web based.</li>
|
||||
<li>Self host (run on your own infrastructure).</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-3 border-accent rounded-lg shadow-lg p-4">
|
||||
<div class="text-5xl text-primary font-bold">Coming Soon</div>
|
||||
<div class="text-xl ms-10 mt-10">
|
||||
<ul class="list-disc">
|
||||
<li>API integration.</li>
|
||||
<li>Command line interface.</li>
|
||||
<li>Fitting selection tool.</li>
|
||||
<li>Room load import from PDF.</li>
|
||||
</ul>
|
||||
<div class="border-3 border-accent rounded-lg shadow-lg p-4">
|
||||
<div class="text-5xl text-primary font-bold">Coming Soon</div>
|
||||
<div class="text-xl ms-10 mt-10">
|
||||
<ul class="list-disc">
|
||||
<li>API integration.</li>
|
||||
<li>Command line interface.</li>
|
||||
<li>Fitting selection tool.</li>
|
||||
<li>Room load import from PDF.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user