:root {
  --bg: #0e0e10;
  --fg: #f2efe9;
  --dim: #8b8780;
  --line: #26262a;
  --accent: #c8663c;
  --ok: #6f9e6f;
  --bad: #c4614f;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", sans-serif;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f4f1ea;
    --fg: #1a1917;
    --dim: #78736b;
    --line: #ddd6c8;
    --accent: #b4552d;
  }
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  line-height: 1.6;
  overflow-x: hidden;
}

a { color: var(--accent); }

/* ---------------------------------------------------------------- the clock */

.stage {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 6vh 5vw 4vh;
  text-align: center;
  position: relative;
}

.clock {
  margin: auto 0;
  width: 100%;
}

/* Preview watermark. Baked into the stage itself, not just the caption below
   it — a caption can scroll out of frame before a screenshot; a repeating
   diagonal stamp across the whole card can't be cropped out without also
   cropping out the message it's stamped on. */
.stage.is-preview::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image: repeating-linear-gradient(
    -35deg,
    transparent 0 90px,
    var(--line) 90px 91px,
    transparent 91px 180px
  );
}
.stage.is-preview::after {
  content: 'PREVIEW · NOT PURCHASED';
  position: absolute;
  top: 1.1rem;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 1;
  font-family: var(--sans);
  font-size: clamp(0.6rem, 1.4vw, 0.75rem);
  letter-spacing: 0.18em;
  color: var(--dim);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0.25rem 0.6rem;
}

.stamp {
  font-family: var(--sans);
  font-size: clamp(0.7rem, 1.6vw, 0.85rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 clamp(1.5rem, 5vh, 3rem);
}

.message {
  font-family: var(--serif);
  font-size: clamp(1.75rem, 6.5vw, 3.75rem);
  line-height: 1.22;
  letter-spacing: -0.015em;
  /* Measure in em so it tracks the display size rather than the body size —
     a ch/rem cap here silently produces two words a line at large viewports. */
  max-width: 12em;
  margin: 0 auto;
  text-wrap: balance;
  transition: opacity 480ms ease;
}

.message.swap { opacity: 0; }

.message.empty {
  color: var(--dim);
  font-style: italic;
  font-size: clamp(1.1rem, 3.2vw, 1.6rem);
}

.attribution {
  font-family: var(--serif);
  font-size: clamp(0.95rem, 2.2vw, 1.15rem);
  color: var(--dim);
  margin: 1.4rem 0 0;
  font-style: italic;
}

/* Deliberately smaller and quieter than .message — this must never be
   mistaken for the actual content of the minute on screen, which is what
   .message and .attribution report. Quotation marks plus this typographic
   distance are the signal that it's someone else's, from another minute. */
.examples { margin-top: 2.25rem; }

.examples-rotator {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1rem, 2.6vw, 1.3rem);
  color: var(--dim);
  max-width: 26em;
  margin: 0 auto;
  min-height: 1.4em; /* holds its place as text of different lengths rotates through */
  transition: opacity 480ms ease;
}
.examples-rotator.swap { opacity: 0; }

.examples-prompt {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--accent);
  margin: 0.9rem 0 0;
}

.stage-foot { margin-top: auto; }

@keyframes riseIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Separate end-opacity from riseIn — .explainer's resting state is 0.75, not
   1, and an animation's final keyframe overrides the element's own opacity
   declaration for as long as animation-fill-mode holds it. Reusing riseIn
   here would have left it stuck fully opaque instead of quiet. */
@keyframes riseInDim {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 0.75; transform: translateY(0); }
}

.tagline {
  font-family: var(--serif);
  font-style: italic;
  color: var(--dim);
  margin: 0 0 1rem;
  /* A beat after the clock's own content is already on screen — motion
     draws the eye down here far more reliably than static position does. */
  animation: riseIn 700ms ease-out both;
  animation-delay: 250ms;
}

/* Plain-language, deliberately quieter than the tagline above it — a second
   voice explaining rather than evoking, not competing for the same attention. */
.explainer {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--dim);
  opacity: 0.75;
  max-width: 26em;
  margin: 0 auto 1.25rem;
  /* Staggered behind the tagline — the two arriving in sequence reads as the
     page revealing itself, not everything dumped on screen at once. */
  animation: riseInDim 700ms ease-out both;
  animation-delay: 500ms;
}

@media (prefers-reduced-motion: reduce) {
  .tagline, .explainer { animation: none; }
}

/* Share controls — quiet by default. This sits under a memorial as often as
   not, so it must not read like a call to action. */
.share {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin: 0 0 1.5rem;
}

.share button {
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  width: auto;
  padding: 0.4rem 0.8rem;
  color: var(--dim);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}
.share button:hover:not(:disabled) { color: var(--fg); border-color: var(--dim); }
.share button:disabled { opacity: 0.4; cursor: wait; }

.share-status {
  font-size: 0.75rem;
  color: var(--dim);
  min-width: 8ch;
  text-align: left;
}

/* In-app-browser fallback: a real image to long-press, since the buttons
   below it don't work inside these WebViews. Full width, so the press target
   is generous rather than a thumbnail. */
