/* ==========================================================================
   eclipse2026.ch
   --------------------------------------------------------------------------
   Everything visual is driven by the custom properties in :root, so you can
   restyle the whole page from that one block. Layout below is plain flex/grid
   with single-class selectors — no nesting, no !important, easy to override.

   1. Tokens
   2. Reset & base
   3. Layout helpers
   4. Header & language bar
   5. Hero (full-viewport, eclipse canvas as background) & countdown
   6. Sections
   7. Timeline
   8. Prose & footer
   9. Responsive
  10. Motion & print
   ========================================================================== */

/* ------------------------------------------------------------- 1. Tokens */

:root {
  /* palette */
  --c-bg:            #07080f;
  --c-bg-raised:     #0d0f1a;
  --c-bg-sunk:       #05060c;
  --c-ink:           #f2ece4;
  --c-ink-muted:     #a6a2b4;
  --c-ink-faint:     #6f6b80;
  --c-line:          rgba(242, 236, 228, 0.12);
  --c-line-strong:   rgba(242, 236, 228, 0.24);

  /* One accent, used for the logo's 2026, the peak line, the maximum
     time, links, focus rings and the button. */
  --c-accent:        #ff8a3d;
  --c-accent-hover:  #ffa361;
  --c-on-accent:     #1a1005;   /* dark ink, for text on the accent fill */

  /* type */
  /* Helvetica everywhere — one family, no serif or monospace anywhere.
     Arial is the stand-in on systems without Helvetica. */
  --font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;

  --fs-kicker:   0.78rem;
  --fs-note:     0.84rem;
  --fs-body:     1.02rem;
  --fs-lead:     1.18rem;
  --fs-h2:       clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem);
  --fs-display:  clamp(2.6rem, 1.4rem + 6vw, 5.4rem);
  --fs-count:    clamp(1.9rem, 1.1rem + 3.4vw, 3.1rem);

  --lh-tight: 1.08;
  --lh-body:  1.62;
  --tracking-wide: 0.16em;

  /* space */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4.5rem;

  /* shape */
  --wrap:      68rem;
  --wrap-pad:  clamp(1.15rem, 4vw, 2.5rem);
  --radius:    10px;
  --radius-lg: 16px;
  --border:    1px solid var(--c-line);

  --shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  --ease:   cubic-bezier(0.22, 0.61, 0.36, 1);
  --speed:  180ms;
}

/* ------------------------------------------------------ 2. Reset & base */

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

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

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, dl, dd, ol, ul, figure {
  margin: 0;
  padding: 0;
}

ol, ul { list-style: none; }

a {
  color: var(--c-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

canvas { display: block; }

button, select, input { font: inherit; color: inherit; }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-ink);
  color: var(--c-bg);
  border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
  left: 0;
}

/* --------------------------------------------------- 3. Layout helpers */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--wrap-pad);
}

/* Asymmetric: less air above the title than below the section's content, so
   each heading sits close to the block it introduces. */
.section {
  padding-block: var(--sp-6) var(--sp-8);
}

.section__title {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

.section__sub {
  max-width: 46rem;
  margin-top: var(--sp-3);
  color: var(--c-ink-muted);
}

.kicker {
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--c-accent);
}

.note {
  max-width: 48rem;
  margin-top: var(--sp-4);
  font-size: var(--fs-note);
  line-height: 1.55;
  color: var(--c-ink-faint);
}

.note--quiet {
  color: var(--c-ink-faint);
  opacity: 0.72;
}

/* --------------------------------------------- 4. Header & language bar */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--c-bg) 82%, transparent);
  backdrop-filter: blur(10px);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: 3.5rem;
}

.brand {
  color: var(--c-ink);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.brand strong {
  color: var(--c-accent);
  font-weight: 600;
}

.langbar {
  display: flex;
  gap: 2px;
  padding: 2px;
  border: var(--border);
  border-radius: 999px;
}

/* Two elements wear this class: <a> in the page header, where switching is a
   navigation, and <button> in the map viewer, where it happens in place. They
   have to look identical, hence the reset of both sets of defaults. */
.langbar__btn {
  display: inline-block;
  padding: 0.3rem 0.72rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--c-ink-muted);
  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.06em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--speed) var(--ease), color var(--speed) var(--ease);
}

.langbar__btn:hover {
  color: var(--c-ink);
}

.langbar__btn[aria-current="true"] {
  background: var(--c-ink);
  color: var(--c-bg);
}

