← back to Coming Soon Template

template.html

305 lines

<!doctype html>
<html lang="en" data-theme="light">
<head>
<!--
  Coming-soon template — Gucci-aesthetic editorial landing.
  Per-domain swap points (case-sensitive, double-curly):
    {{WORDMARK}}     — domain stem, no TLD          → e.g. "abramsos"
    {{TAGLINE}}      — italic line under wordmark    → e.g. "the operating system"
    {{HERO_URL}}     — 2560×1600 editorial photo URL → CC0 or Steve-owned
    {{HERO_ALT}}     — accessible alt text
    {{DOMAIN}}       — full domain incl. TLD         → posted as `source` to /api/email-signup
    {{PAGE_TITLE}}   — <title> + og:title            → e.g. "abramsos — coming soon"
    {{ACCENT_HEX}}   — single accent hex for chrome  → keep neutral or pull from hero

  Paper-design specs:
    container max-width: 1440px center, 24px gutters
    grid: hero 100vh, wordmark zone 480px below
    type scale (modular 1.25): 11→14→18→22→28→36→48 (px)
    wordmark: clamp(56px, 9vw, 128px), Cormorant Garamond display, weight 300
    tagline: 12px, sans, +0.06em tracked, uppercase, opacity .6
    email input: 14px monospace, hairline 1px underline, no border
    breakpoints: <=720 mobile (wordmark→clamp 44px,12vw,96px; hero 70vh)

  Standing rules honored:
    - Logo upper-left (initial only)
    - Hamburger upper-right (decorative — no menu wired)
    - Sun/moon toggle next to hamburger (anti-flash inline script)
    - Wordmark BELOW the hero photo, never overlapping
    - Viewport meta required (mobile @media depends on it)
    - No AI-vendor names visible
