/* Mobile-first: this is used outdoors, at night, on a phone, one-handed.
   Hence the dark palette (preserves dark adaptation), the large tap targets,
   and type that stays legible at arm's length on a tripod. */
:root {
  --bg: #0b0d12;
  --panel: #141821;
  --panel-2: #1b2130;
  --ink: #e8ecf4;
  --muted: #9aa5b8;
  --line: #2a3242;
  --good: #5fd38d;
  --warn: #e8c468;
  --bad: #f0806a;
  --accent: #7aa7ff;
  --radius: 12px;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}
.wrap {
  max-width: 44rem; margin: 0 auto;
  /* Bottom padding clears the iPhone home indicator and Safari's floating
     address bar; the side insets matter in landscape on a notched phone. */
  padding: 1rem calc(1rem + env(safe-area-inset-left))
           calc(4rem + env(safe-area-inset-bottom))
           calc(1rem + env(safe-area-inset-right));
}
header.site { padding: 1.25rem 0 0.5rem; }
header.site h1 { font-size: 1.35rem; margin: 0 0 0.25rem; letter-spacing: -0.01em; }
header.site p { margin: 0; color: var(--muted); font-size: 0.95rem; }

nav.steps {
  display: flex; gap: 0.4rem; flex-wrap: wrap;
  margin: 1rem 0 1.25rem; padding: 0; list-style: none;
  font-size: 0.82rem;
}
nav.steps a {
  display: block; padding: 0.35rem 0.7rem; border-radius: 999px;
  background: var(--panel); color: var(--muted); text-decoration: none;
  border: 1px solid var(--line);
}
nav.steps a[aria-current="page"] { background: var(--accent); color: #0b0d12; border-color: transparent; font-weight: 600; }

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.1rem; margin: 0 0 1rem;
}
.card h2 { font-size: 1.05rem; margin: 0 0 0.6rem; }
.card h3 { font-size: 0.95rem; margin: 1rem 0 0.4rem; color: var(--ink); }
.card p, .card li { color: var(--muted); }
.card p:last-child { margin-bottom: 0; }
.card.good { border-left: 3px solid var(--good); }
.card.warn { border-left: 3px solid var(--warn); }
.card.bad  { border-left: 3px solid var(--bad); }

h2 .tag, .tag {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
  padding: 0.15rem 0.45rem; border-radius: 4px; background: var(--panel-2);
  color: var(--muted); vertical-align: middle; margin-left: 0.4rem;
}
.tag.good { background: rgba(95,211,141,0.15); color: var(--good); }
.tag.warn { background: rgba(232,196,104,0.15); color: var(--warn); }
.tag.bad  { background: rgba(240,128,106,0.15); color: var(--bad); }

label { display: block; font-size: 0.85rem; color: var(--muted); margin: 0.75rem 0 0.25rem; }

/* An unstyled checkbox renders at about 13px on iOS -- a quarter of Apple's
   own 44pt minimum, and the smallest thing on a page that otherwise claims
   large tap targets. This one gates the whole study, is tapped once, outdoors,
   in the dark, by someone holding a tripod. `flex: none` matters: inside the
   flex label below it would otherwise be shrunk by the text beside it. */
input[type=checkbox] {
  flex: none;
  width: 1.4rem; height: 1.4rem; margin: 0;
  accent-color: var(--accent);
}

/* A tick and its text. The whole row is the tap target, not just the box. */
label.check {
  display: flex; gap: 0.7rem; align-items: flex-start;
  margin: 0 0 0.25rem; padding: 0.5rem 0; min-height: 2.75rem;
  cursor: pointer; font-size: 0.85rem; color: var(--ink);
}
input[type=text], input[type=email], input[type=number], input[type=datetime-local], select, textarea {
  width: 100%; padding: 0.7rem 0.75rem; font-size: 1rem;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px;
}
/* 16px exactly: iOS Safari zooms the page when a focused control's text is
   smaller, and the zoom does not come back on blur. */
input[type=file] { width: 100%; padding: 0.75rem 0; color: var(--muted); font-size: 1rem; }
button {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  width: 100%; min-height: 3rem; margin-top: 1rem;
  font-size: 1rem; font-weight: 600; font-family: inherit;
  background: var(--accent); color: #0b0d12;
  border: 0; border-radius: 10px; cursor: pointer;
}
button.secondary { background: var(--panel-2); color: var(--ink); border: 1px solid var(--line); }
button[disabled] { opacity: 0.5; cursor: default; }
a { color: var(--accent); }

.row { display: flex; gap: 0.6rem; }
.row > * { flex: 1; min-width: 0; }

