Correspondence

A thoughtful room
starts with a question.

Suggest a guide, flag a correction or ask about the journal. Keep project-specific technical questions for your qualified local specialist.

Write to the journal

All fields are required. This form prepares an email draft locally; it does not send a message or upload your details.

20–1,500 characters. Please omit payment information and sensitive personal details.

Your details stay in this page until you choose to open and send an email. Read the privacy policy before including personal information.

A note before you write

Useful context makes a better question.

For an editorial correction, include the guide title and the passage you mean. For a topic suggestion, tell us what decision feels unclear. This journal offers general design information, not structural, electrical, conservation or legal advice.

Your privacy choices

Essential storage remembers this choice. Optional categories are inactive on this website; enabling them does not load additional services.

===ENDFILE=== ===FILE: styles.css=== :root { --paper: #f5f1e9; --surface: #ebe5d9; --ink: #292e29; --muted: #605e54; --green: #2f4039; --rust: #85503a; --line: #c8c0b1; --white: #fffdf8; --error: #922c25; --space-1: 4px; --space-2: 8px; --space-3: 16px; --space-4: 24px; --space-5: 40px; --space-6: 64px; } * { box-sizing: border-box; } html { scroll-behavior: smooth; scroll-padding-top: 24px; } body { margin: 0; background: var(--paper); color: var(--ink); font-family: Arial, Helvetica, sans-serif; font-size: 16px; line-height: 1.7; } body.is-modal-open { overflow-y: hidden; } [hidden] { display: none !important; } h1, h2, h3, p, figure { margin: 0; } h1, h2, h3 { font-family: Georgia, "Times New Roman", serif; font-weight: 400; line-height: 1.12; letter-spacing: -.035em; overflow-wrap: anywhere; } h1 { font-size: clamp(48px, 6.5vw, 88px); } h2 { font-size: clamp(32px, 3.4vw, 48px); } h3 { font-size: clamp(28px, 2.7vw, 36px); } p, a, nav, address, label, button, li, td, th, code, pre { overflow-wrap: anywhere; } p + p { margin-top: 16px; } a { color: inherit; text-underline-offset: 5px; text-decoration-thickness: 1px; } a:hover { color: var(--rust); } a, button, input, textarea, select { -webkit-tap-highlight-color: transparent; } a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible { outline: 3px solid var(--rust); outline-offset: 4px; } button, input, textarea, select { font: inherit; } button { cursor: pointer; } button, .primary-button, .compact-cta { border: 1px solid var(--green); background: var(--paper); color: var(--green); padding: 8px 16px; line-height: 1.5; } button:hover, .primary-button:hover, .compact-cta:hover { background: var(--green); color: var(--paper); } button:disabled { cursor: not-allowed; background: var(--surface); color: var(--muted); border-color: var(--line); } button, a { transition: color .18s ease, background-color .18s ease, border-color .18s ease; } svg { display: block; max-width: 100%; } img { display: block; max-width: 100%; height: auto; } :where(.site-header, .header-actions, .desktop-nav, .hero, .section-heading, .guide-grid, .card-meta, .approach-grid, .footer-grid, .article-layout, .contact-layout, .cookie-banner, .cookie-actions, .dialog-heading, .check-row) > * { min-width: 0; } .container { width: min(100% - 80px, 1280px); margin-inline: auto; } .section { margin-top: 64px; } .eyebrow { color: var(--rust); font-size: 11px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase; line-height: 1.6; } .lede { font-size: clamp(18px, 1.7vw, 23px); line-height: 1.6; color: #4c5047; max-width: 640px; } .small { font-size: 13px; line-height: 1.8; color: var(--muted); } .text-link { display: inline-flex; align-items: center; gap: 16px; width: fit-content; font-size: 13px; font-weight: 700; text-decoration: none; padding-bottom: 8px; border-bottom: 1px solid var(--rust); } .text-link span { font-size: 20px; } .skip-link { position: absolute; top: 8px; left: 16px; z-index: 100; padding: 16px 24px; background: var(--green); color: var(--paper); transform: translateY(-160%); } .skip-link:focus { transform: translateY(0); } .site-header { height: 64px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 24px; padding-inline: 40px; border-bottom: 1px solid var(--line); } .brand { display: flex; align-items: center; gap: 8px; font-family: Georgia, "Times New Roman", serif; font-size: 18px; line-height: 1.05; letter-spacing: -.035em; text-decoration: none; overflow-wrap: anywhere; } .brand svg { flex: 0 0 28px; } .brand span { min-width: 0; } .desktop-nav { display: flex; align-items: center; gap: 24px; font-size: 12px; } .desktop-nav a { text-decoration: none; } [aria-current="page"] { text-decoration: underline; text-underline-offset: 5px; } .header-actions { display: flex; justify-content: flex-end; align-items: center; gap: 8px; } .compact-cta { display: inline-flex; align-items: center; gap: 16px; font-size: 11px; text-decoration: none; } .menu-toggle { display: none; padding: 4px 8px; font-size: 20px; } .hero { display: grid; grid-template-columns: 1fr 1.05fr; align-items: center; gap: 64px; padding-top: 64px; } .hero-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; } .hero-copy .lede { max-width: 440px; } .hero-copy h1 { font-size: clamp(52px, 6.4vw, 88px); } .hero-caption { margin-top: 16px; font-size: 12px; color: var(--muted); max-width: 280px; } .hero-art { align-self: stretch; } .parisian-apartment-illustration { width: 100%; height: auto; } figcaption { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 16px; padding-top: 16px; font-size: 11px; color: var(--muted); } .section-heading { display: grid; grid-template-columns: 1.4fr 1fr; align-items: end; gap: 64px; margin-bottom: 40px; } .section-heading .eyebrow { margin-bottom: 16px; } .section-heading > p { max-width: 400px; color: var(--muted); font-size: 15px; } .guide-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px 24px; } .guide-card, .note-card { border-top: 2px solid var(--rust); padding: 24px; display: flex; flex-direction: column; gap: 24px; background: var(--surface); color: var(--ink); } .guide-card p, .note-card p { margin: 0; } .guide-card { min-height: 340px; } .guide-card h3 a { text-decoration: none; } .guide-card > p { color: #56574d; font-size: 15px; } .guide-card > .text-link { margin-top: auto; } .card-meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16px; font-size: 10px; line-height: 1.5; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); } .approach { padding-block: 64px; background: var(--green); color: var(--paper); } .approach-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; } .approach .eyebrow { color: #d8c2a4; margin-bottom: 24px; } .approach .lede { color: var(--paper); margin-bottom: 24px; } .approach .text-link { margin-top: 24px; border-color: #d8c2a4; } .approach a:hover { color: #e1c5a4; } .site-footer { border-top: 1px solid var(--line); padding-block: 64px; } .footer-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr; gap: 40px; } .footer-brand { display: inline-block; font: 26px Georgia, "Times New Roman", serif; letter-spacing: -.04em; text-decoration: none; overflow-wrap: anywhere; } .footer-grid > div > p { margin-top: 16px; font-size: 14px; } .footer-grid > div > .small { font-size: 12px; } .footer-grid nav { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; font-size: 13px; } .footer-grid nav a { text-decoration: none; } .footer-heading { font: 700 11px Arial, Helvetica, sans-serif; text-transform: uppercase; letter-spacing: .12em; margin-bottom: 16px; color: var(--rust); } .link-button { border: 0; padding: 0; text-align: left; background: transparent; color: var(--ink); text-decoration: underline; text-underline-offset: 5px; font-size: inherit; } .link-button:hover { background: transparent; color: var(--rust); } .article-page, .legal-page, .contact-page { padding-bottom: 64px; } .article-header { padding-block: 64px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; align-items: flex-start; gap: 24px; } .article-header h1 { max-width: 1000px; } .article-header .lede { max-width: 760px; } .breadcrumb { font-size: 12px; color: var(--muted); } .article-layout { display: grid; grid-template-columns: minmax(0, .65fr) minmax(0, 1.6fr); gap: 64px; padding-top: 64px; align-items: start; } .article-aside .note-card { max-width: 340px; } .article-aside p:not(.eyebrow) { font: 24px/1.5 Georgia, "Times New Roman", serif; } .article-aside nav { display: flex; flex-direction: column; gap: 16px; font-size: 12px; } .prose { max-width: 760px; } .prose section + section { margin-top: 64px; } .prose h2 { font-size: clamp(27px, 2.8vw, 36px); margin-bottom: 24px; } .prose p { color: #45483f; } .prose ul { padding-left: 24px; } .prose li + li { margin-top: 8px; } .next-guide { margin-top: 64px; padding-top: 24px; border-top: 2px solid var(--rust); display: flex; flex-direction: column; gap: 24px; } .next-guide a { font: 28px/1.3 Georgia, "Times New Roman", serif; text-decoration: none; } .next-guide .eyebrow { color: var(--rust); } .legal-prose { margin: 64px auto 0; } .table-wrapper { max-width: 100%; overflow-x: auto; margin-top: 24px; } table { width: 100%; border-collapse: collapse; font-size: 13px; line-height: 1.6; } caption { text-align: left; margin-bottom: 16px; font-weight: 700; } th, td { padding: 16px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; } thead th { background: var(--green); color: var(--paper); } tbody th { font-weight: 700; } code { font-size: 12px; } .contact-layout { display: grid; grid-template-columns: 1.2fr 1fr; gap: 64px; margin-top: 64px; } .contact-layout > section > h2 { margin-bottom: 24px; } .contact-layout > section > p { color: var(--muted); } form { margin-top: 40px; display: flex; flex-direction: column; align-items: stretch; gap: 24px; } .field { display: flex; flex-direction: column; gap: 8px; } .field label { font-size: 13px; font-weight: 700; } input:not([type="checkbox"]), textarea, select { width: 100%; min-width: 0; max-width: 100%; border: 1px solid #8c8b7e; border-radius: 0; background: var(--white); color: var(--ink); padding: 16px; line-height: 1.5; } textarea { resize: vertical; } .field-hint { font-size: 12px; color: var(--muted); } .field-error { font-size: 13px; color: var(--error); margin: 0; } .is-invalid { border: 2px solid var(--error) !important; } .primary-button { background: var(--green); color: var(--paper); text-decoration: none; display: inline-block; width: fit-content; padding: 16px 24px; font-size: 13px; } .primary-button:hover { background: #1f2d27; color: var(--paper); } form > .small { margin: 0; } .form-status { font-size: 14px; color: var(--green); } .form-status:empty { display: none; } .draft-result h3 { font-size: 27px; } .draft-preview { white-space: pre-wrap; margin: 0; font: 13px/1.7 Arial, Helvetica, sans-serif; } address { font-style: normal; font-size: 15px; } .contact-details { display: flex; flex-direction: column; gap: 40px; } .contact-details h2 { font-size: 34px; } .static-map svg { width: 100%; height: auto; } .contact-note { max-width: 760px; } .contact-note h2 { margin-block: 24px; } .notice { padding: 24px; border-left: 2px solid var(--rust); background: var(--surface); color: var(--ink); margin-top: 24px; } .cookie-banner { position: fixed; bottom: 0; left: 0; right: 0; z-index: 20; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 24px; padding: 24px 40px; max-height: 65dvh; overflow-y: auto; background: var(--white); color: var(--ink); border-top: 1px solid var(--line); box-shadow: 0 -8px 32px #292e2910; } .cookie-banner h2 { font-size: 24px; margin-bottom: 8px; } .cookie-banner p { font-size: 12px; line-height: 1.6; max-width: 600px; } .cookie-actions { display: flex; flex-wrap: wrap; gap: 8px; } .cookie-actions button { font-size: 11px; padding: 8px 16px; min-height: 40px; } dialog { width: min(560px, calc(100% - 32px)); max-width: calc(100% - 32px); max-height: calc(100dvh - 32px); padding: 24px; border: 1px solid var(--line); background: var(--paper); color: var(--ink); overflow-y: auto; } dialog::backdrop { background: #19221fcc; color: var(--paper); } dialog[open] { display: block; } .dialog-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-bottom: 24px; } .dialog-heading h2 { font-size: 32px; } .dialog-heading button { flex-shrink: 0; padding: 8px 16px; font-size: 11px; } .preferences-dialog > p { font-size: 14px; } .check-row { display: flex; align-items: flex-start; gap: 16px; margin-block: 24px; font-size: 14px; } input[type="checkbox"] { width: 20px; height: 20px; flex: 0 0 20px; margin: 2px 0 0; accent-color: var(--green); } .preferences-dialog .small { margin-top: 16px; } .preferences-dialog .small:empty { display: none; } .menu-dialog nav { display: flex; flex-direction: column; gap: 24px; padding-block: 16px; } .menu-dialog nav a { font: 25px/1.25 Georgia, "Times New Roman", serif; text-decoration: none; } .menu-dialog nav a[aria-current="page"] { text-decoration: underline; } @media (min-width: 1100px) { .guide-card:nth-child(4) { grid-column: 1 / 2; } .guide-card:nth-child(5) { grid-column: 2 / 4; } } @media (max-width: 1099px) { .site-header { padding-inline: 24px; gap: 16px; } .desktop-nav { gap: 16px; } .brand { font-size: 16px; } .hero { gap: 40px; } .guide-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .guide-card:last-child { grid-column: 1 / -1; } .article-layout, .contact-layout { gap: 40px; } .cookie-banner { grid-template-columns: 1fr; gap: 16px; } } @media (max-width: 767px) { .container { width: calc(100% - 48px); } .site-header { height: 52px; grid-template-columns: minmax(0, 1fr) auto; padding-inline: 24px; gap: 16px; } .brand { font-size: 16px; max-width: 240px; } .brand svg { width: 22px; height: 28px; flex-basis: 22px; } .desktop-nav { display: none; } .menu-toggle { display: inline-block; } .compact-cta { padding: 8px; gap: 8px; font-size: 10px; } .hero { grid-template-columns: 1fr; gap: 40px; padding-top: 40px; } .hero-copy h1 { font-size: clamp(48px, 10vw, 72px); } .hero-caption { max-width: 100%; margin-top: 0; } .hero-art { max-width: 560px; width: 100%; } .section-heading, .approach-grid { grid-template-columns: 1fr; gap: 24px; } .guide-card { padding: 24px; } .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 24px; } .footer-grid > div { grid-column: 1 / -1; } .article-header { padding-top: 40px; } .article-layout, .contact-layout { grid-template-columns: 1fr; gap: 64px; } .article-aside .note-card { max-width: none; } .article-aside p:not(.eyebrow) { font-size: 23px; } .article-aside nav { flex-direction: row; flex-wrap: wrap; gap: 16px 24px; } .contact-details { gap: 40px; } .cookie-banner { padding: 16px 24px; max-height: 55dvh; } .cookie-banner h2 { font-size: 22px; } .cookie-actions { gap: 8px; } .cookie-actions button { flex: 1 1 auto; } table { font-size: 12px; } th, td { padding: 16px; } } @media (max-width: 539px) { .guide-grid { grid-template-columns: 1fr; } .guide-card:last-child { grid-column: auto; } .guide-card { min-height: 0; } .guide-card > .text-link { margin-top: 0; } .card-meta { font-size: 10px; } .footer-grid { grid-template-columns: 1fr; } .footer-grid > div { grid-column: auto; } .article-header h1 { font-size: 48px; } .contact-details h2 { font-size: 32px; } } @media (max-width: 399px) { .container { width: calc(100% - 32px); } .site-header { padding-inline: 16px; gap: 8px; } .brand { font-size: 14px; gap: 4px; } .brand svg { width: 18px; flex-basis: 18px; } .header-actions { gap: 4px; } .compact-cta { padding: 8px; gap: 4px; font-size: 9px; } .menu-toggle { font-size: 18px; padding: 4px 8px; } h1, .hero-copy h1, .article-header h1 { font-size: 42px; } h2 { font-size: 30px; } .guide-card, .note-card { padding: 24px; } .cookie-banner { padding: 16px; } .cookie-actions { display: grid; grid-template-columns: 1fr 1fr; } .cookie-actions button { padding: 8px; } .cookie-actions button:last-child { grid-column: 1 / -1; } .dialog-heading { gap: 16px; } .dialog-heading h2 { font-size: 27px; } .dialog-heading button { padding: 8px; } dialog { padding: 24px; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } html { scroll-behavior: auto; } } ===ENDFILE=== ===FILE: script.js=== (() => { "use strict"; const menu = document.querySelector("[data-menu-dialog]"); const menuOpen = document.querySelector("[data-menu-open]"); const menuClose = document.querySelector("[data-menu-close]"); const preferences = document.querySelector("[data-cookie-dialog]"); const preferencesClose = document.querySelector("[data-cookie-close]"); const banner = document.querySelector("[data-cookie-banner]"); const analytics = document.querySelector("[data-cookie-analytics]"); const functional = document.querySelector("[data-cookie-functional]"); const saveButton = document.querySelector("[data-cookie-save]"); const storageStatus = document.querySelector("[data-cookie-status]"); const choiceButtons = document.querySelectorAll("[data-cookie-choice]"); const storageKey = "spg-cookie-consent-v1"; let savedChoice = null; let preferenceOpener = null; function validChoice(value) { return value && value.version === 1 && ["accept", "reject", "custom"].includes(value.choice) && typeof value.analytics === "boolean" && typeof value.functional === "boolean" && typeof value.savedAt === "string"; } try { const stored = JSON.parse(localStorage.getItem(storageKey)); if (validChoice(stored)) savedChoice = stored; } catch { savedChoice = null; } function syncScrollLock() { document.body.classList.toggle("is-modal-open", menu.open || preferences.open); } menuOpen.addEventListener("click", () => { menu.showModal(); syncScrollLock(); }); menuClose.addEventListener("click", () => menu.close()); menu.addEventListener("close", () => { syncScrollLock(); if (window.innerWidth < 768) menuOpen.focus(); }); menu.addEventListener("click", event => { if (event.target === menu) { const rect = menu.getBoundingClientRect(); if (event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom) { menu.close(); } } }); window.addEventListener("resize", () => { if (window.innerWidth >= 768 && menu.open) menu.close(); }); function openPreferences(opener) { preferenceOpener = opener; analytics.checked = savedChoice ? savedChoice.analytics : false; functional.checked = savedChoice ? savedChoice.functional : false; storageStatus.textContent = ""; if (menu.open) menu.close(); preferences.showModal(); syncScrollLock(); } preferencesClose.addEventListener("click", () => preferences.close()); preferences.addEventListener("close", () => { syncScrollLock(); if (preferenceOpener && preferenceOpener.isConnected && !preferenceOpener.closest("[hidden]")) { preferenceOpener.focus(); } }); function storeChoice(choice, allowAnalytics, allowFunctional) { savedChoice = { version: 1, choice, analytics: allowAnalytics, functional: allowFunctional, savedAt: new Date().toISOString() }; let persistent = true; try { localStorage.setItem(storageKey, JSON.stringify(savedChoice)); } catch { persistent = false; } const focusWasInBanner = banner.contains(document.activeElement); banner.hidden = true; if (persistent) { if (preferences.open) preferences.close(); if (focusWasInBanner) { const footerPreferences = document.querySelector( '.site-footer [data-cookie-choice="preferences"]' ); footerPreferences.focus({ preventScroll: true }); } } else { if (!preferences.open) { analytics.checked = allowAnalytics; functional.checked = allowFunctional; preferences.showModal(); syncScrollLock(); } storageStatus.textContent = "Your choice applies to this page, but your browser blocked storage. " + "The banner may return on navigation or reload. No optional services are active."; } } choiceButtons.forEach(button => { button.addEventListener("click", () => { const choice = button.dataset.cookieChoice; if (choice === "preferences") { openPreferences(button); } else if (choice === "accept") { storeChoice("accept", true, true); } else if (choice === "reject") { storeChoice("reject", false, false); } }); }); saveButton.addEventListener("click", () => { storeChoice("custom", analytics.checked, functional.checked); }); banner.hidden = Boolean(savedChoice); window.addEventListener("storage", event => { if (event.key !== storageKey && event.key !== null) return; try { const value = event.newValue ? JSON.parse(event.newValue) : null; savedChoice = validChoice(value) ? value : null; } catch { savedChoice = null; } banner.hidden = Boolean(savedChoice); if (preferences.open) { analytics.checked = Boolean(savedChoice && savedChoice.analytics); functional.checked = Boolean(savedChoice && savedChoice.functional); } }); const form = document.querySelector("[data-contact-form]"); if (!form) return; const fields = Array.from(form.querySelectorAll("[data-contact-field]")); const errorElements = Array.from(form.querySelectorAll("[data-error-for]")); const formStatus = form.querySelector("[data-form-status]"); const result = form.querySelector("[data-draft-result]"); const draftLink = form.querySelector("[data-email-draft]"); const preview = form.querySelector("[data-draft-preview]"); const submitButton = form.querySelector("[data-contact-submit]"); submitButton.disabled = false; function errorFor(field) { const value = field.value.trim(); if (field.name === "name") { if (value.length < 2) return "Enter your name using at least 2 characters."; if (value.length > 100) return "Keep your name to 100 characters or fewer."; } if (field.name === "email") { if (!value || field.validity.typeMismatch || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) { return "Enter a valid email address, such as [email protected]."; } if (value.length > 254) return "Keep the email address to 254 characters or fewer."; } if (field.name === "topic" && !value) return "Choose a topic for your message."; if (field.name === "message") { if (value.length < 20) return "Write at least 20 characters so the question is clear."; if (value.length > 1500) return "Keep the message to 1,500 characters or fewer."; } return ""; } function validateField(field) { const message = errorFor(field); const error = errorElements.find(element => element.dataset.errorFor === field.name); field.classList.toggle("is-invalid", Boolean(message)); field.setAttribute("aria-invalid", String(Boolean(message))); error.textContent = message; error.hidden = !message; return !message; } fields.forEach(field => { field.addEventListener("blur", () => validateField(field)); const handleEdit = () => { if (field.getAttribute("aria-invalid") === "true") validateField(field); if (!result.hidden) { result.hidden = true; draftLink.href = "mailto:[email protected]"; preview.textContent = ""; formStatus.textContent = "Your details changed. Prepare a new draft when you are ready."; } }; field.addEventListener("input", handleEdit); field.addEventListener("change", handleEdit); }); form.addEventListener("submit", event => { event.preventDefault(); const invalid = fields.filter(field => !validateField(field)); if (invalid.length) { result.hidden = true; formStatus.textContent = `Please correct ${invalid.length === 1 ? "the highlighted field" : `the ${invalid.length} highlighted fields`}. Nothing has been sent.`; invalid[0].focus(); return; } const values = Object.fromEntries(fields.map(field => [field.name, field.value.trim()])); const recipient = values.topic === "Privacy enquiry" ? "[email protected]" : "[email protected]"; const subject = `Journal enquiry: ${values.topic}`; const body = `Name: ${values.name}\nReply email: ${values.email}\nTopic: ${values.topic}\n\n${values.message}`; draftLink.href = `mailto:${recipient}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`; preview.textContent = `To: ${recipient}\nSubject: ${subject}\n\n${body}`; result.hidden = false; formStatus.textContent = "Draft prepared locally. Review it below; nothing has been sent."; draftLink.focus(); }); })(); ===ENDFILE===