/* ═══════════════════════════════════════════════════════════════
   DAYWORLD — dayworld.space

   The page has two grounds and moves between them once. It opens at night
   (#0f0f1a, the app icon's ground), the sky explodes into place, and then
   the ground warms into the app's paper — whichever of the twelve monthly
   papers the app is wearing today. That is the whole argument of the site
   in one gesture: look up, then look down.

   Everything below is written as two sets of the same tokens. Nothing is
   coloured directly; `html.is-day` swaps the set and the transitions carry
   the change. Add a colour and it has to exist in both grounds, or it will
   be invisible in one of them.
   ═══════════════════════════════════════════════════════════════ */

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

/* The `hidden` attribute only sets `display: none` in the UA stylesheet, so
   any author rule that sets a display — and half the boxes on this page are
   flex or grid — silently outranks it. That is how the timer's Start button
   went on showing underneath an open card, and how the empty social row went
   on claiming its margin in the footer. One rule, once, rather than an
   `[hidden]` clause bolted onto every flex container as it is written. */
[hidden] { display: none !important; }

:root {
  /* ── Night: fixed. This is the icon's ground and it does not vary. ── */
  --night: #0f0f1a;

  /* ── Paper: filled in at runtime from the app's MONTH_THEMES, so the site
        and the app are wearing the same month. These are April's, and they
        are only ever seen if the script fails to run. ── */
  --paper: #faf0e2;
  --paper-accent: #c4a24e;
  --wash-a: rgba(220, 200, 160, 0.30);
  --wash-b: rgba(200, 190, 150, 0.25);
  --wash-c: rgba(190, 180, 140, 0.20);

  /* ── Live tokens — night values. Everything paints with these. ── */
  --bg: var(--night);
  --text-primary: #ece6da;
  --text-secondary: #9d97ab;
  --text-dim: #635e75;
  --line: rgba(236, 230, 218, 0.16);
  --line-strong: rgba(236, 230, 218, 0.32);
  --accent: #e8c46a;
  --surface: rgba(236, 230, 218, 0.05);
  --wash-opacity: 0;
  --star-opacity: 1;
  /* The discs are painted in the app's paper-tuned colours. On black they
     need lifting, or the field reads as mud; in daylight they are already
     right. One filter, transitioned, does it for all ten. */
  --sky-lift: saturate(1.3) brightness(1.45);
  --sky-glow: drop-shadow(0 0 6px rgba(232, 196, 106, 0.35));

  --serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Times New Roman', serif;
  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto,
          'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;

  --ground-fade: 1400ms;
  --measure: 33rem;
}

html.is-day {
  --bg: var(--paper);
  --text-primary: #2c2420;
  --text-secondary: #6b5e54;
  --text-dim: #9b8e84;
  --line: rgba(44, 36, 32, 0.10);
  --line-strong: rgba(44, 36, 32, 0.22);
  --accent: var(--paper-accent);
  --surface: rgba(255, 255, 255, 0.42);
  --wash-opacity: 1;
  /* The stars do not leave when the sun comes up. They are just harder to see. */
  --star-opacity: 0.14;
  --sky-lift: none;
  --sky-glow: none;
}

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

body {
  min-height: 100%;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.7;
  color: var(--text-primary);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* Not a linear fade. A straight crossfade from #0f0f1a to paper spends its
     middle second as grey mud; this holds the night, then goes. The warm half
     of the change is carried by .dawn below, not by this. */
  transition: background-color var(--ground-fade) cubic-bezier(0.65, 0, 0.35, 1),
              color var(--ground-fade) ease;
}

/* The app's watercolour wash, which only exists in daylight. Kept painted at
   all times and faded by opacity rather than switched on, so the dawn brings
   it up with the ground instead of after it. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--wash-opacity);
  background:
    radial-gradient(ellipse 60% 50% at 20% 30%, var(--wash-a) 0%, transparent 70%),
    radial-gradient(ellipse 50% 60% at 80% 60%, var(--wash-b) 0%, transparent 70%),
    radial-gradient(ellipse 70% 40% at 50% 90%, var(--wash-c) 0%, transparent 60%);
  filter: blur(40px);
  transition: opacity var(--ground-fade) ease;
}

/* ── Dawn ──
   Light does not arrive from everywhere at once. This is a single warm bloom
   centred on wherever the Sun's disc actually is in the field that day, lit
   for the length of the ground's change and then gone. It is the only thing
   on the page that exists purely for the ninety frames it is visible. */