/* ------------------------------------------------- 5. Hero & countdown */

/* Full-viewport hero. The eclipse canvas is the section's background; the
   date sits above it and the countdown below, so the sun lands in the gap
   between them. Keep --sun-fill in js/scene.js in step with this layout. */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;              /* dodges mobile address-bar resize */
  overflow: hidden;
  background: var(--c-bg);         /* shows if WebGL never starts */
}

.hero__canvas {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
}

/* Darkens only the top and bottom bands, leaving the sun's middle clear. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(7, 8, 15, 0.94) 0%,
    rgba(7, 8, 15, 0.80) 22%,
    rgba(7, 8, 15, 0) 38%,
    rgba(7, 8, 15, 0) 80%,
    rgba(7, 8, 15, 0.72) 92%,
    rgba(7, 8, 15, 0.96) 100%
  );
}

.hero__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--sp-6);
  min-height: 100vh;
  min-height: 100svh;
  padding-block: clamp(var(--sp-6), 7vh, var(--sp-8));
}

/* Own column on the left, clear of the off-centre disk. Widening this past
   ~26rem starts pushing the copy onto the glow — see SUN_CENTER in scene.js. */
.hero__head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  max-width: 26rem;
}

.hero__warning {
  position: absolute;
  inset: auto var(--sp-4) var(--sp-4) var(--sp-4);
  z-index: 3;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.6);
  font-size: var(--fs-note);
  color: var(--c-ink-muted);
}

/* Approximate time of deepest coverage, right under the date.
   pre-line so the \n in the hero.peak string breaks the line, while long
   translations can still wrap normally. */
.hero__peak {
  font-family: var(--font-sans);
  font-size: clamp(1rem, 0.85rem + 0.9vw, 1.35rem);
  font-variant-numeric: tabular-nums;
  line-height: 1.42;
  letter-spacing: 0.01em;
  white-space: pre-line;
  color: var(--c-accent);
}

/* The h1 is two lines: the date at display size, and under it the subject in
   words. Both are inside the heading, so the page's main heading says what the
   page is about rather than only when it is. */
.hero__title {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  font-weight: 400;
}

.hero__date {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-display);
  font-weight: 400;
  line-height: var(--lh-tight);
  letter-spacing: -0.025em;
}

/* Deliberately quiet: it is there to name the subject, not to compete with the
   date above it or the accented peak line below. */
.hero__subtitle {
  display: block;
  max-width: 26rem;
  font-size: clamp(0.95rem, 0.85rem + 0.4vw, 1.1rem);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: 0.01em;
  color: var(--c-ink-muted);
}

/* The date reads as one line, which needs more room than the 26rem copy
   column: the column's cap comes off and moves onto the copy itself, so the
   prose still stays clear of the glow. Only the date runs wider, and it sits
   inside the scrim's dark top band, well above the disk. The longest string
   ("12. August 2026") is ~7.3em wide, so it clears the wrap at every width
   where this applies. */
@media (min-width: 48rem) {
  .hero__head { max-width: none; }

  .hero__date { white-space: nowrap; }

  .hero__peak { max-width: 26rem; }
}

/* Held narrow so the copy stays clear of the centred disk, and given a soft
   shadow as insurance where the glow reaches it on short viewports. */
.hero__lead {
  max-width: 26rem;
  font-size: var(--fs-lead);
  color: var(--c-ink-muted);
  text-wrap: pretty;
}

.hero__date,
.hero__subtitle,
.hero__peak,
.hero__lead,
.countdown {
  text-shadow: 0 1px 16px rgba(7, 8, 15, 0.75);
}

/* The label is empty while counting down; it only carries the
   "happening now" / "over" message. */
.countdown__label:empty { display: none; }

.countdown__label {
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--c-ink-faint);
}

.countdown__units {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(var(--sp-4), 4vw, var(--sp-7));
}

.unit {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 3.6rem;
}

/* Needed because the display above outranks the browser's [hidden] rule. */
.unit[hidden] { display: none; }

.unit__value {
  font-family: var(--font-sans);
  font-size: var(--fs-count);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--c-ink);
}

/* Only present while the eclipse runs, so it must not reserve space the rest
   of the time — the countdown sits at the bottom of the hero and any empty
   line here would push it up. */
.countdown__caption:empty { display: none; }

.countdown__caption {
  margin-top: var(--sp-3);
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--c-accent);
}

