Migrate to thin Eleventy build + a11y/SEO/perf/CI hardening (#20)
* chore(build): add Eleventy scaffold
Thin Eleventy build (v3.1.6, pinned) — passthrough-copies assets/,
robots.txt, sitemap.xml; outputs flat HTML to _site/. _data/site.json
holds site-wide constants; _data/images.json maps image keys to
src+width+height for the {% image %} shortcode (CLS fix). Output stays
flat HTML served from the same S3 bucket + CloudFront.
* refactor(templates): base layout, partials, shared JS, CSS extraction
- _includes/base.njk + nav/mobile-menu/footer partials reproduce the
shared chrome once (was hand-duplicated across 13 pages). Adds a
skip-link and <main> landmark (WCAG 2.4.1), aria-expanded/role=dialog
hooks on the menu, and a {% year %} shortcode replacing document.write.
- assets/js/nav.js: extracted sticky-nav + accessible mobile-menu dialog
(focus trap, Escape, focus return) + rAF-throttled hero parallax.
- assets/js/form.js: Basin AJAX submit with an accessible status region.
- assets/css/*.css: per-page inline <style> extracted into page CSS files
(home/about/services/careers/jobs/contact/social/legal/404); skip-link
+ :focus-visible added to main.css.
- index.njk: homepage converted as the reference page.
* fix(css): make hero-bg url root-relative after extraction
Inline CSS used a document-relative url('assets/...') that resolves
correctly from / but breaks once moved into /assets/css/home.css.
Rewrite to /assets/images/.
* refactor(pages): convert 12 pages to Eleventy templates
Convert about, services, careers (listing + 3 jobs), contact, social-
accountability, privacy-policy, terms-of-service, eula, and 404 from
standalone HTML to .njk against base.njk. Each page now carries only
front-matter (title/description/SEO) + its <main> content; shared head/
nav/footer/scripts come from the layout. JobPosting + LocalBusiness
JSON-LD preserved. Images use the {% image %} shortcode (width/height).
Contact gets an accessible #form-status region. form.js generalized to
wire BOTH the contact form and the .apply-form job application forms
(was contact-only), preserving each submit button's own label.
* fix(a11y): footer contrast to WCAG AA + scope services .form-group
Raise footer text colors (footer-bottom/col/brand/social/contact) and
darken --text-muted so muted text clears 4.5:1 on the dark footer and
warm-gray surfaces. Scope services' flex .form-group override to
.contact-form .form-group so it can't leak to the global rule.
* perf(seo): og-cover image, webp logos, hero preload
Add a real 1200x630 og-cover.jpg (was a 153x49 favicon) wired site-wide
via base.njk og:image/twitter:image. Convert nav/footer logos to webp
(nav 58KB->22KB); PNGs kept as passthrough so old URLs still resolve.
Preload the LCP hero image on the homepage (fetchpriority=high). All
<img> carry width/height via the image shortcode (CLS).
* ci(deploy): build-then-sync, cache headers, safe concurrency
Rename main.yml -> deploy.yaml (org convention). Build with Eleventy
(npm ci && npm run build) and sync _site/ instead of the repo root, so
only built output ships (no source/templates/node_modules). Split
Cache-Control (1-day assets, no-cache HTML) and keep /* invalidation
since filenames are not yet fingerprinted. concurrency cancel-in-progress
false so a deploy is never cut mid sync. ci.yaml validates _site/ via
ci-static build mode.
* docs: README for the Eleventy build and structure
* fix(security): wire services form, guard build, harden deploy
Fable build-review findings:
- BLOCK: services puts .contact-form on the <form> itself (contact uses a
wrapper div), so form.js selector '.contact-form form' never matched it
— the services lead form submitted natively with an empty reCAPTCHA
token. Selector now also matches form.contact-form.
- Guard the build before the --delete S3 sync: require index/contact/404
and >=40 files, so a silently-empty build can never wipe the live bucket.
- npm ci --ignore-scripts on deploy (build verified to pass) to shrink the
supply-chain window on the OIDC-credentialed runner.
- Escape quotes in the image shortcode alt text.
2026-06-12 17:02:06 -04:00
---
layout: base.njk
title: "Terms of Service — Sea Haven Industries"
description: "Terms of Service for Sea Haven Industries. Review the terms and conditions governing your use of the Sea Haven Industries website."
pageCss: legal
2026-06-12 17:23:11 -04:00
breadcrumbName: "Terms of Service"
Migrate to thin Eleventy build + a11y/SEO/perf/CI hardening (#20)
* chore(build): add Eleventy scaffold
Thin Eleventy build (v3.1.6, pinned) — passthrough-copies assets/,
robots.txt, sitemap.xml; outputs flat HTML to _site/. _data/site.json
holds site-wide constants; _data/images.json maps image keys to
src+width+height for the {% image %} shortcode (CLS fix). Output stays
flat HTML served from the same S3 bucket + CloudFront.
* refactor(templates): base layout, partials, shared JS, CSS extraction
- _includes/base.njk + nav/mobile-menu/footer partials reproduce the
shared chrome once (was hand-duplicated across 13 pages). Adds a
skip-link and <main> landmark (WCAG 2.4.1), aria-expanded/role=dialog
hooks on the menu, and a {% year %} shortcode replacing document.write.
- assets/js/nav.js: extracted sticky-nav + accessible mobile-menu dialog
(focus trap, Escape, focus return) + rAF-throttled hero parallax.
- assets/js/form.js: Basin AJAX submit with an accessible status region.
- assets/css/*.css: per-page inline <style> extracted into page CSS files
(home/about/services/careers/jobs/contact/social/legal/404); skip-link
+ :focus-visible added to main.css.
- index.njk: homepage converted as the reference page.
* fix(css): make hero-bg url root-relative after extraction
Inline CSS used a document-relative url('assets/...') that resolves
correctly from / but breaks once moved into /assets/css/home.css.
Rewrite to /assets/images/.
* refactor(pages): convert 12 pages to Eleventy templates
Convert about, services, careers (listing + 3 jobs), contact, social-
accountability, privacy-policy, terms-of-service, eula, and 404 from
standalone HTML to .njk against base.njk. Each page now carries only
front-matter (title/description/SEO) + its <main> content; shared head/
nav/footer/scripts come from the layout. JobPosting + LocalBusiness
JSON-LD preserved. Images use the {% image %} shortcode (width/height).
Contact gets an accessible #form-status region. form.js generalized to
wire BOTH the contact form and the .apply-form job application forms
(was contact-only), preserving each submit button's own label.
* fix(a11y): footer contrast to WCAG AA + scope services .form-group
Raise footer text colors (footer-bottom/col/brand/social/contact) and
darken --text-muted so muted text clears 4.5:1 on the dark footer and
warm-gray surfaces. Scope services' flex .form-group override to
.contact-form .form-group so it can't leak to the global rule.
* perf(seo): og-cover image, webp logos, hero preload
Add a real 1200x630 og-cover.jpg (was a 153x49 favicon) wired site-wide
via base.njk og:image/twitter:image. Convert nav/footer logos to webp
(nav 58KB->22KB); PNGs kept as passthrough so old URLs still resolve.
Preload the LCP hero image on the homepage (fetchpriority=high). All
<img> carry width/height via the image shortcode (CLS).
* ci(deploy): build-then-sync, cache headers, safe concurrency
Rename main.yml -> deploy.yaml (org convention). Build with Eleventy
(npm ci && npm run build) and sync _site/ instead of the repo root, so
only built output ships (no source/templates/node_modules). Split
Cache-Control (1-day assets, no-cache HTML) and keep /* invalidation
since filenames are not yet fingerprinted. concurrency cancel-in-progress
false so a deploy is never cut mid sync. ci.yaml validates _site/ via
ci-static build mode.
* docs: README for the Eleventy build and structure
* fix(security): wire services form, guard build, harden deploy
Fable build-review findings:
- BLOCK: services puts .contact-form on the <form> itself (contact uses a
wrapper div), so form.js selector '.contact-form form' never matched it
— the services lead form submitted natively with an empty reCAPTCHA
token. Selector now also matches form.contact-form.
- Guard the build before the --delete S3 sync: require index/contact/404
and >=40 files, so a silently-empty build can never wipe the live bucket.
- npm ci --ignore-scripts on deploy (build verified to pass) to shrink the
supply-chain window on the OIDC-credentialed runner.
- Escape quotes in the image shortcode alt text.
2026-06-12 17:02:06 -04:00
---
<!-- ── Page Hero ── -->
<section class="page-hero">
<div class="container">
<nav class="breadcrumb" aria-label="Breadcrumb">
<a href="/">Home</a>
<span aria-hidden="true">/</span>
<span>Terms of Service</span>
</nav>
<h1>Terms of Service</h1>
</div>
</section>
<!-- ── Content ── -->
<section class="prose-section">
<div class="container">
<div class="prose">
<p><em>Effective Date: April 4, 2026</em></p>
<p>Welcome to the Sea Haven Industries, Inc. website ("Site"). By accessing or using this Site, you agree to be bound by these Terms of Service ("Terms"). If you do not agree to these Terms, please do not use this Site.</p>
<h3>1. Acceptance of Terms</h3>
<p>By accessing, browsing, or using this Site, you acknowledge that you have read, understood, and agree to be bound by these Terms, as well as our <a href="/privacy-policy/">Privacy Policy</a>. These Terms apply to all visitors, users, and others who access or use the Site.</p>
<h3>2. Use of Website</h3>
<p>You agree to use this Site only for lawful purposes and in a manner that does not infringe upon the rights of, restrict, or inhibit anyone else's use of the Site. You may not use this Site to:</p>
<ul>
<li>Transmit any unlawful, threatening, abusive, or otherwise objectionable material</li>
<li>Gain unauthorized access to other computer systems</li>
<li>Use automated means to access the Site without permission</li>
<li>Interfere with or disrupt the Site or its servers</li>
</ul>
<h3>3. Intellectual Property</h3>
<p>All content on this Site, including text, graphics, logos, images, and software, is the property of Sea Haven Industries, Inc. or its licensors and is protected by applicable copyright, trademark, and other intellectual property laws. You may not reproduce, distribute, modify, or create derivative works from any content on this Site without our prior written consent.</p>
<h3>4. Disclaimer of Warranties</h3>
<p>This Site and its content are provided on an "as is" and "as available" basis. Sea Haven Industries makes no representations or warranties of any kind, express or implied, regarding the operation of the Site or the information, content, or materials included on the Site.</p>
<h3>5. Limitation of Liability</h3>
<p>To the fullest extent permitted by law, Sea Haven Industries shall not be liable for any damages of any kind arising from the use of this Site, including but not limited to direct, indirect, incidental, punitive, and consequential damages.</p>
<h3>6. Indemnification</h3>
<p>You agree to indemnify, defend, and hold harmless Sea Haven Industries, Inc., its officers, directors, employees, and agents from and against any claims, liabilities, damages, losses, or expenses arising out of or in any way connected with your access to or use of the Site.</p>
<h3>7. Governing Law</h3>
<p>These Terms shall be governed by and construed in accordance with the laws of the State of New York, without regard to its conflict of law principles.</p>
<h3>8. Modifications to Terms</h3>
<p>We reserve the right to modify these Terms at any time. Any changes will be effective immediately upon posting on the Site. Your continued use of the Site after changes are posted constitutes your acceptance of the revised Terms.</p>
<h3>9. Contact Us</h3>
<p>If you have any questions about these Terms of Service, please contact us:</p>
<p>Sea Haven Industries, Inc.<br>
710 Koehler Ave, Ronkonkoma, NY 11779<br>
Email: <a href="mailto:work-orders@seahaven.com">work-orders@seahaven.com</a><br>
Phone: (631) 776-5102</p>
</div>
</div>
</section>