/* ============================================================================
   Faceward — reservation page

   Design notes, so the next person does not have to guess:

   PALETTE. Warm neutrals, one accent. The accent is a deep plum — the colour of
   document ink, the thing you sign permission with. It is deliberately not the
   terracotta that every warm-cream page currently reaches for, and it is
   deliberately not a blue (institutional) or a green (a tick, which would be
   claiming an approval this page cannot give).

   TYPE. System serifs and system sans, no webfont. Not a compromise: the brief
   asks for fast loading on a bad phone connection and no third-party requests,
   and a page about privacy should not open a connection to a font CDN. The
   personality is carried by the treatment — size, leading, measure, where the
   lines break — rather than by an exotic face. See README for the upgrade path
   if a licensed face is ever self-hosted.

   NO PHOTOGRAPH. This is a page about somebody's face. A stock face on it would
   be wrong in an obvious way, and an illustrated one would be twee. The paper
   and the type do the work, and the empty space is the statement.

   MOTION. One moment, once: the mark under "permission" draws itself, slowly,
   like a signature being made. Nothing else moves. Under reduced-motion it is
   simply already there.
   ============================================================================ */

/* The hidden attribute has to win, and without !important it does not.
   `.reserve` gets `display: grid` in the wide-viewport media query below,
   and any author-origin display beats the user-agent stylesheet's
   `[hidden] { display: none }`. The result was that after a successful
   signup `form.hidden = true` did nothing on desktop: the confirmation
   appeared and the form stayed under it with a disabled 'Reserving...'
   button, so a page that had worked looked like a page that had hung.

   Mobile was fine, because the base .reserve rule sets no display at all.
   That is exactly why it survived review -- the failure needed a viewport
   wide enough to trigger the media query. */
[hidden] {
  display: none !important;
}

