/* Glyphproof. Dark, warm, low light: ink and graphite on a near black plate,
   brass for the lens rim, the panel frame, links, focus rings and the button.
   Contrast ratios for every real text colour are listed in PLAN.md, "Redesign".

   Two compositions share these materials: the phone composition below 600 px
   and the desktop composition from 600 px up. Each has its own block at the
   end of its section. */
:root {
  --plate: #13110e;
  --plate-raised: #1b1814;
  --ink: #ece4d4;
  --ink-soft: #c9bfae;
  --ink-faint: #a39a8b;
  --rule: #39322a;
  --accent: #c8a165;
  --accent-deep: #d8b47a;
  --on-accent: #17130f;
  /* The sign-up panel: a raised plate a step lighter than the field, framed in brass. */
  --panel-top: #201c17;
  --panel-bottom: #1a1713;
  --frame: #8c7149;
  --frame-inner: #4f402d;
  --slot: #0e0c0a;
  --slot-edge: #7f705c;
  --slot-edge-hover: #9a8466;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.75 0 0 0 0 0.66 0 0 0 0 0.52 0 0 0 0.035 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  color-scheme: dark;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  background-color: var(--plate);
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  background-color: var(--plate);
  background-image:
    radial-gradient(ellipse 90% 70% at 30% 0%, rgba(120, 96, 64, 0.10), rgba(120, 96, 64, 0) 70%),
    var(--grain);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(200, 161, 101, 0.55);
  transition: color 500ms ease, text-decoration-color 500ms ease;
}

a:hover {
  color: var(--accent-deep);
  text-decoration-color: currentColor;
}

a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 2px;
}

.page {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 16px;
}

/* The field canvas sits behind everything and takes no input. */
.field {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  display: block;
  pointer-events: none;
}

/* ===== Home: hero ===== */
.hero {
  position: relative;
  overflow: hidden;
  overflow: clip;
  min-height: 100vh;
  min-height: 100svh;
  padding-left: 16px;
  padding-right: 16px;
  text-align: center;
}

.wordmark {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
}

.wordmark-word {
  display: inline-block;
  transform-origin: 50% 50%;
}

.tm {
  font-size: 0.32em;
  vertical-align: super;
  line-height: 0;
  margin-left: 2px;
  letter-spacing: 0;
  opacity: 0.8;
}

/* Hugs its two lines, so the clear zone the field leaves around it stays small. */
.tagline-group {
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding: 0 10px;
}

.tagline {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  line-height: 1.3;
  color: var(--ink);
}

.status {
  margin: 10px 0 0;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* Before field.js takes over, the arrival hides what it is about to animate.
   If the script never runs, the page shows itself after 2.5 s. */
.arriving .wordmark-word,
.arriving .tagline,
.arriving .status,
.arriving .field {
  opacity: 0;
  animation: show-anyway 0s linear 2.5s forwards;
}

@keyframes show-anyway { to { opacity: 1; } }

/* ===== Home: below the hero =====
   The page column overlaps the bottom of the hero by --peek, so the top of the
   panel shows on the first screen. It paints above the hero. */
.home .page { margin-top: calc(-1 * var(--peek)); }

.below { display: block; }

.contact {
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  letter-spacing: 0.03em;
  text-align: center;
}

/* Phone composition: a tall narrow poster. The wordmark fills the width, the
   panel shows its label and first sentence at the bottom of the first screen. */
@media (max-width: 599.98px) {
  :root { --peek: 146px; }
  .hero { padding-top: 19vh; padding-top: 19svh; }
  .wordmark { font-size: 15.4vw; }
  .tagline-group { margin-top: 22px; }
  .tagline { font-size: clamp(20px, 6.15vw, 27px); }
  .status { font-size: 12px; letter-spacing: 0.16em; }
  .home .page { padding-bottom: 28px; }
  .contact { margin-top: 34px; font-size: 17px; }
  .contact a { position: relative; }
  .contact a::after { content: ""; position: absolute; inset: -13px -6px; }
}

/* Desktop composition: a poster scale opening. The wordmark and tagline sit
   centred at about 42 percent of the space above the panel's label, which shows
   at the bottom edge of the first screen; the lens rests between them. */
@media (min-width: 600px) {
  :root { --peek: 68px; }
  .hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-top: 0;
    /* Centring in the top 84 percent of the space above the peek puts the
       middle of the group at 42 percent of that space. */
    padding-bottom: calc(16vh + 0.84 * var(--peek));
    padding-bottom: calc(16svh + 0.84 * var(--peek));
  }
  .wordmark { font-size: clamp(72px, 13.5vw, 120px); }
  .tagline-group { margin-top: 26px; }
  .tagline { font-size: 28px; }
  .status { font-size: 13px; letter-spacing: 0.14em; }
  .home .page { padding-bottom: 44px; }
  .contact { margin-top: 48px; font-size: 16px; }
}

/* Shorter desktop screens: the group rises to 37 percent so the lens keeps
   room to rest between it and the panel. */