.share-preview {
  display: block;
  width: 100%;
  max-width: 22rem;
  margin: 0 auto 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--line);
}

.share-hint {
  flex-basis: 100%;
  font-size: 0.78rem;
  color: var(--dim);
  text-align: center;
  margin: 0 0 0.6rem;
}

@keyframes gentleBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}

.scroll-cue {
  display: inline-block;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
  /* Fades in last, after the tagline and explainer have settled, then
     idles in a slow, small bounce — the one element on this screen whose
     job is ongoing (inviting scroll for as long as someone lingers here),
     not a one-time reveal like the text above it. */
  animation:
    riseIn 700ms ease-out 650ms both,
    gentleBounce 2s ease-in-out 900ms infinite;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-cue { animation: none; }
}

/* --------------------------------------------------------------- the panels */

/*
 * Horizontal padding is capped. At a flat 5vw the content box shrank as the
 * viewport grew — 467px at 768px wide, ~404px at 1400px — so headings wrapped
 * differently on every screen and appeared to change size.
 */
.panel {
  max-width: 34rem;
  margin: 0 auto;
  padding: clamp(3rem, 10vh, 6rem) clamp(1.25rem, 5vw, 2rem);
  border-top: 1px solid var(--line);
}

/*
 * At 2.1rem the second line of the h1 landed within a few pixels of the 34rem
 * panel, so it broke to three lines or two depending on which serif resolved —
 * reading as though the size kept changing. 2rem clears it reliably.
 */
h1 {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 4.5vw, 1.9rem);
  line-height: 1.25;
  font-weight: 400;
  margin: 0 0 1.25rem;
  text-wrap: balance;
}

/*
 * 1.15rem left section headings barely above body text and a long way below
 * the h1. 1.4rem gives them presence while staying clearly subordinate:
 * roughly 2 / 1.4 / 1 across h1, h2 and body.
 */
h2 {
  font-family: var(--serif);
  font-size: 1.4rem;
  font-weight: 400;
  margin: 2.75rem 0 0.6rem;
}

.lede { color: var(--dim); margin: 0 0 2.5rem; }
.prose p { color: var(--dim); margin: 0 0 1rem; }

/* Real examples, before the form asks for one of your own — proof of the
   concept in the words people actually used, not a count next to 525,600. */
.recent-claims { margin: 0 0 2.5rem; }
.recent-claims-label {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 0.9rem;
}
.recent-claims-list { list-style: none; margin: 0 0 0.9rem; padding: 0; }
.recent-claims-list li {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.4;
  color: var(--fg);
  margin: 0 0 0.9rem;
  padding-left: 1rem;
  border-left: 2px solid var(--line);
}
.recent-claims-list .when {
  display: block;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
  margin-top: 0.3rem;
}
.recent-claims-link { font-size: 0.85rem; }

/* ----------------------------------------------------------------- the form */

fieldset { border: 0; padding: 0; margin: 0 0 2rem; }

legend {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 0;
  margin-bottom: 0.75rem;
}

.hint { color: var(--dim); text-transform: none; letter-spacing: 0; font-size: 0.85em; }

/* The legend it sits in is deliberately quiet (dim, tiny) — right for a
   section label, wrong for the one fact that determines whether someone
   claims the right minute. Accent color and weight pull it out of that
   quietness without breaking out of the legend's line. */
.utc-note {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* A small text trigger, not a form-style button — it sits inline in a
   <legend>, and the default bordered/full-width button rule would look wrong
   here. Same visual language as .scroll-cue: underline, no fill. */
.tz-open {
  all: unset;
  cursor: pointer;
  margin-left: 0.6rem;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--dim);
  border-bottom: 1px solid var(--line);
  padding-bottom: 1px;
}
.tz-open:hover { color: var(--fg); border-color: var(--dim); }

.tz-modal {
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 1.5rem;
  width: min(24rem, 90vw);
  text-align: left;
}
.tz-modal::backdrop { background: rgba(0, 0, 0, 0.6); }

.tz-modal h2 {
  font-family: var(--serif);
  font-size: 1.3rem;
  margin: 0 0 0.75rem;
}

.tz-modal .hint { margin: 0 0 1.25rem; }

.tz-label {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 0.5rem;
}

.tz-zone-note {
  font-size: 0.72rem;
  color: var(--dim);
  margin: 0 0 1.1rem;
}

.tz-result {
  font-family: var(--serif);
  font-size: 1.2rem;
  color: var(--fg);
  margin: 0 0 0.4rem;
}

.tz-info {
  font-size: 0.78rem;
  color: var(--dim);
  margin: 0 0 1.25rem;
}

.tz-actions { display: flex; gap: 0.6rem; }

.tz-use {
  font-size: 0.8rem;
  width: auto;
  border-color: var(--accent);
  color: var(--accent);
}
.tz-use:disabled { opacity: 0.4; cursor: not-allowed; }

.tz-close {
  font-size: 0.8rem;
  width: auto;
}

.selects { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5rem; }