.dawn {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at var(--dawn-x, 50%) var(--dawn-y, 40%),
              rgba(255, 219, 158, 0.62) 0%,
              rgba(255, 198, 133, 0.26) 32%,
              rgba(255, 190, 130, 0) 62%);
  transition: opacity 1100ms ease-out;
}
html.dawning .dawn { opacity: 1; }

/* Everything real sits above the wash. */
.page { position: relative; z-index: 1; }

::selection { background: var(--accent); color: var(--bg); }

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

/* ═══════════════════════════════════════════
   SHARED TYPE
   ═══════════════════════════════════════════ */

/* The one label style: small, spaced, dim. It names a section without
   competing with anything in it. Chinese loses the tracking — spaced CJK
   reads as broken rather than quiet. */
.label {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color var(--ground-fade) ease;
}
html[lang="zh"] .label { letter-spacing: 0.1em; text-transform: none; font-size: 0.72rem; }

.serif { font-family: var(--serif); }

/* For text that exists only for a screen reader — the timers' status line. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.section {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 24px;
}

/* ═══════════════════════════════════════════
   LANGUAGE SWITCH — the only chrome on the page
   ═══════════════════════════════════════════ */
.lang-btn {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 40;
  padding: 6px 12px;
  min-width: 44px;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: color var(--ground-fade) ease, border-color var(--ground-fade) ease,
              background-color 0.25s ease, opacity 0.8s ease 300ms;
}
.lang-btn:hover { background: var(--surface); color: var(--text-primary); }
/* Absent until the sky has finished arriving. */
html.intro .lang-btn { opacity: 0; pointer-events: none; }

/* ═══════════════════════════════════════════
   HERO — the sky, and the three lines under it
   ═══════════════════════════════════════════ */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 72px 20px 40px;
  gap: 8px;
}

/* The cosmos: background stars and, for two seconds, the explosion. Fixed to
   the hero rather than the page so scrolling does not drag the stars along. */
.cosmos {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: var(--star-opacity);
  transition: opacity var(--ground-fade) ease;
}

.sky-wrap {
  position: relative;
  z-index: 1;
  width: min(84vmin, 540px);
  max-width: 100%;
}

/* On a wide screen vmin stops being the binding constraint and the height
   starts to be. Below the sky sit the scrubber, one line, and the cue: about
   400px, measured rather than guessed — it was 520 when the hero carried
   three lines and a subtitle, and those moved to the foot of the page.
   Below 700px wide this never applies: there vmin is the width, the sky is
   already small, and a hero slightly taller than the viewport is what the
   scroll cue is for. */
@media (min-width: 700px) {
  .sky-wrap { width: clamp(260px, min(84vmin, 100svh - 400px), 540px); }
}

.sky-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* The lift is on the group, not the discs, so the app's exact colours ship
   unmodified and daylight simply stops touching them. */
#skyBodies {
  filter: var(--sky-lift) var(--sky-glow);
  transition: filter var(--ground-fade) ease;
}
#skyZodiac text {
  fill: var(--text-dim);
  transition: fill var(--ground-fade) ease, opacity 900ms ease;
}
/* The zodiac and the dot at the centre are gated on `sky-set` rather than on
   `intro`: they belong to the sky and arrive the moment it settles, which is
   a second before the page's own furniture does. */
#skyZodiac { opacity: 1; transition: opacity 900ms ease; }
html:not(.sky-set) #skyZodiac { opacity: 0; }

.sky-centre {
  fill: var(--text-secondary);
  transition: fill var(--ground-fade) ease, opacity 900ms ease;
}
html:not(.sky-set) .sky-centre { opacity: 0; }

/* ── The three lines ── */
.hero-lines {
  position: relative;
  z-index: 1;
  margin-top: 26px;
  text-align: center;
  max-width: 30rem;
}

.hero-line {
  font-family: var(--serif);
  font-size: clamp(1.12rem, 3.4vw, 1.5rem);
  line-height: 1.85;
  color: var(--text-primary);
  transition: color var(--ground-fade) ease, opacity 1s ease, transform 1s ease;
}
html[lang="zh"] .hero-line { letter-spacing: 0.04em; }

/* The line arrives after the sky has settled. The delay is on the class
   rather than in script so a reduced-motion reader drops the whole thing by
   turning transitions off, and nothing else has to know. */