@media (min-width: 600px) and (max-height: 860px) {
  .hero {
    padding-bottom: calc(26vh + 0.74 * var(--peek));
    padding-bottom: calc(26svh + 0.74 * var(--peek));
  }
}

@media (min-width: 1024px) {
  .wordmark { font-size: clamp(120px, 10.5vw, 168px); }
  .tagline-group { margin-top: clamp(26px, 2.1vw, 34px); }
  .tagline { font-size: clamp(28px, 2.2vw, 34px); }
  .status { font-size: 14px; letter-spacing: 0.16em; }
}

/* ===== Email sign-up: self-contained block (markup in index.html, script in signup.js) ===== */
.signup {
  position: relative;
  margin: 0 auto;
  text-align: center;
  background-color: var(--panel-bottom);
  background-image: var(--grain), linear-gradient(160deg, var(--panel-top), var(--panel-bottom));
  border: 1px solid var(--frame);
  border-radius: 6px;
  box-shadow:
    inset 1px 1px 0 rgba(255, 234, 200, 0.07),
    inset -1px -1px 0 rgba(0, 0, 0, 0.45),
    0 1px 1px rgba(0, 0, 0, 0.6),
    5px 12px 22px -6px rgba(0, 0, 0, 0.6),
    12px 34px 70px -18px rgba(0, 0, 0, 0.75);
}

/* The inner rule of the double frame. */
.signup::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid var(--frame-inner);
  border-radius: 3px;
  pointer-events: none;
}

/* The lamp is at the upper left, as on the field: the brass frame catches it
   along its top and left edges and falls back to plain brass by the middle. */
.signup::after {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(135deg, rgba(255, 230, 186, 0.5), rgba(255, 230, 186, 0) 40%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* An engraved label: letterspaced capitals between two short brass rules. */
.signup-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin: 0 0 22px;
  padding-left: 0.3em;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent);
}

.signup-title::before,
.signup-title::after {
  content: "";
  flex: 0 0 40px;
  height: 1px;
  background: linear-gradient(90deg, rgba(200, 161, 101, 0), rgba(200, 161, 101, 0.75));
}

.signup-title::after {
  background: linear-gradient(90deg, rgba(200, 161, 101, 0.75), rgba(200, 161, 101, 0));
}

.signup-intro {
  margin: 0 auto;
  font-family: var(--serif);
  color: var(--ink-soft);
  text-wrap: balance;
}

.signup-form { margin: 0; }

.signup-label {
  display: block;
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.4;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* The email field and the button as one control: a dark slot holding a brass key. */
.signup-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
  padding: 8px;
  background-color: var(--slot);
  border: 1px solid var(--slot-edge);
  border-radius: 7px;
  box-shadow:
    inset 1px 2px 5px rgba(0, 0, 0, 0.7),
    1px 1px 0 rgba(255, 234, 200, 0.07);
  transition: border-color 600ms ease, box-shadow 600ms ease;
}

.signup-row:hover { border-color: var(--slot-edge-hover); }

.signup-row:has(.signup-input:focus-visible),
.signup-row:has(.signup-button:focus-visible) {
  border-color: var(--accent);
  box-shadow:
    inset 1px 2px 5px rgba(0, 0, 0, 0.7),
    0 0 0 1px var(--accent);
}

.signup-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 48px;
  padding: 0 12px;
  font: inherit;
  color: var(--ink);
  caret-color: var(--accent);
  /* An engraved baseline to write on. On focus a brass line draws out over it
     from the centre. */
  background-color: transparent;
  background-image:
    linear-gradient(var(--frame), var(--frame)),
    linear-gradient(var(--frame-inner), var(--frame-inner));
  background-size: 0 1px, calc(100% - 24px) 1px;
  background-position: center bottom 9px, center bottom 9px;
  background-repeat: no-repeat;
  border: 0;
  border-radius: 3px;
  transition: background-size 700ms ease;
}

.signup-input:focus {
  background-size: calc(100% - 24px) 1px, calc(100% - 24px) 1px;
}

/* The slot lights up instead; the transparent outline shows in forced colours. */
.signup-input:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

@supports not selector(:has(*)) {
  .signup-input:focus-visible { outline-color: var(--accent); }
}

.signup-button {
  flex: 0 0 auto;
  height: 48px;
  padding: 0 28px;
  font: inherit;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--on-accent);
  background-color: var(--accent);
  background-image: linear-gradient(to bottom right, #ddbd86 0%, #c9a266 50%, #b8925a 100%);
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  box-shadow:
    inset 1px 1px 0 rgba(255, 246, 226, 0.5),
    inset -1px -1px 0 rgba(90, 62, 26, 0.5),
    1px 1px 2px rgba(0, 0, 0, 0.6);
  transition: filter 500ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.signup-button:hover { filter: brightness(1.07); }

.signup-button:active {
  transform: translateY(1px);
  filter: brightness(0.96);
  box-shadow:
    inset 1px 2px 4px rgba(70, 46, 16, 0.55),
    inset -1px -1px 0 rgba(255, 240, 210, 0.15);
}

/* Keyboard focus: the slot takes the brass ring, the key an engraved inner line. */
.signup-button:focus-visible {
  outline: 2px solid var(--on-accent);
  outline-offset: -6px;
}

.signup-button[disabled] {
  cursor: wait;
  filter: saturate(0.6) brightness(0.85);
}

.signup-trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.signup-consent {
  margin: 16px auto 0;
  max-width: 30em;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-faint);
  text-wrap: balance;
}

