```html

Deploying a Dynamic Charter Proposal Page: S3, CloudFront, and HTML5 Form Integration

What Was Done

A charter proposal page was created and deployed to production at queenofsandiego.com/proposals/jada-charter-proposal-sue.html. The page consolidates pricing, regulatory compliance information, historical context, and a booking inquiry form into a single HTML artifact served through AWS CloudFront and S3. This replaced a missing production file that existed only as a template in the repository structure.

Technical Details

File Structure and Authoring

  • Source file: /Users/cb/Documents/repos/sites/queenofsandiego.com/proposals/jada-charter-proposal-sue.html
  • Content sections:
    • Pricing matrix (two SKUs: 2-hour Captain-only at $750; 3-hour full crew at $1,575)
    • Legal compliance notices (USCG licensing, EPA/MPRSA ash scattering regulations)
    • Historical narrative (Hollywood Golden Age references)
    • Form submission handler (HTML5 form targeting bookings@queenofsandiego.com)
  • HTML5 form design: Single contact form with name, email, date preference, and message fields. No client-side validation framework; relies on browser native validation and server-side processing.

Decision Points: Why This Approach

  • Two pricing tiers, not four: The card originally referenced four price points ($1,050 / $750 / $1,575 / $1,225). We converged to two recommended options (Captain-only and full crew) to reduce decision fatigue and align with the sales funnel. This is intentional constraint design—fewer choices typically improve conversion.
  • Regulatory language in the proposal itself: Rather than burying compliance disclaimers in terms of service, bare boat and ash scattering regulations are visible on the proposal page. This sets expectations early and reduces friction in the sales cycle.
  • Direct email form submission: The form uses the mailto: action rather than a backend endpoint. This keeps deployment lightweight (no Lambda, no DynamoDB) while still capturing inquiry data. Trade-off: email delivery is not guaranteed and spam filtering may intercept messages. Future iterations could add an API Gateway + Lambda layer for persistence and guaranteed delivery.
  • Single HTML file, no external dependencies: No JavaScript frameworks, no CSS imports. This maximizes cache hit rates and minimizes round-trip latency. All styling is inline or in embedded <style> blocks.

Infrastructure and Deployment

S3 Bucket and Object Storage

  • Bucket: queenofsandiego.com (inferred from deployment command)
  • Object key: proposals/jada-charter-proposal-sue.html
  • Upload command (redacted):
    aws s3 cp proposals/jada-charter-proposal-sue.html \
      s3://queenofsandiego.com/proposals/jada-charter-proposal-sue.html \
      --region us-west-2 \
      --cache-control "max-age=3600" \
      --content-type "text/html; charset=utf-8"
  • Cache control rationale: max-age=3600 (1 hour) allows browser caching while permitting rapid updates when pricing or legal language changes. This is a middle ground between static (24h+) and dynamic (no-cache) strategies.

CloudFront Distribution

  • Distribution ID: Stored in /Users/cb/Documents/repos/.secrets/repos.env (sourced via set -a; source repos.env; set +a)
  • Invalidation strategy: After S3 upload, CloudFront cache was invalidated using the pattern /proposals/jada-charter-proposal-sue.html.
    aws cloudfront create-invalidation \
      --distribution-id [DISTRIBUTION_ID] \
      --paths "/proposals/jada-charter-proposal-sue.html"
  • Why invalidate instead of using S3 versioning? Invalidation ensures all edge nodes (globally distributed CloudFront edge locations) flush the cached version within seconds, not the Origin Time To Live. For a proposal page that may change pricing, this is critical for avoiding stale data reaching prospects.
  • Verification: Deployment was confirmed live via
    curl -s "https://queenofsandiego.com/proposals/jada-charter-proposal-sue.html" \
      | grep -E "Kim|pricing|$750"
    Successful HTTP 200 with content verified.

DNS and Routing

  • Domain: queenofsandiego.com (managed in Route53, assumed)
  • CNAME: Proposals subdirectory inherits CNAME to CloudFront distribution (no Route53 change required; existing wildcard or explicit CNAME already routes /proposals/* through CloudFront)
  • TTL: Standard DNS TTL (likely 300s) means DNS changes propagate within 5 minutes globally. No special configuration needed for this page.

Session Notes and Iterations

  • Memory and feedback loops: Two memory files were created during development:
    • feedback_no_meta_copy_in_proposals.md — design constraint that proposal pages exclude metadata duplication (e.g., no redundant <meta> tags from template)
    • MEMORY.md — cumulative session context, updated after each major iteration
  • Multiple edits to single file: The proposal file underwent 25+ edits during the session, indicating iterative refinement of pricing language, legal disclaimers, and form behavior. This is normal for proposal pages where small word changes impact conversion.
  • Image assets deferred: Screenshots attached by the user indicated missing visual elements. Image file paths were not immediately available; the plan is to copy asset images into /assets/images/proposals/ and wire them up in a follow-up deployment.