.unit__label {
  font-size: var(--fs-kicker);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-ink-faint);
}

/* The label swaps in for the units when the eclipse is live or finished. */
.countdown--message .countdown__units { display: none; }

.countdown--message .countdown__label {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-accent);
}

/* ------------------------------------------------------- 7. Timeline */

/* No borders, no cell backgrounds — the columns are held apart by the grid
   gap alone. The peak column is distinguished only by its text colour. */
.timeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--sp-5) var(--sp-6);
  margin-top: var(--sp-6);
}

.phase {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.phase__label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-ink-muted);
}

.phase__time {
  font-family: var(--font-sans);
  font-size: 1.55rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.phase--peak .phase__time { color: var(--c-accent); }

.phase__note {
  font-size: var(--fs-note);
  color: var(--c-ink-faint);
}

/* --------------------------------------------- 7b. Paired columns (.duo) */

/* Stacked by default; two equal columns once there is room for both. Each
   column is a flex column whose prose takes up the slack, so the two buttons
   line up on the same baseline however unequal the copy above them is. */
.duo {
  display: grid;
  gap: var(--sp-8) var(--sp-6);
}

.duo__col {
  display: flex;
  flex-direction: column;
}

.duo__col .prose { flex: 1 1 auto; }

@media (min-width: 60rem) {
  .duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------------------------------------------------- 8. Prose & footer */

.prose {
  max-width: 40rem;
  margin-top: var(--sp-5);
  color: var(--c-ink-muted);
}

.prose > * + * { margin-top: var(--sp-4); }

/* Solid accent call-to-action, sits at the end of a section. */
.btn {
  display: inline-block;
  margin-top: var(--sp-5);
  padding: 0.7rem 1.2rem;
  border: 0;
  border-radius: var(--radius);
  background: var(--c-accent);
  color: var(--c-on-accent);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--speed) var(--ease);
}

.btn:hover {
  background: var(--c-accent-hover);
  color: var(--c-on-accent);
}

/* fit-content keeps the box tight to the label; auto margins do the centring. */
.btn--center {
  display: block;
  width: fit-content;
  margin-inline: auto;
}

/* ------------------------------------------------- 8b. Full-page viewer */

/* The map lives in an iframe of its own (eclipse-map/web), so this is only a
   frame around it: cover the page, put the site's bar on top and hand the rest
   of the area to the frame. Column flex rather than an overlaid bar, so the
   map's legend and controls stay clear of it without the map knowing. */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: var(--c-bg);
}

/* Needed because .viewer is display:flex, which outranks [hidden]. */
.viewer[hidden] { display: none; }

.viewer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex: none;
  min-height: 3.5rem;
  /* Full width rather than .wrap: the map underneath is edge to edge, so the
     close button belongs by the edge and not at a centred column's margin. */
  padding-inline: var(--wrap-pad);
  border-bottom: var(--border);
  background: var(--c-bg-sunk);
}

.viewer__tools {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

/* min-height: 0 lets the frame shrink inside the column; without it the
   iframe's intrinsic height would push the bar off the top. */
.viewer__frame {
  display: block;
  flex: 1;
  min-height: 0;
  width: 100%;
  border: 0;
}

.viewer__close {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--c-ink-muted);
  cursor: pointer;
  transition: background var(--speed) var(--ease), color var(--speed) var(--ease);
}

.viewer__close:hover {
  background: var(--c-accent);
  color: var(--c-on-accent);
}

/* Set while the viewer is open: the page behind it must not scroll under it. */
.is-viewer-open,
.is-viewer-open body { overflow: hidden; }

.site-footer {
  padding-block: var(--sp-7);
  background: var(--c-bg-sunk);
}

/* Both footer lines are centred: margin-inline centres the block itself,
   which .note's max-width would otherwise pin to the left, and text-align
   centres the lines inside it. */
.site-footer .note {
  margin-inline: auto;
  text-align: center;
}

.footer__copyright a {
  text-decoration: underline;
}

.footer__copyright a:hover {
  color: var(--c-accent-hover);
}

/* ------------------------------------------------------ 9. Responsive */

@media (max-width: 40rem) {
  .hero__inner { gap: var(--sp-5); }
}

/* ------------------------------------------------- 10. Motion & print */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    transition-duration: 1ms;
    animation-duration: 1ms;
    animation-iteration-count: 1;
  }
}

@media print {
  .langbar { display: none; }

  body { background: #fff; color: #000; }
}
