/*
 * The wall.
 *
 * Everything here floats over a full-bleed canvas, so the rules are narrow: nothing
 * gets a box, nothing gets a shadow, and the only backgrounds are the two scrims
 * that keep the type readable where it sits over rock. The interface is meant to be
 * noticed once and then forgotten - the wall is the page.
 */

:root {
  /* Limestone. The canvas paints its own, warmer version of this; the value here is
     only so the page never flashes white before the first frame. */
  --stone: #e7dfce;
  --ink: #2b2620;
  --muted: #74695b;
  --hair: rgba(43, 38, 32, 0.16);
  --ochre: #c26a2d;
  --charcoal: #2c2521;
  --bone: #f7f2e6;

  /*
   * Two voices, both already on the machine. The serif carries the record - dates,
   * the countdown, the one line of prose. The sans carries the tools.
   */
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
    "URW Palladio L", Charter, "Bitstream Charter", "Source Serif Pro", Georgia,
    "Times New Roman", serif;

  font-family: Inter, "Inter Variable", system-ui, -apple-system, "Segoe UI Variable Text",
    "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  color-scheme: light;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--stone);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

body { line-height: 1.5; letter-spacing: -0.008em; }

a { color: inherit; }

#rock {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: crosshair;
}

body.panning #rock { cursor: grabbing; }
body.dark-rock #rock { cursor: not-allowed; }

/* ---------- the two rails ---------- */

.rail {
  position: fixed;
  left: 0;
  right: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 22px max(26px, env(safe-area-inset-left)) 22px max(26px, env(safe-area-inset-right));
  pointer-events: none;
  z-index: 2;
}

.rail > * { pointer-events: auto; }

/*
 * The scrim. A gradient of the stone itself rather than of black: the wall is a
 * light surface, and darkening it to hold type would read as a bar across the rock.
 */
.rail::before {
  content: "";
  position: absolute;
  inset: -1px 0;
  z-index: -1;
  pointer-events: none;
}

.rail-top { top: 0; }
.rail-top::before {
  background: linear-gradient(to bottom, rgba(240, 233, 219, 0.86), rgba(240, 233, 219, 0.5) 46%, rgba(240, 233, 219, 0));
  bottom: -64px;
}

.rail-bottom {
  bottom: 0;
  align-items: flex-end;
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
.rail-bottom::before {
  background: linear-gradient(to top, rgba(240, 233, 219, 0.9), rgba(240, 233, 219, 0.5) 46%, rgba(240, 233, 219, 0));
  top: -76px;
}

/* ---------- who and when ---------- */

.mark h1 {
  margin: 0;
  font-size: 16px;
  font-weight: 560;
  letter-spacing: -0.03em;
}

.mark h1 a { text-decoration: none; }

.line {
  margin: 3px 0 0;
  font-family: var(--serif);
  font-size: 15px;
  letter-spacing: 0;
  color: var(--muted);
  max-width: 34ch;
}

.when {
  text-align: right;
  font-family: var(--serif);
  letter-spacing: 0;
}

.day {
  margin: 0;
  font-size: 15px;
  white-space: nowrap;
}

.dries {
  margin: 2px 0 0;
  font-size: 14px;
  color: var(--muted);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: baseline;
  white-space: nowrap;
}

.digits { font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }

/* A sealed day has no clock. It has a fact. */
.when.sealed .digits { display: none; }

/* ---------- pigments and nib ---------- */

/*
 * Both tools live at the left end together. The middle of the rail is left empty
 * on purpose: it is where the legal links sit, and they are the one thing on this
 * page nobody should have to hunt for.
 */
.tools {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.pigments {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-wrap: wrap;
}

.pigment {
  appearance: none;
  border: 0;
  padding: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--dab);
  cursor: pointer;
  position: relative;
  transition: transform 140ms ease;
}

.pigment::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--ink);
  opacity: 0;
  transition: opacity 140ms ease;
}

.pigment[aria-checked="true"] { transform: scale(1.06); }
.pigment[aria-checked="true"]::after { opacity: 0.55; }
.pigment:hover { transform: scale(1.1); }

/* Unground. Present, named, and plainly not yours yet. */
.pigment.locked {
  background:
    radial-gradient(circle at 50% 50%, var(--dab) 0 41%, transparent 42%),
    transparent;
  box-shadow: inset 0 0 0 1px var(--hair);
  opacity: 0.75;
}
.pigment.locked:hover { opacity: 1; }

/* The gap between what anyone can find and what had to be carried here. */
.divider {
  width: 1px;
  height: 18px;
  background: var(--hair);
  margin: 0 3px;
}

/*
 * Looking at a day that has dried. The tools are still there - the wall is one
 * surface and you are one step from today - but they are plainly not for this day.
 */
body.reading .tools, body.reading .breath { opacity: 0.34; }
.tools, .breath { transition: opacity 300ms ease; }

/* ---------- nib ---------- */

.nibs { display: flex; align-items: center; gap: 12px; }

.nib {
  appearance: none;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  opacity: 0.4;
  transition: opacity 140ms ease;
}

.nib span {
  display: block;
  border-radius: 50%;
  background: currentColor;
  width: var(--dot);
  height: var(--dot);
}

.nib[aria-checked="true"], .nib:hover { opacity: 1; }

/* ---------- taking one back ---------- */

/*
 * Not an icon. The wall has one undo, it lasts a minute, and a word says both of
 * those better than a curved arrow does.
 */
.wipe {
  appearance: none;
  border: 0;
  background: none;
  padding: 2px 0;
  font-family: var(--serif);
  font-size: 14px;
  letter-spacing: 0;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 1px solid var(--hair);
}

.wipe:hover { color: var(--ink); border-bottom-color: var(--ink); }