:root {
  --paper: #fbf8f3;
  --sand: #efe8dc;
  --ink: #26221e;
  --ink-soft: #6e655b;
  --mark: #5c3d57;

  --measure: 34rem;
  --gutter: clamp(1.5rem, 6vw, 3rem);

  --serif: "Iowan Old Style", "Charter", "Palatino Linotype", Constantia, Cambria,
    Georgia, "Times New Roman", serif;
  --sans:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  /* Large by default. This is read on phones by people who are not squinting at
     a spec sheet. */
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

main {
  display: block;
}

/* ---------------------------------------------------------------------------
   Hero
   --------------------------------------------------------------------------- */

.hero {
  padding: clamp(3rem, 12vw, 7rem) var(--gutter) clamp(2.5rem, 8vw, 3.5rem);
  max-width: calc(var(--measure) + var(--gutter) * 2);
  margin: 0 auto;
}

.wordmark {
  margin: 0 0 clamp(2.5rem, 9vw, 4.5rem);
  font-family: var(--serif);
  font-size: 1.0625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.headline {
  margin: 0;
  font-family: var(--serif);
  /* Tight leading against very open spacing elsewhere: the headline should feel
     like one held breath, not a paragraph. */
  /* The size is governed by the line break, not by taste. "Your permission"
     costs about 6.99px of width for every 1px of font-size, so the largest
     size that keeps the intended two lines is (available width / 6.99).
     Measured on the live page: 47px at a 375px phone, 77px inside the 544px
     body measure. Both ends of the original clamp sat exactly on that limit.

     So growing the headline means giving it a wider measure than the body
     copy -- which is ordinary for display type -- rather than a bigger number.
     max-content lets it size to its longest line and extend past the hero's
     box to the RIGHT only, so its left edge stays aligned with the subhead,
     the form and every section below. max-width keeps it inside the viewport,
     so on an awkward in-between width it wraps rather than causing the page
     to scroll sideways.

     The phone floor stays at 2.75rem deliberately: a phone has no spare width
     to give, so anything larger there buys a third line instead of a bigger
     headline. */
  font-size: clamp(2.75rem, 11.5vw, 6rem);
  width: max-content;
  max-width: calc(100vw - var(--gutter) * 2);
  line-height: 1.04;
  letter-spacing: -0.021em;
  font-weight: 400;
}

/* The signature: a stroke under "permission", drawn rather than ruled. */
.marked {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}

.mark {
  position: absolute;
  left: 0;
  right: -0.06em;
  bottom: -0.16em;
  width: 100%;
  height: 0.22em;
  color: var(--mark);
  overflow: visible;
}

.mark path {
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  animation: draw 1400ms cubic-bezier(0.22, 0.61, 0.36, 1) 500ms forwards;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

.subhead {
  margin: clamp(1.75rem, 6vw, 2.5rem) 0 0;
  max-width: 30rem;
  font-size: clamp(1.125rem, 4.4vw, 1.3125rem);
  line-height: 1.6;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   The reservation. One field, one button.
   --------------------------------------------------------------------------- */

.reserve {
  margin: clamp(2.5rem, 8vw, 3.5rem) 0 0;
}

.field {
  display: block;
}

.field label {
  display: block;
  margin-bottom: 0.6rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

.field input {
  display: block;
  width: 100%;
  padding: 0.95rem 1rem;
  font: inherit;
  font-size: 1.0625rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid #ded4c6;
  border-radius: 4px;
  transition: border-color 140ms ease;
}

.field input::placeholder {
  color: #a89d90;
}

.field input:hover {
  border-color: #c9bcaa;
}

/* The accent's second and last appearance: the field you are being asked to
   sign. Two pixels of the same ink as the mark. */
.field input:focus-visible {
  outline: none;
  border-color: var(--mark);
  box-shadow: 0 0 0 3px rgba(92, 61, 87, 0.16);
}

.button {
  display: block;
  width: 100%;
  margin-top: 0.9rem;
  padding: 1rem 1.5rem;
  font: inherit;
  font-size: 1.0625rem;
  font-weight: 600;
  color: #fff;
  background: var(--mark);
  border: 1px solid var(--mark);
  border-radius: 4px;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    transform 140ms ease;
}

.button:hover {
  background: #4d3349;
}

.button:focus-visible {
  outline: 3px solid var(--mark);
  outline-offset: 3px;
}

.button:active {
  transform: translateY(1px);
}

.button[disabled] {
  opacity: 0.55;
  cursor: default;
  transform: none;
}

.fineprint {
  margin: 1.1rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* The count sits quietly on its own line. It is a fact, not a scoreboard. */
.count {
  display: block;
}

.count[data-state="loading"] {
  opacity: 0.45;
}

/* The honeypot. Off-screen rather than display:none — more bots fill it in, and
   it stays out of the keyboard order and out of the accessibility tree. */
.nope {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.status {
  margin: 1.5rem 0 0;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  min-height: 1.65em;
}

.status[data-tone="error"] {
  color: #8c2f2f;
}

.status:empty {
  margin: 0;
  min-height: 0;
}

/* ---------------------------------------------------------------------------
   How it works
   --------------------------------------------------------------------------- */

.how {
  padding: 0 var(--gutter) clamp(3.5rem, 11vw, 5rem);
  max-width: calc(var(--measure) + var(--gutter) * 2);
  margin: 0 auto;
}

/* Inset so the rule sits over the text measure rather than edge to edge — the
   same hairline the steps use, doing the same job one level up. */
.how::before {
  content: "";
  display: block;
  height: 1px;
  background: #e4dbcd;
  margin-bottom: clamp(2.75rem, 9vw, 4rem);
}

.how h2 {
  margin: 0 0 clamp(2rem, 7vw, 3rem);
  font-family: var(--serif);
  font-size: clamp(1.5rem, 6vw, 2rem);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.012em;
}

.steps {
  margin: 0;
  padding: 0;
  list-style: none;
}

.steps li {
  padding: 0 0 clamp(1.75rem, 6vw, 2.25rem);
  margin: 0 0 clamp(1.75rem, 6vw, 2.25rem);
  border-bottom: 1px solid #e4dbcd;
}

.steps li:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

/* First / Then / Whenever you want — not 01 / 02 / 03. The third is not a step
   you take once, and a number would hide the most reassuring thing here. */
.when {
  margin: 0 0 0.5rem;
  font-family: var(--serif);
  font-size: 1rem;
  font-style: italic;
  color: var(--mark);
}

.what {
  margin: 0;
  font-size: clamp(1.0625rem, 4vw, 1.1875rem);
  line-height: 1.62;
}

/* ---------------------------------------------------------------------------
   Closing + footer
   --------------------------------------------------------------------------- */

.closing {
  padding: 0 var(--gutter) clamp(3rem, 9vw, 4.5rem);
  max-width: calc(var(--measure) + var(--gutter) * 2);
  margin: 0 auto;
}

.closing p {
  margin: 0;
  padding-top: clamp(2rem, 7vw, 2.5rem);
  border-top: 1px solid #e4dbcd;
  font-size: 1rem;
  color: var(--ink-soft);
}

footer {
  padding: clamp(2rem, 7vw, 2.75rem) var(--gutter) clamp(2.5rem, 8vw, 3.5rem);
  background: var(--sand);
}

footer p {
  max-width: 44rem;
  margin: 0 auto;
  font-size: 0.875rem;
  line-height: 1.75;
  color: var(--ink-soft);
}

a {
  color: var(--mark);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

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

/* ---------------------------------------------------------------------------
   Privacy page. Same tokens, prose measure, no separate stylesheet.
   --------------------------------------------------------------------------- */

.prose {
  padding: clamp(3rem, 10vw, 5rem) var(--gutter) clamp(3rem, 9vw, 4.5rem);
  max-width: calc(var(--measure) + var(--gutter) * 2);
  margin: 0 auto;
}

.prose h1 {
  margin: 0 0 1.75rem;
  font-family: var(--serif);
  font-size: clamp(2rem, 8vw, 2.75rem);
  line-height: 1.15;
  font-weight: 400;
  letter-spacing: -0.018em;
}

.prose h2 {
  margin: 2.5rem 0 0.75rem;
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
}

.prose p {
  margin: 0 0 1.1rem;
  max-width: var(--measure);
}

.prose .back {
  display: inline-block;
  margin-top: 2.5rem;
  font-size: 0.9375rem;
}

/* ---------------------------------------------------------------------------
   Wider screens.

   Deliberately restrained: the measure stays narrow and the page stays a single
   column. A 1440px screen gets more air, not more columns — the content is one
   short argument and splitting it would only make it look like a brochure.
   --------------------------------------------------------------------------- */

@media (min-width: 46rem) {
  body {
    font-size: 1.125rem;
  }

  .reserve {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "field button"
      "fine  fine";
    gap: 0 0.75rem;
    align-items: end;
  }

  .field {
    grid-area: field;
  }

  .button {
    grid-area: button;
    width: auto;
    margin-top: 0;
    white-space: nowrap;
  }

  .fineprint {
    grid-area: fine;
  }

  .count {
    display: inline;
  }

  .count::before {
    content: " · ";
  }
}

/* ---------------------------------------------------------------------------
   Reduced motion: the mark is simply already drawn.
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .mark path {
    animation: none;
    stroke-dashoffset: 0;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* Printed, this should still read as a document rather than a screenshot. */
@media print {
  .reserve,
  footer {
    display: none;
  }

  body {
    background: #fff;
  }
}
