Website under construction

New Zealand-made wood burners & sauna stoves


FLINT MINI
$2,499 inc gst

Compact wood burner for small spaces. Designed for tiny homes, huts, sleepouts and mobile setups.

Core
6mm body / 8mm cook top
Secondary burn
Insulated
Heat shields
Build
Rimu handles
Hand-blown marble window
Round door + porthole window

Available in Black · Sky Blue · Rose
Flue kit option

Buy →



FLINT Sauna

A compact wood-fired sauna stove designed for smaller spaces. Made to order on request.

Core
6mm body / 8mm cook top
Secondary burn
Insulated
Heat shields
Build
Rimu handles
Round door + porthole window
Cage

Available in Black · Sky Blue · Rose
Flue kit option

Request →


Future Heating Solutions

Flint Fires aims to contribute to improved woodburning technology and cleaner emissions outcomes in New Zealand by undertaking research and experimental development focused on woodburners, heating systems, and associated technologies.


Contact Dave

26 Newtown avenue
Newtown
Wellington
6021

[email protected]


FLINT MINI

Please note a NZ$500 deposit is required to confirm your order.

CHOOSE YOUR COLOUR
ADD-ONS
CUSTOMER DETAILS
Submitting your order details...
FLINT MINI
Thank you
Your Flint Mini order request has been received.
Your deposit details have been sent to your email.
Your build slot will be confirmed once the NZ$500 deposit has been received.
Please check your inbox.
Something went wrong. Please contact Flint Fires directly.
document.getElementById("flintOrderForm").addEventListener("submit", async function(e) { e.preventDefault(); const form = e.target; const intro = document.getElementById("flintIntro"); const submitting = document.getElementById("flintSubmitting"); const success = document.getElementById("flintSuccess"); const errorBox = document.getElementById("flintError"); const wrapper = document.getElementById("flintOrderWrapper"); const card = document.getElementById("flintCard"); const data = new FormData(form); const colour = data.get("colour") || ""; const flueKit = data.get("flue_kit") || ""; const address = data.get("address") || ""; const postcode = data.get("postcode") || ""; const shippingRegion = data.get("shipping_region") || ""; const ruralDelivery = data.get("rural_delivery") || ""; let shippingCost = ""; let shippingSummary = ""; if (shippingRegion === "North Island") { shippingCost = ruralDelivery ? "205" : "145"; shippingSummary = ruralDelivery ? "North Island rural — NZ$205" : "North Island — NZ$145"; } else if (shippingRegion === "South Island") { shippingCost = ruralDelivery ? "255" : "195"; shippingSummary = ruralDelivery ? "South Island rural — NZ$255" : "South Island — NZ$195"; } else if (shippingRegion === "Collect") { shippingCost = "0"; shippingSummary = "Workshop collection — NZ$0"; } else if (shippingRegion === "International") { shippingCost = "Quote required"; shippingSummary = "International — shipping quote required"; } const fullAddress = postcode ? address + "\nPostcode: " + postcode : address; data.set("stove", "Flint Mini"); data.set("colour", colour); data.set("flueKit", flueKit); data.set("address", fullAddress); data.set("shippingRegion", shippingRegion); data.set("ruralDelivery", ruralDelivery); data.set("shippingCost", shippingCost); data.set("shippingSummary", shippingSummary); data.set("shipping", shippingSummary); data.set("message", ""); form.style.display = "none"; intro.style.display = "none"; errorBox.style.display = "none"; success.style.display = "none"; submitting.style.display = "block"; try { const response = await fetch("https://script.google.com/macros/s/AKfycbyHoaWRXXUvqNk_uNDgIvNr-CKFZloiqPrZKRQyd2RrI3SETrmmLHh4hS-6N2M7GQX-/exec", { method: "POST", body: data }); const json = await response.json(); wrapper.style.maxWidth = "920px"; card.style.padding = "0"; card.style.border = "0"; card.style.background = "transparent"; card.style.boxShadow = "none"; submitting.style.display = "none"; success.style.display = "block"; } catch (error) { submitting.style.display = "none"; errorBox.style.display = "block"; form.style.display = "block"; intro.style.display = "block"; } });
FLINT FIRES
Custom Quote
Loading quote...
const CUSTOM_QUOTE_ENDPOINT = "https://flint-fires-admin.web.app/quote-api"; const QUOTE_UNAVAILABLE_MESSAGE = "This quote link is unavailable. Please contact Flint Fires and we will send you a new one."; let currentQuoteToken = ""; let currentQuotePrice = 0; function formatMoney(value) { return "$" + Number(value || 0).toLocaleString("en-NZ"); } function getQuoteTokenFromUrl() { const searchParams = new URLSearchParams(window.location.search); const hashParams = new URLSearchParams(window.location.hash.split("?")[1] || ""); return searchParams.get("t") || hashParams.get("t") || ""; } function showQuoteUnavailable() { const quoteMeta = document.getElementById("quoteMeta"); const quoteContent = document.getElementById("quoteContent"); const quoteError = document.getElementById("quoteError"); quoteMeta.textContent = ""; quoteContent.style.display = "none"; quoteError.textContent = QUOTE_UNAVAILABLE_MESSAGE; quoteError.style.display = "block"; } async function loadAcceptQuote() { const token = getQuoteTokenFromUrl(); const quoteMeta = document.getElementById("quoteMeta"); const quoteContent = document.getElementById("quoteContent"); const quoteError = document.getElementById("quoteError"); if (!token) { showQuoteUnavailable(); return; } currentQuoteToken = token; quoteMeta.textContent = "Loading quote..."; try { const response = await fetch(CUSTOM_QUOTE_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "getPublicQuote", token: token }) }); const result = await response.json(); if (!result.success) { throw new Error(result.error || "Quote could not be loaded."); } const quote = result.quote; currentQuotePrice = Number(quote.price || 0); const formattedDate = new Date(quote.quoteDate).toLocaleDateString("en-NZ", { day: "numeric", month: "long", year: "numeric" }); quoteMeta.textContent = quote.quoteNumber + " · " + formattedDate; document.getElementById("quoteTitle").textContent = quote.quoteTitle || ""; document.getElementById("quoteDescription").textContent = quote.description || ""; document.getElementById("quoteBasePrice").textContent = formatMoney(currentQuotePrice); document.getElementById("flintAcceptQuotePrice").textContent = formatMoney( quote.totalInclGst || currentQuotePrice ); if (quote.deliveryMethod) { const deliverySelect = document.getElementById("deliveryMethod"); deliverySelect.value = quote.deliveryMethod; } if (quote.deliveryMethod && quote.deliveryCost !== "" && quote.deliveryCost !== null && quote.deliveryCost !== undefined) { document.getElementById("quoteDeliveryPrice").textContent = formatMoney(quote.deliveryCost); document.getElementById("flintAcceptQuotePrice").textContent = formatMoney( quote.totalInclGst || currentQuotePrice ); document.getElementById("quotePriceNote").textContent = "incl GST, including delivery"; } else { updateQuoteTotal(); } if (quote.accepted) { const button = document.getElementById("acceptanceContinueButton"); const message = document.getElementById("acceptanceMessage"); button.style.display = "none"; message.style.display = "block"; message.textContent = "This quote has already been accepted. Thank you."; } quoteContent.style.display = "block"; quoteError.style.display = "none"; } catch (error) { console.error(error); showQuoteUnavailable(); } } async function updateQuoteTotal() { const deliveryMethod = document.getElementById("deliveryMethod").value.trim(); const deliveryPrice = document.getElementById("quoteDeliveryPrice"); const totalPrice = document.getElementById("flintAcceptQuotePrice"); const priceNote = document.getElementById("quotePriceNote"); if (!deliveryMethod) { deliveryPrice.textContent = "Select delivery"; totalPrice.textContent = formatMoney(currentQuotePrice); priceNote.textContent = "incl GST"; return; } if (deliveryMethod === "International delivery") { deliveryPrice.textContent = "Quoted separately"; totalPrice.textContent = formatMoney(currentQuotePrice); priceNote.textContent = "delivery to be quoted separately"; return; } deliveryPrice.textContent = "Calculating..."; try { const response = await fetch(CUSTOM_QUOTE_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "getPublicQuote", token: currentQuoteToken }) }); const quoteResponse = await response.json(); if (!quoteResponse.success) { throw new Error("Quote unavailable."); } const quote = quoteResponse.quote; const deliveryResponse = await fetch( "https://script.google.com/macros/s/AKfycbyHoaWRXXUvqNk_uNDgIvNr-CKFZloiqPrZKRQyd2RrI3SETrmmLHh4hS-6N2M7GQX-/exec", { method: "POST", body: JSON.stringify({ action: "calculateQuoteTotal", quotePrice: currentQuotePrice, deliveryMethod: deliveryMethod }) } ); const result = await deliveryResponse.json(); if (!result.success) { throw new Error(result.error || "Could not calculate delivery."); } deliveryPrice.textContent = formatMoney(result.deliveryCost); totalPrice.textContent = formatMoney(result.totalInclGst); priceNote.textContent = "incl GST, including delivery"; } catch (error) { console.error(error); deliveryPrice.textContent = "Could not calculate"; totalPrice.textContent = formatMoney(currentQuotePrice); priceNote.textContent = "delivery will be confirmed separately"; } } async function submitQuoteAcceptance() { const name = document.getElementById("customerName").value.trim(); const phone = document.getElementById("customerPhone").value.trim(); const address = document.getElementById("customerAddress").value.trim(); const deliveryMethod = document.getElementById("deliveryMethod").value.trim(); const button = document.getElementById("acceptanceContinueButton"); const message = document.getElementById("acceptanceMessage"); message.style.display = "block"; if (!name || !phone || !address || !deliveryMethod) { message.textContent = "Please fill in your name, phone number, delivery address, and delivery method."; return; } if (!currentQuoteToken) { message.textContent = QUOTE_UNAVAILABLE_MESSAGE; return; } button.disabled = true; button.textContent = "SUBMITTING..."; message.textContent = "Submitting your acceptance..."; try { const response = await fetch(CUSTOM_QUOTE_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "acceptPublicQuote", token: currentQuoteToken, customerName: name, customerPhone: phone, customerAddress: address, deliveryMethod: deliveryMethod }) }); const result = await response.json(); if (!result.success) { throw new Error(result.error || "Quote acceptance failed."); } if (result.alreadyAccepted) { message.textContent = "This quote has already been accepted. Thank you."; } else { message.textContent = "Thank you. Your quote has been accepted. We will email your deposit details shortly. If it does not arrive soon, please check your junk or spam folder."; } button.style.display = "none"; } catch (error) { console.error(error); message.textContent = "Sorry, something went wrong. Please contact Flint Fires directly."; button.disabled = false; button.textContent = "ACCEPT QUOTE"; } } loadAcceptQuote();