html.intro .hero-line { opacity: 0; transform: translateY(8px); }
.hero-line { opacity: 1; transform: none; }

/* ── Scroll cue: a hairline that breathes. No arrow, no word. ── */
.scroll-cue {
  position: relative;
  z-index: 1;
  margin-top: 26px;
  width: 1px;
  height: 40px;
  background: linear-gradient(var(--line-strong), transparent);
  transition: opacity 1s ease 1.4s, background 1s ease;
}
html.intro .scroll-cue { opacity: 0; }

/* ═══════════════════════════════════════════
   TIME — the scrubber under the sky
   ═══════════════════════════════════════════ */
.time {
  position: relative;
  z-index: 1;
  margin-top: 18px;
  width: min(84vmin, 540px);
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  transition: opacity 1s ease 1.2s;
}
html.intro .time { opacity: 0; pointer-events: none; }

.time-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.time-date {
  font-family: var(--serif);
  font-size: 0.95rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  transition: color var(--ground-fade) ease;
}
.time-hint {
  font-size: 0.7rem;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.6;
  transition: color var(--ground-fade) ease;
}

.time-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
}

/* A hairline the same weight as everything else on the page, with the
   smallest handle that is still catchable by a thumb. */
.scrub {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 22px;
  background: transparent;
  cursor: pointer;
}
.scrub::-webkit-slider-runnable-track {
  height: 1px;
  background: var(--line-strong);
  transition: background var(--ground-fade) ease;
}
.scrub::-moz-range-track { height: 1px; background: var(--line-strong); }
.scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 11px; height: 11px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
  transition: background var(--ground-fade) ease, transform 0.15s ease;
}
.scrub::-moz-range-thumb {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.scrub:active::-webkit-slider-thumb { transform: scale(1.35); }

.pill {
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 13px;
  min-height: 32px;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--ground-fade) ease, border-color var(--ground-fade) ease,
              background-color 0.2s ease;
}
.pill:hover { background: var(--surface); color: var(--text-primary); }
.pill[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }

/* ═══════════════════════════════════════════
   SECTION HEADINGS
   ═══════════════════════════════════════════ */
/* Sections 2 and 3 are each headed by one line of the poem, set exactly as the
   hero's line is. That is the structure: three lines, three screens, and the
   page is the sentence. */
.section-line {
  font-family: var(--serif);
  font-size: clamp(1.12rem, 3.4vw, 1.5rem);
  font-weight: 400;
  line-height: 1.7;
  text-align: center;
  color: var(--text-primary);
  transition: color var(--ground-fade) ease;
}
html[lang="zh"] .section-line { letter-spacing: 0.04em; }

/* ═══════════════════════════════════════════
   TIMERS — the part you can actually press
   ═══════════════════════════════════════════ */
.timer {
  padding: clamp(40px, 8vh, 80px) 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}

.timer-modes {
  display: flex;
  gap: 8px;
}

.timer-stage {
  position: relative;
  width: min(78vmin, 340px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* Focus paints this; meditation leaves it empty. */
  background: var(--stage-bg, transparent);
  transition: background-color 700ms ease;
}

.timer-ring-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}
.timer-track {
  fill: none;
  stroke: var(--line);
  stroke-width: 2;
  transition: stroke var(--ground-fade) ease;
}
.timer-progress {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.9s linear, stroke 600ms ease, opacity 600ms ease;
}
/* One ring each, and which one you get says which timer you are in.

   They were both drawn once, and the picture had nothing to look at: a plain
   track sitting outside a rainbow that swells and shrinks gives the eye two
   circles and no reason to prefer either, and the breathing — the only thing
   on this screen that is actually telling you to do something — lost. So
   meditation shows the rainbow alone and focus shows the sweep alone. */