table.metrics { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
table.metrics td { padding: 0.4rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }
table.metrics td:first-child { color: var(--muted); }
table.metrics td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
table.metrics tr:last-child td { border-bottom: 0; }

.bars { font-variant-numeric: tabular-nums; font-size: 0.78rem; line-height: 1.5; }
.bars .r { display: flex; align-items: center; gap: 0.4rem; }
/* "Mon 26" does not fit in 3.2rem, so every other row wrapped its label onto
   two lines. Fixed basis, no shrink, no wrap. */
.bars .t { flex: 0 0 3.9rem; color: var(--muted); white-space: nowrap; }
/* The bar's own width is a percentage of its track, not of the row -- without
   this wrapper a 90% bar left no room for the value and pushed it onto the
   next line, which is what made the chart look broken on a phone. */
.bars .bw { flex: 1 1 auto; min-width: 0; }
.bars .b { display: block; height: 0.6rem; border-radius: 3px; background: var(--panel-2); min-width: 1px; }
.bars .b.go { background: var(--good); }
.bars .b.marginal { background: var(--warn); }
.bars .b.no { background: var(--line); }
.bars .v { flex: 0 0 auto; color: var(--muted); white-space: nowrap; }

/* Narrow phones cannot hold label, bar and value on one line once the value
   carries a time or a reason. Give the value its own line rather than letting
   it wrap mid-phrase. */
@media (max-width: 430px) {
  .bars .r { flex-wrap: wrap; row-gap: 0; }
  .bars .v { flex: 1 0 100%; padding-left: 4.3rem; }
}

.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.spin { display: inline-block; width: 1rem; height: 1rem; border: 2px solid rgba(0,0,0,0.25);
        border-top-color: #0b0d12; border-radius: 50%; animation: s 0.8s linear infinite; }
/* The spinner is dark-on-light for the accent button. On a .secondary button
   -- which is what "Use my device location" is -- that made it invisible, so
   the button looked dead during the 30 s a GPS fix can take. */
button.secondary .spin { border-color: rgba(232,236,244,0.25); border-top-color: var(--ink); }
@keyframes s { to { transform: rotate(360deg); } }
/* Injected into every page by the server. Deployment here is rsync onto a
   box, so this is the only way to tell from the phone whether what you are
   looking at is what you just pushed -- and a stale cached module is exactly
   the failure that looks like a broken feature. */
.build {
  font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted); opacity: 0.65; text-align: right;
  padding: 0.35rem 1rem 0; letter-spacing: 0.02em;
}

/* Feedback from a control, sitting directly under it. Muted grey small text
   was not enough: a geolocation refusal arrives in milliseconds, so there is
   no spinner to notice and the words are the only evidence anything happened.
   They have to look like something. */
.note {
  margin: 0.5rem 0 0; padding: 0.6rem 0.75rem; border-radius: 8px;
  font-size: 0.85rem; line-height: 1.5;
  background: var(--panel-2); color: var(--ink);
  border-left: 3px solid var(--line);
}
.note.bad  { border-left-color: var(--bad); }
.note.good { border-left-color: var(--good); }

.hidden { display: none !important; }
code { background: var(--panel-2); padding: 0.1rem 0.3rem; border-radius: 4px; font-size: 0.88em; }
ul.tight { padding-left: 1.1rem; margin: 0.4rem 0; }
ul.tight li { margin: 0.3rem 0; }
footer.site { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--line); }

/* The worked example on the guide page. Two panels side by side on a desktop,
   stacked on a phone -- they are 4:3 each, so side-by-side below about 700 px
   makes both unreadable. */
figure.example { margin: 1.25rem 0; padding: 0; }
figure.example .shots { display: grid; gap: 0.9rem; grid-template-columns: 1fr; }
@media (min-width: 700px) {
  figure.example .shots { grid-template-columns: 1fr 1fr; }
}
figure.example img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--line); border-radius: 8px; background: #000;
}
figure.example figcaption {
  margin-top: 0.4rem; font-size: 0.85rem; line-height: 1.45; color: var(--muted);
}
figure.example > p { margin-top: 0.8rem; }

/* The Moon crop on the result page. Deliberately small: it is evidence for a
   sentence ("the halo was three times the Moon"), not a gallery piece. */
figure.moon { margin: 1rem 0; padding: 0; max-width: 260px; }
figure.moon img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--line); border-radius: 8px; background: #000;
}
figure.moon figcaption {
  margin-top: 0.4rem; font-size: 0.8rem; line-height: 1.45; color: var(--muted);
}

/* The folded list of earlier attempts on the result page. */
details.card > summary {
  cursor: pointer; font-weight: 600; color: var(--ink);
  list-style-position: outside;
}
details.card > summary::marker { color: var(--muted); }
details.card > .card { margin: 0.8rem 0 0; }