.signup-consent a { color: var(--accent); }

.signup-status:empty { display: none; }

/* The message line, set off by a short brass rule, fading in slowly. */
.signup-status,
.signup-notice {
  position: relative;
  margin: 22px auto 0;
  padding-top: 18px;
  max-width: 24em;
  font-family: var(--serif);
  font-style: italic;
  line-height: 1.45;
  color: var(--ink);
  text-wrap: balance;
  animation: notice-in 900ms ease both;
}

.signup-status::before,
.signup-notice::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 48px;
  height: 1px;
  margin-left: -24px;
  background: var(--frame);
}

@keyframes notice-in { from { opacity: 0; } }

.signup-notice { display: none; scroll-margin-top: 40vh; }
.signup-notice:focus { outline: none; }
.signup-notice:target { display: block; }
.signup-status:not(:empty) ~ .signup-notice { display: none; }

/* Phone: a full width card. The field and the key stack as one tall control. */
@media (max-width: 599.98px) {
  .signup { padding: 36px 24px 34px; }
  .signup-intro { margin-bottom: 30px; font-size: 19px; line-height: 1.5; }
  .signup-row { flex-direction: column; }
  .signup-input { height: 50px; font-size: 17px; }
  .signup-button { height: 50px; font-size: 17px; }
  .signup-consent { margin-top: 18px; }
  .signup-consent a { position: relative; white-space: nowrap; }
  .signup-consent a::after { content: ""; position: absolute; inset: -14px -4px; }
  .signup-status,
  .signup-notice { font-size: 18px; }
}

/* Desktop: an instrument plate about 560 px wide, the key beside the field. */
@media (min-width: 600px) {
  .signup { max-width: 560px; padding: 40px 52px 40px; }
  .signup-intro { max-width: 22em; margin-bottom: 26px; font-size: 20px; line-height: 1.45; }
  .signup-input { font-size: 17px; }
  .signup-button { font-size: 16px; }
  .signup-status,
  .signup-notice { font-size: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .signup-button:active { transform: none; }
  .signup-input { transition: none; }
}
/* ===== End email sign-up ===== */

/* ===== Footer ===== */
.colophon {
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  font-size: 13px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  text-align: center;
}

/* Each sentence keeps to one line; a narrow screen breaks between them. */
.colophon-part { white-space: nowrap; }

/* Phone: stacked and centered, one sentence per line, the link under them. */
@media (max-width: 599.98px) {
  .colophon { margin-top: clamp(80px, 12svh, 120px); }
  .colophon-part { display: block; }
  .colophon-link { position: relative; display: inline-block; margin-top: 14px; }
  .colophon-link::after { content: ""; position: absolute; inset: -13px -6px; }
}

/* Desktop: one line, a small brass point before the link. */
@media (min-width: 600px) {
  .colophon {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    margin-top: clamp(112px, 20svh, 200px);
  }

  .colophon-line:not(:last-child)::after {
    content: "";
    display: inline-block;
    width: 3px;
    height: 3px;
    margin: 0 14px;
    border-radius: 50%;
    background: var(--frame);
    vertical-align: 0.3em;
  }
}

/* ===== Privacy and 404 pages ===== */
.masthead {
  padding: 40px 0 0;
  text-align: center;
}

/* A short brass rule under the wordmark. */
.masthead::after {
  content: "";
  display: block;
  width: 56px;
  height: 1px;
  margin: 22px auto 0;
  background: var(--frame);
}

a.wordmark,
.masthead .wordmark {
  font-size: 24px;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--ink);
}

a.wordmark:hover { color: var(--ink); }

.masthead .tm { font-size: 0.5em; }

.policy {
  max-width: 36em;
  margin: 0 auto;
  padding: 48px 0 0;
}

.policy h1,
.notfound h1 {
  margin: 0 0 28px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(32px, 7vw, 46px);
  line-height: 1.1;
  color: var(--ink);
  text-align: center;
}

.policy h2 {
  margin: 32px 0 8px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 22px;
  color: var(--ink);
}

.policy p { margin: 0 0 14px; color: var(--ink-soft); }
.policy .updated { margin-top: 28px; font-size: 14px; color: var(--ink-faint); }

.policy + .colophon { margin-top: 72px; }

/* Padding, not a footer margin, so the space stays inside the body's grain. */
body:not(.home) .page { padding-bottom: 44px; }

/* The 404 message sits in the middle of the space under the masthead. */
body:has(.notfound) .page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
}

.notfound {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 48px 0 12vh;
  padding-bottom: 12svh;
  text-align: center;
}

.notfound p { margin: 0; font-size: 19px; }

@media (min-width: 860px) {
  body { font-size: 18px; }
  .page { padding: 0 40px; }
}