.timer-breath-ring {
  fill: none;
  stroke: url(#rainbow);
  stroke-width: 2.5;
  opacity: 0;
  transition: opacity 700ms ease;
}
.timer-stage.breathing .timer-breath-ring { opacity: 0.9; }
.timer-stage.breathing .timer-track,
.timer-stage.breathing .timer-progress { opacity: 0; }

.timer-readout {
  position: relative;
  z-index: 1;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.timer-time {
  font-family: var(--serif);
  font-size: clamp(2.4rem, 9vw, 3.4rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  transition: color 600ms ease;
}
.timer-unit {
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color 600ms ease;
}
html[lang="zh"] .timer-unit { letter-spacing: 0.12em; text-transform: none; }
/* `breathe` is set as written, in both languages: it is the word the app
   says, and it is an instruction rather than a field name. Without this the
   English would read BREATHE while the Chinese read breathe. */
.timer-unit--breath { text-transform: none; letter-spacing: 0.18em; }

.timer-controls { display: flex; gap: 10px; min-height: 32px; }

.timer-msg {
  font-size: 0.85rem;
  line-height: 1.7;
  color: var(--text-secondary);
  text-align: center;
  min-height: 1.7em;
  max-width: 26rem;
  transition: color var(--ground-fade) ease;
}

/* Focus takes the whole stage, the way it does in the app: the colour is the
   point of it. The readout inverts so it stays legible on all three. */
.timer-stage.focus-red    { --stage-bg: rgba(180, 74,  46,  0.92); }
.timer-stage.focus-yellow { --stage-bg: rgba(180, 146, 74,  0.92); }
.timer-stage.focus-blue   { --stage-bg: rgba(74,  100, 140, 0.92); }
.timer-stage[class*="focus-"] .timer-time { color: #fff; }
.timer-stage[class*="focus-"] .timer-unit { color: rgba(255, 255, 255, 0.7); }
.timer-stage[class*="focus-"] .timer-track { stroke: rgba(255, 255, 255, 0.22); }
.timer-stage[class*="focus-"] .timer-progress { stroke: rgba(255, 255, 255, 0.9); }

/* ═══════════════════════════════════════════
   THE FOCUS CARD, AND THE LOG IT FEEDS
   ═══════════════════════════════════════════ */
/* The card is part of the timer block, not a layer over it: what it asks is
   the last step of the session, and a modal would make it an interruption. */
.focus-card {
  width: min(100%, 26rem);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  transition: border-color var(--ground-fade) ease, background-color var(--ground-fade) ease;
}

.focus-tags { display: flex; gap: 10px; }

/* Icons and nothing else. A word under each one is a word you have to read
   before you can press it, and there are only three. */
.focus-tag {
  width: 46px;
  height: 46px;
  font-size: 1.25rem;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.15s ease;
}
.focus-tag:hover { background: var(--surface); }
.focus-tag.picked { border-color: var(--accent); background: var(--accent-soft, transparent); }
/* The +. Dashed, and a shade quieter than the icons beside it, so the row
   still reads as three things you can pick and one thing you can do. */
.focus-tag--add {
  font-size: 1.1rem;
  color: var(--text-dim);
  border-style: dashed;
  border-color: var(--line-strong);
}
.focus-tag--add:hover { color: var(--text-primary); }
.focus-tag--add[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

/* What the + opens. Smaller circles than the tags, because these are not
   choices about this session — they are a shelf you are taking one off. */
.focus-palette {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.palette-icon {
  width: 38px;
  height: 38px;
  font-size: 1.05rem;
  line-height: 1;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.15s ease;
}
.palette-icon:hover { background: var(--surface); transform: scale(1.08); }

.focus-hint, .focus-log-note, .field-hint {
  font-size: 0.72rem;
  line-height: 1.75;
  color: var(--text-dim);
  transition: color var(--ground-fade) ease;
}

.focus-note {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 6px 0;
  resize: none;
  transition: border-color 0.2s ease, color var(--ground-fade) ease;
}
.focus-note:focus { outline: none; border-bottom-color: var(--accent); }
.focus-note::placeholder { color: var(--text-dim); }

.focus-card-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* A button that is a word, for the second-choice action beside a pill. */
.link-btn {
  font-family: var(--sans);
  font-size: 0.74rem;
  color: var(--text-dim);
  background: none;
  border: none;
  padding: 6px 2px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.2s ease;
}
.link-btn:hover { color: var(--text-primary); }

/* ── The log ──
   The app's shape and its reasoning: the sessions in the order they happened,
   then the total under them, the way a receipt totals at the bottom. */
.focus-log {
  width: min(100%, 26rem);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 8px;
}

.log-row {
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  transition: border-color var(--ground-fade) ease;
}
.log-head {
  font-size: 0.82rem;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  transition: color var(--ground-fade) ease;
}
.log-note {
  margin-top: 3px;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-secondary);
  transition: color var(--ground-fade) ease;
}
.focus-log-total {
  padding-top: 8px;
  font-size: 0.76rem;
  color: var(--text-dim);
  transition: color var(--ground-fade) ease;
}
.focus-log-note { padding-top: 10px; }

/* ═══════════════════════════════════════════
   YOUR CHART
   ═══════════════════════════════════════════ */
.chart {
  padding: clamp(60px, 11vh, 130px) 24px clamp(30px, 6vh, 60px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}
.chart-body {
  max-width: 30rem;
  font-size: 0.92rem;
  line-height: 1.9;
  text-align: center;
  color: var(--text-secondary);
  transition: color var(--ground-fade) ease;
}

.pill--wide { padding: 10px 24px; min-height: 40px; }

/* ── The form ── */
.chart-form, .chart-view {
  width: min(100%, 26rem);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field-label {
  margin-top: 12px;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  transition: color var(--ground-fade) ease;
}

.field {
  width: 100%;
  font-family: var(--sans);
  font-size: 0.92rem;
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 7px 0;
  border-radius: 0;             /* iOS rounds date and number inputs */
  transition: border-color 0.2s ease, color var(--ground-fade) ease;
}
.field:focus { outline: none; border-bottom-color: var(--accent); }
.field::placeholder { color: var(--text-dim); }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.field-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 0.82rem;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--ground-fade) ease;
}
.field-check input { accent-color: var(--accent); width: 16px; height: 16px; }

.field-hint { margin-top: 4px; }
/* The one line someone about to type their birth time has to see. */
.field-hint--privacy { margin-top: 14px; text-align: center; }
.field-hint--centre { margin-top: 22px; text-align: center; }

.field-status {
  margin-top: 10px;
  font-size: 0.78rem;
  color: var(--retro, #c44535);
}

.place-wrap { position: relative; }
.place-results {
  position: absolute;
  z-index: 5;
  left: 0; right: 0;
  max-height: 240px;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
}
.place-result {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--sans);
  font-size: 0.84rem;
  color: var(--text-primary);
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 10px 12px;
  cursor: pointer;
}
.place-result:last-child { border-bottom: none; }
.place-result:hover { background: var(--surface); }

.dst-note {
  margin-top: 8px;
  padding: 10px 12px;
  font-size: 0.76rem;
  line-height: 1.7;
  color: var(--text-secondary);
  border: 1px solid var(--line);
  border-radius: 10px;
}

/* ── The readout ── */
.chart-three {
  display: flex;
  flex-direction: column;
  margin-top: 10px;
}
.chart-three-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.chart-three-label {
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  color: var(--text-dim);
}
.chart-three-sign {
  font-family: var(--serif);
  font-size: 1.15rem;
  color: var(--text-primary);
}

.chart-houses { margin-top: 22px; }
.chart-house-list {
  margin-top: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 20px;
}
.chart-house-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.8rem;
}
.chart-house-body { color: var(--text-primary); }
.chart-house-num { color: var(--text-dim); font-variant-numeric: tabular-nums; }

#chartRedoBtn { align-self: center; margin-top: 20px; }

/* ── The wheel ──
   chartWheelSvg() is the app's, lifted whole, and it writes these class names.
   The rules are the app's too (src/index.html), with its --chart-rule-soft
   token defined here because the site does not carry the chart page's. */
:root { --chart-rule-soft: rgba(0, 0, 0, 0.05); }

.chart-wheel { display: block; width: 100%; height: auto; margin: 2px 0 4px; }
.wheel-rule { fill: none; stroke: var(--chart-rule-soft); stroke-width: 1; }
.wheel-cusp { stroke: var(--chart-rule-soft); stroke-width: 1; }
.wheel-cusp--angle { stroke: var(--text-dim); stroke-width: 1; opacity: 0.55; }
.wheel-sign { font-size: 11px; fill: var(--text-secondary); text-anchor: middle; }
.wheel-house-num {
  font-family: var(--serif);
  font-size: 12px;
  fill: var(--text-dim);
  text-anchor: middle;
}
.wheel-angle {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.5px;
  fill: var(--text-dim);
  text-anchor: middle;
}
.wheel-glyph { font-size: 13px; fill: var(--text-primary); text-anchor: middle; }
/* Venus and Mars arrive as nested SVG using currentColor, so their colour has
   to come from `color` — setting fill here would paint the shapes solid. */
.wheel-glyph-svg { color: var(--text-primary); overflow: visible; }
.wheel-retro {
  font-size: 8px;
  font-style: italic;
  fill: var(--retro, #c44535);
  text-anchor: middle;
}

/* ═══════════════════════════════════════════
   FEATURES — four lines, no icons, no cards
   ═══════════════════════════════════════════ */
.features { padding: clamp(50px, 9vh, 100px) 24px; }
.features-title { margin-bottom: 22px; }

.features-list { list-style: none; }
.features-list li {
  padding: 15px 0;
  font-size: 0.94rem;
  line-height: 1.75;
  color: var(--text-primary);
  border-bottom: 1px solid var(--line);
  transition: color var(--ground-fade) ease, border-color var(--ground-fade) ease;
}
.features-list li:last-child { border-bottom: none; }

/* Two lines above the list of what is in it — the argument for the list. */
.creed {
  padding: clamp(56px, 10vh, 120px) 24px clamp(20px, 4vh, 44px);
  text-align: center;
}
.closing-line {
  font-size: clamp(1.05rem, 3.2vw, 1.35rem);
  line-height: 2.1;
  color: var(--text-secondary);
  transition: color var(--ground-fade) ease;
}

/* And one line at the foot of the page, alone, set in ink. */
.closing {
  padding: clamp(60px, 12vh, 140px) 24px;
  text-align: center;
  font-size: clamp(1.15rem, 3.4vw, 1.5rem);
  color: var(--text-primary);
  transition: color var(--ground-fade) ease;
}

/* ═══════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════ */
.footer {
  padding: 40px 24px calc(46px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  text-align: center;
  transition: border-color var(--ground-fade) ease;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 22px;
  margin-bottom: 26px;
}
.footer a {
  font-size: 0.8rem;
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.footer a:hover { color: var(--text-primary); border-bottom-color: var(--line-strong); }

.footer-mark {
  font-family: var(--serif);
  font-size: 0.95rem;
  color: var(--text-primary);
  transition: color var(--ground-fade) ease;
}
.footer-tagline, .footer-site {
  font-size: 0.72rem;
  color: var(--text-dim);
  transition: color var(--ground-fade) ease;
}
.footer-site { margin-top: 3px; letter-spacing: 0.06em; }

/* ═══════════════════════════════════════════
   LEGAL PAGES
   ═══════════════════════════════════════════ */
/* The legal pages skip the night entirely: nobody arrives at a privacy policy
   wanting a light show. They open on paper — `is-day` is on the element from
   the first byte — and share every other token with the home page.

   Both languages ship in the HTML and one of them is `hidden`; the switch
   swaps which. That is one page rather than four, and it means a link to
   /privacy.html is correct whoever follows it. */
.legal {
  max-width: 40rem;
  margin: 0 auto;
  padding: clamp(56px, 10vh, 110px) 24px 40px;
}
.legal h1 {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 5vw, 2rem);
  font-weight: 500;
  line-height: 1.35;
  margin-bottom: 6px;
}
.legal .legal-date {
  font-size: 0.75rem;
  color: var(--text-dim);
  margin-bottom: 40px;
}
.legal h2 {
  font-family: var(--serif);
  font-size: 1.08rem;
  font-weight: 600;
  margin: 38px 0 12px;
}
.legal p, .legal li {
  font-size: 0.92rem;
  line-height: 1.85;
  color: var(--text-secondary);
}
.legal p { margin-bottom: 14px; }
.legal ul { margin: 0 0 14px 1.1rem; }
.legal li { margin-bottom: 7px; }
.legal a { color: var(--text-primary); text-decoration: underline; text-underline-offset: 3px; }
.legal strong { color: var(--text-primary); font-weight: 600; }

/* ═══════════════════════════════════════════
   REDUCED MOTION — the sky is already there
   ═══════════════════════════════════════════ */
/* Not a lesser version of the page: the same page, arrived at rather than
   performed. The script skips straight to the settled state; this makes sure
   nothing left over animates its way in behind it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 420px) {
  :root { --measure: 100%; }
  .hero { padding-top: 60px; }
  .lang-btn { top: 12px; right: 12px; }
}

/* A short screen of any width — an SE, or a browser carrying a lot of chrome.
   Every value here is taken back from padding, leading and the sky; not one
   line of copy is dropped, because the copy is the page. */
@media (max-height: 700px) {
  .sky-wrap { width: min(68vmin, 400px); }
  .hero { padding: 52px 20px 24px; }
  .hero-lines { margin-top: 18px; }
  .hero-line { font-size: clamp(1rem, 3.4vw, 1.2rem); line-height: 1.6; }
  .time { margin-top: 12px; }
  .scroll-cue { margin-top: 16px; height: 28px; }
}