@media (max-width: 720px) {
  /* The only way back on a machine with no keyboard, so it gets a real target. */
  .wipe { font-size: 15px; padding: 8px 0; margin-left: auto; }
}

/* ---------- breath ---------- */

.breath { text-align: right; }

.lungs {
  display: flex;
  gap: 2px;
  justify-content: flex-end;
  height: 12px;
  align-items: flex-end;
}

.lungs i {
  display: block;
  width: 3px;
  height: 12px;
  border-radius: 1px;
  background: var(--ink);
  opacity: 0.72;
}

.lungs i.spent { opacity: 0.14; height: 6px; }

.breath-note {
  margin: 6px 0 0;
  font-family: var(--serif);
  font-size: 13px;
  color: var(--muted);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- moving along ---------- */

.steps {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.step {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  appearance: none;
  border: 0;
  background: none;
  font-family: var(--serif);
  font-size: 14px;
  color: var(--muted);
  cursor: pointer;
  pointer-events: auto;
  padding: 14px 18px;
  opacity: 0;
  transition: opacity 260ms ease;
  white-space: nowrap;
}

.step-back { left: max(6px, env(safe-area-inset-left)); }
.step-now { right: max(6px, env(safe-area-inset-right)); }

body:hover .step, .step:focus-visible { opacity: 0.7; }
.step:hover { opacity: 1; }

/* ---------- the things the wall says ---------- */

/* Said once, to somebody who has never been here. */
.first {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  z-index: 3;
  font-family: var(--serif);
  font-size: clamp(19px, 3.4vw, 28px);
  letter-spacing: -0.01em;
  color: var(--ink);
  text-align: center;
  max-width: 22ch;
  pointer-events: none;
  /* It lands wherever the wall happens to be, which may be on top of somebody's
     drawing. A halo of the stone rather than a box: the sentence has to be legible
     without putting a card over the thing it is asking you to look at. */
  text-shadow: 0 0 26px rgba(240, 233, 219, 0.98), 0 0 10px rgba(240, 233, 219, 0.98),
    0 0 4px rgba(240, 233, 219, 0.9);
  animation: breathe 5.5s ease forwards;
}

@keyframes breathe {
  0% { opacity: 0; transform: translate(-50%, calc(-50% + 8px)); }
  16% { opacity: 1; transform: translate(-50%, -50%); }
  74% { opacity: 1; }
  100% { opacity: 0; }
}

/* Anything else the wall has to say. Quiet, brief, over the rock. */
.say {
  position: fixed;
  left: 50%;
  bottom: 108px;
  transform: translateX(-50%);
  margin: 0;
  z-index: 3;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--ink);
  background: rgba(238, 231, 216, 0.88);
  padding: 7px 15px;
  border-radius: 999px;
  pointer-events: none;
  white-space: nowrap;
  animation: settle 200ms ease;
}

@keyframes settle { from { opacity: 0; transform: translate(-50%, 6px); } }

.foot {
  position: fixed;
  left: max(26px, env(safe-area-inset-left));
  bottom: max(20px, env(safe-area-inset-bottom));
  margin: 0;
  z-index: 1;
  display: none;
  gap: 16px;
  font-size: 12px;
  color: var(--muted);
}

.foot a { text-decoration: none; opacity: 0.75; }
.foot a:hover { opacity: 1; text-decoration: underline; }

/* ---------- grinding a pigment ---------- */

.sheet {
  border: 0;
  border-radius: 3px;
  padding: 30px 30px 24px;
  width: min(420px, calc(100vw - 32px));
  background: var(--bone);
  color: var(--ink);
  box-shadow: 0 30px 80px rgba(35, 28, 20, 0.28);
}

.sheet::backdrop { background: rgba(52, 44, 34, 0.4); }

.grind-swatch {
  display: block;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--dab, var(--charcoal));
  margin-bottom: 16px;
}

.sheet h2 {
  margin: 0;
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -0.015em;
}

.grind-note {
  margin: 8px 0 18px;
  font-family: var(--serif);
  font-size: 16px;
  color: var(--muted);
}

.fineprint {
  margin: 0 0 12px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}

.fineprint strong { color: var(--ink); font-weight: 560; }

.consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
  margin: 4px 0 6px;
}

.consent input { margin-top: 2px; accent-color: var(--charcoal); }

.error {
  margin: 6px 0 0;
  font-size: 13px;
  color: #a8331a;
}

.sheet menu {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin: 18px 0 0;
  padding: 0;
}

.sheet button {
  font: inherit;
  font-size: 14px;
  padding: 9px 16px;
  border-radius: 2px;
  cursor: pointer;
  border: 1px solid transparent;
}

.ghost { background: none; border-color: var(--hair); color: var(--muted); }
.ghost:hover { color: var(--ink); border-color: var(--ink); }

.accent { background: var(--charcoal); color: var(--bone); }
.accent:hover { background: #1c1714; }
.accent[disabled] { opacity: 0.45; cursor: default; }

/* ---------- narrow ---------- */

@media (max-width: 720px) {
  .rail { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
  .line { display: none; }
  .rail-bottom { flex-wrap: wrap; gap: 12px; align-items: center; }
  .tools { order: 2; width: 100%; justify-content: flex-start; gap: 12px; }
  .tools > .divider { display: none; }
  .pigments { gap: 9px; }
  .breath { order: 1; margin-left: auto; }
  .lungs { display: none; }
  .step { opacity: 0.5; font-size: 22px; padding: 22px 16px; }
}

@media (min-width: 1100px) {
  .foot { display: flex; left: 50%; transform: translateX(-50%); bottom: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .first { animation-duration: 9s; }
  .say { animation: none; }
}
