/* ==========================================================================
   Nonstick® — one-page site.

   The design is a fixed-size flyer (mobile 398x874, desktop 849x675 for the
   logo + card pair). Everything below is authored at those native pixel
   sizes, exactly as in Figma; app.js scales the whole stage with a single
   transform so the page always fits the viewport and never scrolls.
   ========================================================================== */

:root {
  --ink:        #252414;
  --maroon:     #720200;
  --yellow:     #fcff45;
  --rust:       #a24615;
  --green:      #213f08;
  --offwhite:   #fffefc;
  --near-black: #141413;

  --sans:  "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "Times New Roman", Times, serif;
}

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

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #fff;
  -webkit-text-size-adjust: 100%;
}

body { font-family: var(--sans); color: var(--ink); }

p, h1, h2, ul { margin: 0; padding: 0; }

[hidden] { display: none !important; }
ul { list-style: none; }

/* --------------------------------------------------------------------------
   Scale-to-fit stage
   -------------------------------------------------------------------------- */

.viewport {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;   /* tracks mobile browser chrome */
  overflow: hidden;
}

.stage {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center center;
  transform: translate(-50%, -50%) scale(var(--scale, 1));
  display: flex;
  /* Hidden until app.js has measured, so there is no first-paint jump. */
  visibility: hidden;
}
.is-measured .stage { visibility: visible; }

/* Mobile: logo stacked above the card, 398x874. */
.is-mobile .stage {
  width: 398px;
  height: 874px;
  padding: 8px;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
}

/* Desktop: logo and card side by side, centred as a pair (849x675). */
.is-desktop .stage {
  width: 849px;
  height: 675px;
  flex-direction: row;
  align-items: center;
  gap: 107px;
}

/* --------------------------------------------------------------------------
   Logo lockup
   -------------------------------------------------------------------------- */

.logo-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.is-mobile .logo-block { flex: 1 0 0; min-height: 0; width: 100%; padding-top: 6px; }
.is-desktop .logo-block { flex: 0 0 360px; width: 360px; padding-top: 6px; }

.logo {
  display: block;
  width: 338.248px;
  height: 84.858px;
}