-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<title>{{PAGE_TITLE}}</title>
<meta property="og:title" content="{{PAGE_TITLE}}">
<meta property="og:image" content="{{HERO_URL}}">
<meta name="theme-color" content="#faf8f3">
<link rel="preload" as="image" href="{{HERO_URL}}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,500;1,300&family=Inter:wght@300;400&family=JetBrains+Mono:wght@300;400&display=swap">
<script>
  // Anti-flash theme hydration — must run before paint
  (function(){
    try {
      var t = localStorage.getItem('cs-theme');
      if (t === 'dark' || (t === null && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
        document.documentElement.setAttribute('data-theme', 'dark');
      }
    } catch(e) {}
  })();
</script>
<style>
  :root {
    --bg: #faf8f3;
    --ink: #0f0e0c;
    --ink-soft: #57544c;
    --ink-faint: #9b958a;
    --line: #e5dfd0;
    --card: #ffffff;
    --accent: {{ACCENT_HEX}};
    --serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
    --sans: 'Inter', -apple-system, system-ui, sans-serif;
    --mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  }
  html[data-theme="dark"] {
    --bg: #0f0e0c;
    --ink: #faf8f3;
    --ink-soft: #b5ab98;
    --ink-faint: #6c6557;
    --line: #2a2820;
    --card: #18170f;
  }
  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink); }
  body { font-family: var(--sans); font-weight: 300; -webkit-font-smoothing: antialiased; line-height: 1.5; min-height: 100vh; }
  a { color: inherit; text-decoration: none; }

  /* HEADER — fixed bar, transparent over hero, fades to bg on scroll */
  header.gh {
    position: fixed; top: 0; left: 0; right: 0; z-index: 10;
    display: flex; justify-content: space-between; align-items: center;
    padding: 22px 28px;
    pointer-events: none;
  }
  header.gh > * { pointer-events: auto; }
  .glyph {
    font-family: var(--serif); font-weight: 300; font-size: 32px; line-height: 1;
    color: var(--ink); letter-spacing: -0.02em;
    text-shadow: 0 1px 12px rgba(0,0,0,.22);
  }
  html[data-theme="dark"] .glyph { text-shadow: 0 1px 12px rgba(0,0,0,.55); }
  .top-right { display: flex; align-items: center; gap: 18px; }
  .theme-toggle, .ham, .login {
    background: transparent; border: 0; padding: 6px; cursor: pointer;
    color: var(--ink); width: 32px; height: 32px;
    display: flex; align-items: center; justify-content: center;
    filter: drop-shadow(0 1px 8px rgba(0,0,0,.22));
  }
  .ham svg, .theme-toggle svg, .login svg { width: 22px; height: 22px; }

  /* HERO — full-bleed editorial photo */
  .hero {
    width: 100%; height: 100vh; min-height: 560px;
    background: var(--card) center/cover no-repeat;
    background-image: url('{{HERO_URL}}');
    position: relative;
  }
  .hero::after {
    /* Subtle bottom-fade so the wordmark zone reads cleanly when content peeks */
    content: ''; position: absolute; inset: auto 0 0 0; height: 24%;
    background: linear-gradient(to bottom, transparent, var(--bg));
    pointer-events: none;
  }

  /* WORDMARK ZONE — center column under hero */
  .meta {
    max-width: 720px; margin: 0 auto; padding: 64px 24px 96px;
    text-align: center;
  }
  .wordmark {
    font-family: var(--serif); font-weight: 300; font-style: normal;
    font-size: clamp(56px, 9vw, 128px); line-height: 1.02;
    letter-spacing: -0.01em; color: var(--ink);
    margin: 0 0 14px;
  }
  .tagline {
    font-family: var(--serif); font-style: italic; font-weight: 300;
    font-size: clamp(16px, 2.4vw, 22px);
    color: var(--ink-soft); margin: 0 0 4px;
  }
  .eyebrow {
    font-family: var(--sans); font-size: 11px; font-weight: 400;
    text-transform: uppercase; letter-spacing: 0.18em;
    color: var(--ink-faint); margin: 0 0 24px;
  }

  /* EMAIL CAPTURE — hairline, monospace, link-style submit */
  form.signup {
    margin: 40px auto 0; max-width: 420px;
    display: flex; align-items: baseline; gap: 18px;
    border-bottom: 1px solid var(--line);
    padding-bottom: 6px;
  }
  form.signup input[type=email] {
    flex: 1; min-width: 0;
    background: transparent; border: 0; outline: none;
    font-family: var(--mono); font-size: 14px; font-weight: 400;
    color: var(--ink); padding: 10px 0;
  }
  form.signup input[type=email]::placeholder { color: var(--ink-faint); }
  form.signup button {
    background: transparent; border: 0; padding: 0; cursor: pointer;
    font-family: var(--sans); font-size: 11px; font-weight: 400;
    text-transform: uppercase; letter-spacing: 0.18em;
    color: var(--ink); border-bottom: 1px solid var(--ink);
    padding-bottom: 2px;
    transition: opacity .15s ease;
  }
  form.signup button:hover { opacity: 0.6; }
  form.signup button:disabled { color: var(--ink-faint); border-color: var(--ink-faint); cursor: progress; }
  .signup-msg {
    margin: 14px auto 0; max-width: 420px;
    font-family: var(--sans); font-size: 12px; color: var(--ink-soft);
    min-height: 18px;
    text-align: center;
  }
  .signup-msg.err { color: #c0392b; }
  .signup-msg.ok { color: #1e6b3a; }

  /* FOOTER */
  footer.gf {
    margin-top: 40px; padding: 28px 24px 36px;
    border-top: 1px solid var(--line);
    text-align: center;
    font-family: var(--sans); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-faint);
  }
  footer.gf a {
    color: var(--ink-soft); border-bottom: 1px solid transparent;
    transition: border-color .15s ease;
  }
  footer.gf a:hover { border-color: var(--ink-soft); }
  .gf-domain {
    font-family: var(--serif); font-style: italic; font-size: 14px;
    text-transform: none; letter-spacing: 0; color: var(--ink-soft);
    margin-right: 14px;
  }

  /* Mobile */
  @media (max-width: 720px) {
    .hero { height: 70vh; min-height: 480px; }
    .meta { padding: 48px 20px 72px; }
    header.gh { padding: 16px 18px; }
    .glyph { font-size: 26px; }
  }

  /* Print — keep wordmark + tagline readable; suppress chrome */
  @media print {
    header.gh, .theme-toggle, .ham, .login, form.signup, .signup-msg { display: none; }
    .hero { height: 60vh; }
  }
</style>
</head>
<body>

<header class="gh">
  <a href="/" class="glyph" aria-label="{{WORDMARK}} home">{{WORDMARK_INITIAL}}</a>
  <div class="top-right">
    <button class="theme-toggle" id="themeToggle" aria-label="Toggle light/dark theme">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4">
        <circle cx="12" cy="12" r="4"/>
        <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
      </svg>
    </button>
    <a class="login" href="https://admin.agentabrams.com/" aria-label="Admin login">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4">
        <circle cx="12" cy="8" r="4"/>
        <path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/>
      </svg>
    </a>
    <button class="ham" aria-label="Menu (coming soon)">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4">
        <path d="M3 7h18M3 12h18M3 17h18"/>
      </svg>
    </button>
  </div>
</header>

<section class="hero" role="img" aria-label="{{HERO_ALT}}"></section>

<main class="meta">
  <p class="eyebrow">Coming soon</p>
  <h1 class="wordmark">{{WORDMARK}}</h1>
  <p class="tagline">{{TAGLINE}}</p>

  <form class="signup" id="signupForm" novalidate>
    <input type="email" name="email" id="emailInput" placeholder="your@email.com" required autocomplete="email" inputmode="email">
    <button type="submit" id="signupBtn">Notify me</button>
  </form>
  <div class="signup-msg" id="signupMsg" role="status" aria-live="polite"></div>
</main>

<footer class="gf">
  <a href="https://agentabrams.com" class="gf-domain">agentabrams.com</a>
  <span>©&nbsp;{{YEAR}}&nbsp;&middot;&nbsp;{{DOMAIN}}</span>
</footer>

<script>
  // Theme toggle
  (function(){
    var btn = document.getElementById('themeToggle');
    btn.addEventListener('click', function(){
      var cur = document.documentElement.getAttribute('data-theme') || 'light';
      var next = cur === 'dark' ? 'light' : 'dark';
      document.documentElement.setAttribute('data-theme', next);
      try { localStorage.setItem('cs-theme', next); } catch(e){}
    });
  })();

  // Email capture
  (function(){
    var form = document.getElementById('signupForm');
    var input = document.getElementById('emailInput');
    var btn = document.getElementById('signupBtn');
    var msg = document.getElementById('signupMsg');
    var ENDPOINT = 'https://agentabrams.com/api/email-signup';
    var SOURCE = '{{DOMAIN}}';

    function setMsg(text, cls) {
      msg.textContent = text || '';
      msg.classList.remove('err', 'ok');
      if (cls) msg.classList.add(cls);
    }
    form.addEventListener('submit', async function(e){
      e.preventDefault();
      var email = (input.value || '').trim();
      if (!email || !/.+@.+\..+/.test(email)) {
        setMsg('Please enter a valid email.', 'err'); return;
      }
      btn.disabled = true; setMsg('');
      try {
        var r = await fetch(ENDPOINT, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ email: email, source: SOURCE, timestamp: new Date().toISOString() })
        });
        if (r.ok) {
          form.style.display = 'none';
          setMsg('Thank you. We will be in touch.', 'ok');
        } else {
          setMsg('Could not save right now — please try again shortly.', 'err');
          btn.disabled = false;
        }
      } catch (err) {
        setMsg('Network error — please try again shortly.', 'err');
        btn.disabled = false;
      }
    });
  })();
</script>
</body>
</html>