/* Real calendar dates, not the site's own year-agnostic minutes — three
   columns for date, not four, and a real Year select the main form has no
   reason to need. */
.tz-date-selects { grid-template-columns: 5fr 4fr 3fr; margin-bottom: 0.75rem; }
/* Hour and minute only ever need two digits; the zone name needs real room —
   "America/Argentina/Buenos Aires" doesn't fit in a column sized for "31". */
.tz-time-selects { grid-template-columns: 2fr 2fr 5fr; margin-bottom: 0.6rem; }

.selects label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

select, input, textarea, button {
  font: inherit;
  color: var(--fg);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0.6rem 0.65rem;
  width: 100%;
}

/*
 * iOS Safari zooms the whole viewport when a focused control has a font-size
 * under 16px, and does not zoom back out afterwards — so tapping the
 * attribution field left people stuck zoomed in through preview and beyond.
 *
 * These controls inherit from the small uppercase labels around them, which is
 * how they ended up at 11px. The labels stay small; the controls can't.
 *
 * max() rather than a flat 16px so a larger root size is still respected.
 * Checkboxes are excluded: they never trigger the zoom and font-size changes
 * how the box itself renders.
 */
select,
textarea,
input:not([type="checkbox"]) {
  font-size: max(16px, 1rem);
}

select { appearance: none; }
option { background: var(--bg); color: var(--fg); }

textarea {
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.4;
  resize: vertical;
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.meta-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.75rem;
  color: var(--dim);
  margin-top: 0.5rem;
}

.note { text-align: right; }

.inline {
  display: block;
  margin-top: 1.25rem;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}
.inline input { margin-top: 0.4rem; }

/* States the unconditional fact before the choice, so the checkbox can't be
   misread as controlling whether the message is public at all. */
.always-public {
  font-size: 0.85rem;
  color: var(--fg);
  margin: 0 0 1rem;
  padding-left: 0.85rem;
  border-left: 2px solid var(--accent);
}

.check {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  font-size: 0.85rem;
  color: var(--dim);
}
.check input { width: auto; margin-top: 0.35rem; flex: none; }
.check em { font-style: italic; color: var(--fg); }

.availability, .screen-result {
  font-size: 0.85rem;
  margin: 0.75rem 0 0;
  min-height: 1.4em;
}
.is-ok { color: var(--ok); }
.is-bad { color: var(--bad); }
.is-busy { color: var(--dim); }
/* Withheld, not sold — visually distinct from both "yours" and "gone". */
.is-held { color: var(--accent); }

/* Folded away by default. Most people don't have a code, and an empty field
   labelled "code" invites the feeling of missing a discount. */
.code-toggle { margin: 0 0 1.25rem; }
.code-toggle summary {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--dim);
  cursor: pointer;
  width: fit-content;
}
.code-toggle summary:hover { color: var(--fg); }
.code-toggle input { margin-top: 0.6rem; text-transform: uppercase; }
.code-toggle .hint { font-size: 0.75rem; margin: 0.4rem 0 0; }

.actions { display: flex; gap: 0.6rem; align-items: stretch; }
.actions button[type="submit"] { flex: 2; }

#preview {
  flex: 1;
  font-size: 0.85rem;
  color: var(--fg);
  background: transparent;
  border: 1px solid var(--line);
  cursor: pointer;
  padding: 0.85rem 0.6rem;
}
#preview:hover:not(:disabled) { border-color: var(--dim); }
#preview:disabled { opacity: 0.35; cursor: not-allowed; }

/* Marks the clock as showing something unbought, so a preview can never be
   mistaken for a claimed minute. */
.preview-note {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1rem;
}
.preview-note button {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  width: auto;
  padding: 0 0 0 0.5rem;
  border: 0;
  background: none;
  color: var(--dim);
  cursor: pointer;
  text-decoration: underline;
}

@media (max-width: 26rem) {
  .actions { flex-direction: column; }
}

button[type="submit"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.85rem;
  cursor: pointer;
}
button[type="submit"]:disabled { opacity: 0.35; cursor: not-allowed; }

.fineprint { font-size: 0.75rem; color: var(--dim); margin: 1rem 0 0; }

footer {
  border-top: 1px solid var(--line);
  padding: 2rem 5vw 3rem;
  text-align: center;
  font-size: 0.78rem;
  color: var(--dim);
}
footer a { color: var(--dim); }

.social {
  display: flex;
  justify-content: center;
  gap: 1.15rem;
  margin: 1.25rem 0 0;
}
.social a {
  /* 44x44 hit area around an 18px glyph — the iOS minimum. These sit close
     together at the bottom of a phone screen, so the target has to be bigger
     than the icon looks. Negative margin keeps the visual spacing tight. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: -0.6rem -0.55rem;
  color: var(--dim);
  transition: color 120ms ease;
}
.social a:hover { color: var(--fg); }
.social svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
  display: block;
}

@media (max-width: 30rem) {
  .selects { grid-template-columns: repeat(2, 1fr); }
  .meta-row { flex-direction: column; gap: 0.25rem; }
  .note { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  .message { transition: none; }
}