.logo-sub {
  font-weight: 700;
  font-size: 18px;
  line-height: 21px;
  text-align: center;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Card
   -------------------------------------------------------------------------- */

.card {
  flex: 0 0 auto;
  width: 382px;
  background: #fff;
  /* 1px stroke with 9px padding keeps the card at exactly 382x675:
     1 + 9 + 362 + 9 + 1 = 382. Dropping to 8px padding would shrink it. */
  border: 1px solid var(--ink);
  padding: 9px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
}

.block {
  width: 100%;
  padding: 8px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: hidden;
}

/* ---- Maroon contact block (140px) ---- */

.block--maroon {
  background: var(--maroon);
  border: 1px solid var(--maroon);
  gap: 4px;
  text-align: center;
  white-space: nowrap;
  color: #fff;
}

.addr__street,
.addr__city { display: block; }
.addr__street { font-weight: 700; font-size: 22px; line-height: 26px; }
.addr__city   { font-weight: 400; font-size: 18px; line-height: 21px; }

.contact { font-size: 18px; color: var(--offwhite); }
.contact .ln { display: block; line-height: 22px; }
.contact b { font-weight: 700; }
.contact a { color: #fff; font-weight: 700; text-decoration: none; }
.contact a.u { text-decoration: underline; text-underline-position: from-font; }

.tagline-yellow {
  font-family: var(--serif);
  font-weight: 700;
  font-style: italic;          /* technique and "7 Days A Week" both italic */
  font-size: 20px;
  line-height: 23px;
  letter-spacing: 0.6px;
  color: var(--yellow);
}
.tagline-yellow i { font-style: italic; }

/* ---- Outlined blocks: Services (196px) and Our Difference (162px) ---- */

.block--outline {
  background: #fff;
  border: 1px solid var(--maroon);
  gap: 2px;
}

.block__head {
  width: 331.333px;
  font-weight: 700;
  font-size: 18px;
  line-height: 22px;
  color: var(--rust);
  text-decoration: underline;
  text-underline-position: from-font;
}

.services { width: 331.333px; }
.services li {
  font-weight: 700;
  font-size: 18px;
  line-height: 22px;
  color: var(--ink);
  /* One row per service by design. nowrap also stops a scrambling row from
     wrapping and shoving the rest of the list out of a fixed-height block. */
  white-space: nowrap;
}
.services em {
  font-weight: 500;
  font-style: italic;
  font-size: 14px;
  /* Keeps the smaller inline box inside the 22px strut so rows stay on grid. */
  line-height: 1;
  color: var(--maroon);
}
.services em.upright { font-style: normal; }

.difference {
  width: 331.333px;
  font-weight: 700;
  font-size: 18px;
  line-height: 20px;
  color: var(--ink);
}

/* ---- Green consultation block (102px, fixed across all states) ---- */

.block--green {
  background: var(--green);
  border: 4px solid var(--green);
  height: 102px;
  padding: 8px 6px;
  justify-content: flex-start;
  color: #fff;
}

.consult__form,
.consult__done {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}
.consult__form { gap: 10px; }
.consult__done { gap: 6px; justify-content: center; height: 100%; }

.consult__head {
  font-weight: 400;
  font-size: 21px;
  line-height: 26px;
  text-align: center;
  white-space: nowrap;
}
.consult__head b {
  font-weight: 700;
  text-decoration: underline;
  text-underline-position: from-font;
}

.form {
  display: flex;
  gap: 10px;
  width: 100%;
  height: 42px;
}

.form__input {
  flex: 1 1 0;
  min-width: 0;
  height: 42px;
  padding: 10px;
  border: 0;
  border-radius: 0;
  background: #fff;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 18px;
  line-height: 22px;
  color: var(--green);
}
.form__input::placeholder { color: var(--green); opacity: 1; }
.form__input:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }

.form__submit {
  flex: 0 0 auto;
  height: 42px;
  padding: 10px;
  border: 0;
  border-radius: 0;
  background: rgba(255, 255, 255, 0.5);
  font-family: var(--sans);
  font-weight: 700;
  font-size: 18px;
  line-height: 22px;
  color: var(--green);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.form__submit:hover { background: rgba(255, 255, 255, 0.68); }
.form__submit:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }
.form__submit[disabled] { cursor: progress; }

/* Submitting: the round trip to Apps Script can take a second or two, and a
   dead button reads as a broken one. */
.form__submit.is-busy { animation: busy-pulse 1.1s ease-in-out infinite; }
@keyframes busy-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* Success / error state — same box, different contents. */
.done__head {
  font-weight: 700;
  font-size: 21px;
  line-height: 26px;
  text-align: center;
  text-decoration: underline;
  text-underline-position: from-font;
}
.done__body {
  font-weight: 400;
  font-size: 19px;
  line-height: 23px;
  text-align: center;
}
.done__body b { font-weight: 700; }
.done__body a { color: var(--yellow); }

/* ---- Foot tagline ---- */

.tagline-foot {
  width: 100%;
  font-family: var(--serif);
  font-weight: 700;
  font-size: 20px;
  line-height: 23px;
  text-align: center;
  color: var(--near-black);
  /* Capitalising "Free" pushes this to 362.8px in a 362px box. A hair of
     negative tracking pulls it back under; nowrap means a font substitution
     clips the tail rather than wrapping and growing the card by 23px. */
  white-space: nowrap;
  letter-spacing: -0.1px;
}

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Honeypot — off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --------------------------------------------------------------------------
   Intro
   -------------------------------------------------------------------------- */

/* The card and logo do not fade *up* — they are simply there, with the
   briefest settle. All the motion belongs to the letters. */
.stage { opacity: 0; }
.is-measured .stage { opacity: 1; transition: opacity 140ms linear; }

/* Streamed tokens. Every one is in the DOM from the first frame at opacity 0,
   so the layout is fully reserved before a single character is visible — the
   card can never shift, and no measure-and-pin is needed. */
.tok {
  opacity: 0;
  transition: opacity 130ms linear;
}
.tok.on { opacity: 1; }

/* Zero-width so it can sit between tokens without nudging anything. */
.caret {
  display: inline-block;
  position: relative;
  width: 0;
  vertical-align: baseline;
}
.caret::after {
  content: '';
  position: absolute;
  left: 1px;
  bottom: 0.02em;
  width: 2px;              /* a text caret, not a block cursor */
  height: 0.92em;
  background: currentColor;
  opacity: 0.9;
}

/* --------------------------------------------------------------------------
   Custom cursor — the 12-frame pizza, page-wide, pointer devices only
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  html.has-cursor,
  html.has-cursor * { cursor: none !important; }
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 32px;
  height: 32px;
  z-index: 2147483647;
  pointer-events: none;
  background-image: url("assets/cursor-pizza.png");
  background-repeat: no-repeat;
  background-size: 384px 32px;
  image-rendering: pixelated;      /* 32px art stays crisp-chunky on retina */
  will-change: transform;
  opacity: 0;
  transition: opacity 120ms linear;
  /* step-end + the .ani's own rate table: six slow frames, then it accelerates */
  animation: pizza-spin 1.633s step-end infinite;
}
.cursor.is-on { opacity: 1; }

@keyframes pizza-spin {
  0%      { background-position:    0 0; }
  10.204% { background-position: -32px 0; }
  20.408% { background-position: -64px 0; }
  30.612% { background-position: -96px 0; }
  40.816% { background-position: -128px 0; }
  51.020% { background-position: -160px 0; }
  61.224% { background-position: -192px 0; }
  70.408% { background-position: -224px 0; }
  78.571% { background-position: -256px 0; }
  84.694% { background-position: -288px 0; }
  89.796% { background-position: -320px 0; }
  94.898% { background-position: -352px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .cursor { animation: none; background-position: 0 0; }
  .is-measured .stage { transition: none; }
  .tok { opacity: 1; transition: none; }
  .caret { display: none; }
  .form__submit.is-busy { animation: none; opacity: 0.7; }
}
