/* ================================================================
   ECLIPSETRACKER: GLOBAL STYLESHEET
   Dark monochrome glassmorphism aesthetic.
================================================================ */

:root {
  --bg-base:        #030305;
  --bg-surface:     #08080a;
  --bg-card:        rgba(20, 20, 25, 0.65);
  --bg-card-hover:  rgba(30, 30, 38, 0.85);

  --accent-white:   #ffffff;
  --accent-silver:  #c0c0c8;
  --accent-slate:   #6b6b75;
  --accent-blue:    #82aaff;

  --text-primary:   #f8f8f8;
  --text-secondary: #90909a;
  /* At least 4.5:1 on every background it sits on (5.0:1 on the year groups, 5.2:1 on the card);
     it was #555560, 2.6:1 (code review C-2, 2026-10-16). */
  --text-muted:     #84848e;

  --border:         rgba(255, 255, 255, 0.08);
  --border-active:  rgba(255, 255, 255, 0.25);

  --grad-hero:      linear-gradient(135deg, #0d0d12 0%, #030305 100%);
  --grad-primary:   linear-gradient(135deg, #ffffff 0%, #a0a0aa 100%);

  --sp-xs:  0.25rem; --sp-sm:  0.5rem; --sp-md:  1rem; --sp-lg:  1.5rem; --sp-xl:  2rem; --sp-2xl: 3rem;
  --font-sans: 'InterVariable', 'Inter', system-ui, sans-serif;
  --font-mono: 'InterVariable', 'Inter', system-ui, sans-serif;

  --r-sm:   6px; --r-md:   12px; --r-lg:   20px; --r-full: 9999px;
  --shadow-card: 0 8px 32px rgba(0,0,0,0.6), 0 2px 8px rgba(0,0,0,0.4);
  --t-fast: 0.15s ease; --t-med: 0.3s ease;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* 100%, not 16px: a reader's own text size setting carries through (code review C-26). */
html { font-size: 100%; scroll-behavior: smooth; }

body {
  font-family: var(--font-sans);
  background: var(--bg-base);
  color: var(--text-primary);
  min-height: 100vh;
  line-height: 1.6;
  background-image: 
    radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.03) 0%, transparent 60%),
    radial-gradient(circle at 10% 80%, rgba(255, 255, 255, 0.02) 0%, transparent 50%);
  background-attachment: fixed;
  display: flex; flex-direction: column;
}

h1, h2, h3 { color: var(--text-primary); font-weight: 600; line-height: 1.2; letter-spacing: -0.02em; }
.mono { font-family: var(--font-mono); letter-spacing: 0.04em; }

.site-header { padding: var(--sp-xl) var(--sp-md); text-align: center; }
.header-inner { max-width: 600px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: var(--sp-md); }
.logo-icon { width: 64px; height: 64px; animation: pulse 6s infinite alternate; filter: drop-shadow(0 0 12px rgba(255,255,255,0.4)); }
@keyframes pulse { from { opacity: 0.8; transform: scale(0.98); } to { opacity: 1; transform: scale(1.02); } }

.header-text h1 {
  font-size: clamp(2rem, 6vw, 3.2rem); font-weight: 700; letter-spacing: -0.02em;
  background: var(--grad-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; line-height: 1.1;
}
.tagline { color: var(--text-secondary); font-size: 0.95rem; text-transform: uppercase; margin-top: var(--sp-xs); letter-spacing: 0.06em; }

.main-content { flex: 1; padding: 0 var(--sp-md) var(--sp-2xl); display: flex; flex-direction: column; align-items: center; }

.card {
  background: var(--bg-card); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--sp-xl);
  box-shadow: var(--shadow-card); position: relative; overflow: hidden; width: 100%; max-width: 600px;
}
.card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
}

.countdown-section { text-align: center; margin-bottom: var(--sp-xl); }
.countdown-section h2 { font-size: 1.2rem; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: var(--sp-sm); }
.countdown-display { font-size: clamp(2.5rem, 8vw, 4rem); font-weight: 800; color: var(--accent-white); font-variant-numeric: tabular-nums; line-height: 1; text-shadow: 0 0 20px rgba(255,255,255,0.2); }

.event-details { border-top: 1px solid var(--border); padding-top: var(--sp-md); margin-top: var(--sp-md); display: flex; flex-direction: column; gap: var(--sp-sm); }
.event-row { display: flex; justify-content: space-between; align-items: center; padding: var(--sp-sm) 0; }
.event-label { color: var(--text-secondary); font-size: 0.9rem; font-weight: 500; }
.event-value { color: var(--text-primary); font-size: 1rem; font-weight: 600; text-align: right; }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-sm); padding: 0.75rem 1.5rem; border: none; border-radius: var(--r-md); font-family: var(--font-sans); font-size: 0.95rem; font-weight: 600; cursor: pointer; transition: all var(--t-fast); text-decoration: none; }
.btn-primary { background: var(--accent-white); color: #000; box-shadow: 0 4px 16px rgba(255, 255, 255, 0.2); }
.btn-primary:hover { box-shadow: 0 6px 24px rgba(255, 255, 255, 0.4); transform: translateY(-1px); }

/* ---- EclipseTracker 2.0: the list and the alarm planner (2026-10-16) ---- */
[hidden] { display: none !important; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.main-content { gap: var(--sp-xl); }
.noscript { color: var(--text-secondary); }

.eyebrow { color: var(--text-muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: var(--sp-xs); }
/* The title is never wider than a 320 px screen, even with text at 200% (it is large already). */
.header-text h1 { font-size: min(clamp(2rem, 6vw, 3.2rem), 13.5vw); }

/* The countdown: four groups, each a number with its label under it. The groups wrap onto a second
   line rather than being cut off at 320 px with large text (code review C-8); a colon ends every
   group but the last, so a line never starts with one. */
.countdown-display {
  font-size: clamp(1.75rem, 10vw, 4rem);
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; row-gap: var(--sp-md);
}
.cd-part { display: inline-flex; align-items: flex-start; }
.cd-group { display: inline-flex; flex-direction: column; align-items: center; }
.cd-num, .cd-sep { line-height: 1; }
.cd-label {
  margin-top: 0.5rem; color: var(--text-muted); font-size: 0.8rem; font-weight: 400; line-height: 1.2;
  text-transform: uppercase; letter-spacing: 0.04em; text-shadow: none;
}

dl.event-details { margin-bottom: 0; }
.event-row { gap: var(--sp-md); }
.event-value { margin: 0; overflow-wrap: anywhere; }
.card-actions { display: flex; justify-content: center; margin-top: var(--sp-lg); }

.btn:focus-visible, select:focus-visible, input:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent-blue); outline-offset: 2px;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; transform: none; }
.btn-secondary { background: transparent; color: var(--text-primary); border: 1px solid var(--border-active); }
.btn-secondary:hover:not(:disabled) { background: var(--bg-card-hover); }

/* The Android app's store links, Zapstore and Google Play (website only, 2026-10-30). Marked
   data-web-only in the HTML: the Android app's bridge script hides it, and the [hidden] rule above
   wins over the display rule here. The two buttons sit side by side when they fit and one above
   the other on a narrow screen. */
.android-app {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-sm);
  width: 100%; max-width: 600px; text-align: center;
  color: var(--text-secondary); font-size: 0.9rem; line-height: 1.5;
}
.android-app strong { color: var(--text-primary); font-weight: 600; }
.store-links { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-sm); max-width: 100%; }
.android-app .btn { position: relative; min-height: 44px; max-width: 100%; padding-left: 1.25rem; padding-right: 1.25rem; white-space: normal; }

.list-heading { font-size: 1.4rem; margin-bottom: var(--sp-sm); }
.list-intro, .list-source { color: var(--text-secondary); font-size: 0.92rem; }
.list-source { margin-top: var(--sp-lg); font-size: 0.82rem; }
.list-count { color: var(--text-secondary); font-size: 0.88rem; margin: var(--sp-md) 0 var(--sp-sm); }

.filters { display: flex; flex-wrap: wrap; gap: var(--sp-md); margin-top: var(--sp-lg); }
.field { display: flex; flex-direction: column; gap: var(--sp-xs); min-width: 0; flex: 1 1 10rem; }
.field-label { color: var(--text-secondary); font-size: 0.82rem; font-weight: 500; }
select, input[type="time"] {
  font: inherit; font-size: 1rem; color: var(--text-primary); background: var(--bg-surface);
  /* The border at least 3:1 against the card and the field (WCAG 1.4.11, code review C-9). */
  border: 1px solid var(--accent-slate); border-radius: var(--r-sm); padding: 0.55rem 0.6rem;
  min-height: 44px; width: 100%; max-width: 100%; color-scheme: dark;
}
/* A select cannot wrap its chosen option, so at a narrow width with large text it would cut it off
   ("Before gre", verifier item K-2, 2026-10-16). Each field is a container, and each select's text
   shrinks only as far as its longest option needs to fit: (field width less the borders and the
   20px Chromium keeps for the arrow) over (the longest option in em, plus the padding in em). At
   ordinary sizes the min() keeps 1rem, so nothing changes there; where container units are unknown
   the declaration is dropped and the select keeps 1rem. */
.field { container-type: inline-size; }
select { padding-left: 0.6em; padding-right: 0.6em; }
#filter-kind { font-size: min(1rem, calc((100cqi - 22px) / 8.35)); }
#filter-type { font-size: min(1rem, calc((100cqi - 22px) / 6.3)); }
.alarm-choice { font-size: min(1rem, calc((100cqi - 22px) / 13)); }
.alarm-minutes { font-size: min(1rem, calc((100cqi - 22px) / 9.85)); }
/* The When field starts wide enough for "On the day of the eclipse" at 16px, beside the time. */
.alarm-fieldset .field:not(.alarm-time-field):not(.alarm-minutes-field) { flex-basis: 14rem; }

.eclipse-list { display: flex; flex-direction: column; gap: var(--sp-sm); }
.year-group { border: 1px solid var(--border); border-radius: var(--r-md); background: rgba(255, 255, 255, 0.02); }
.year-summary {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; column-gap: var(--sp-md);
  padding: var(--sp-md); cursor: pointer; list-style: none; min-height: 44px; border-radius: var(--r-md);
}
.year-summary::-webkit-details-marker { display: none; }
/* The triangle is decoration: the empty alternative text keeps it out of the year's accessible name
   (code review C-10); browsers without the alternative syntax use the first line. */
.year-summary::before { content: '\25B8'; content: '\25B8' / ''; color: var(--text-muted); margin-right: var(--sp-sm); transition: transform var(--t-fast); }
.year-group[open] > .year-summary::before { transform: rotate(90deg); }
.year-title { font-size: 1.1rem; flex: 1; }
.year-count { color: var(--text-secondary); font-size: 0.85rem; }
.eclipse-items { list-style: none; padding: 0 var(--sp-md) var(--sp-md); display: flex; flex-direction: column; gap: var(--sp-sm); }
.eclipse-item { border-top: 1px solid var(--border); padding-top: var(--sp-md); display: flex; flex-direction: column; gap: 0.15rem; }
.eclipse-head { display: flex; align-items: center; gap: var(--sp-sm); flex-wrap: wrap; }
.eclipse-name { font-size: 1rem; }
.badge { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; padding: 0.1rem 0.5rem; border-radius: var(--r-full); border: 1px solid var(--border-active); }
.badge-solar { color: #f8f8f8; }
.badge-lunar { color: var(--accent-blue); border-color: rgba(130, 170, 255, 0.4); }
.eclipse-when { font-weight: 600; font-variant-numeric: tabular-nums; }
.eclipse-region, .eclipse-path, .eclipse-mag { color: var(--text-secondary); font-size: 0.9rem; overflow-wrap: anywhere; }
.btn-alarm { align-self: flex-start; margin-top: var(--sp-sm); padding: 0.5rem 1rem; min-height: 44px; background: transparent; color: var(--text-primary); border: 1px solid var(--border-active); }
.btn-alarm:hover { background: var(--bg-card-hover); }

.planner {
  width: min(560px, calc(100vw - 2rem)); max-height: calc(100dvh - 2rem); margin: auto; padding: 0;
  color: var(--text-primary); background: #0e0e13; border: 1px solid var(--border-active);
  border-radius: var(--r-lg); box-shadow: var(--shadow-card); overflow: auto;
}
.planner::backdrop { background: rgba(0, 0, 0, 0.7); }
.planner-inner { padding: var(--sp-lg); display: flex; flex-direction: column; gap: var(--sp-md); }
.planner-title { font-size: 1.25rem; }
.planner-when { font-weight: 600; }
.planner-zone, .planner-note { color: var(--text-secondary); font-size: 0.88rem; }
.alarm-rows { list-style: none; display: flex; flex-direction: column; gap: var(--sp-md); padding: 0; }
.alarm-fieldset { border: 1px solid var(--border); border-radius: var(--r-md); padding: var(--sp-md); display: flex; flex-wrap: wrap; gap: var(--sp-md); min-width: 0; }
.alarm-legend { padding: 0 var(--sp-xs); color: var(--text-secondary); font-size: 0.85rem; font-weight: 600; }
.alarm-result { flex-basis: 100%; font-size: 0.92rem; }
.alarm-result.is-warning { color: #ffd58a; }
.btn-remove { padding: 0.4rem 0.9rem; min-height: 44px; background: transparent; color: var(--text-secondary); border: 1px solid var(--border); }
.btn-remove:hover { color: var(--text-primary); }
.planner-status { min-height: 1.4em; font-size: 0.92rem; color: var(--text-secondary); }
.planner-three { font-size: 0.92rem; color: #ffd58a; }
.list-heading:focus { outline: none; }
.list-heading:focus-visible { outline: 2px solid var(--accent-blue); outline-offset: 2px; }
.planner-actions { display: flex; flex-wrap: wrap; gap: var(--sp-sm); }
.planner-actions .btn, #add-alarm { min-height: 44px; }
#add-alarm { align-self: flex-start; }

@media (max-width: 420px) {
  /* The side paddings stop growing with the text size (the min() with px), so large text keeps
     the room it needs on a narrow screen (K-2); at 100% text they are exactly what they were. */
  .main-content { padding-left: min(var(--sp-md), 16px); padding-right: min(var(--sp-md), 16px); }
  .card { padding: var(--sp-lg) min(var(--sp-md), 16px); }
  .event-row { flex-direction: column; align-items: flex-start; gap: 0; }
  .event-value { text-align: left; }
  /* The browser's own limit on a modal dialog is 100% less 6px and 2em, so it too is capped in px. */
  .planner { width: calc(100vw - min(1rem, 16px)); max-width: calc(100% - 6px - min(2em, 32px)); max-height: calc(100dvh - 1rem); }
  .planner-inner { padding: var(--sp-md) min(var(--sp-sm), 8px); }
  .alarm-fieldset { padding: var(--sp-sm) min(var(--sp-sm), 8px); }
  select, input[type="time"] { padding: 0.5rem 0.4rem; }
  select { padding-left: 0.4em; padding-right: 0.4em; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .logo-icon { animation: none; }
  .year-summary::before { transition: none; }
  .btn-primary:hover { transform: none; }
}

/* ---- App switcher carousel ---------------------------------------- */
/* Stormberry chrome, the MetadataScrubber design (2026-10). The track
   holds 10 identical sets of cards and slides by exactly one set
   (-10%), so the loop is seamless. Change the number of sets and the
   shift together. The page's own app is the last card of each set. */
.app-switcher-container {
  padding: 3rem 0;
  margin-top: 2rem;
  text-align: center;
  border-top: 1px solid var(--border);
  line-height: 1.6;
  color-scheme: dark;
}

.switcher-title {
  margin: 0 0 1.5rem;
  padding: 0 1rem;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.5px;
  color: var(--text-secondary);
}

.app-switcher-marquee {
  display: flex;
  width: 100%;
  overflow: hidden;
  padding: 0.5rem 1rem 1.5rem;
}

.app-switcher-track {
  display: flex;
  width: max-content;
  animation: marquee 32s linear infinite;
}

.app-switcher-marquee:hover .app-switcher-track,
.app-switcher-marquee:focus-within .app-switcher-track { animation-play-state: paused; }

@keyframes marquee {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-10%); }
}

.switcher-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-shrink: 0;
  margin-right: 1rem;
  padding: 1rem 1.5rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--text-primary);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 0.2s, background 0.2s, box-shadow 0.2s;
}

.switcher-card:hover {
  transform: translateY(-3px);
  background: var(--bg-card-hover);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
  color: var(--text-primary);
}

.switcher-card img {
  width: 32px;
  height: 32px;
  opacity: 0.9;
}

/* A visible focus ring on the dark chrome, whatever the page does elsewhere */
.app-switcher-container a:focus-visible,
.site-footer a:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}

/* ---- Carousel and footer access (2026-10-10) ---------------------- */
/* The page's own app, the last card of every set, is marked for screen
   readers (aria-current) and for the eye (an accent border). */
.switcher-card[aria-current="page"] { border-color: var(--accent-blue); }

/* Rounded focus ring, whatever corner radius the page's own ring uses */
.switcher-card:focus-visible { border-radius: 12px; }

/* Keyboard focus stops the slide and the row scrolls to the focused card,
   so it is never off-screen. :focus-visible and not :focus-within, so a
   mouse click does not move the card from under the pointer. */
.app-switcher-marquee:has(.switcher-card:focus-visible) { overflow-x: auto; }
.app-switcher-marquee:has(.switcher-card:focus-visible) .app-switcher-track { animation: none; }

/* The pause tick box (WCAG 2.2.2): ticked, the slide stops and the row
   scrolls by hand. Plain CSS, no script. `all: revert` keeps the page's
   own form styles off it. */
.app-switcher-container input.switcher-pause {
  all: revert;
  margin: 0 0.5rem 0.75rem 0;
  vertical-align: middle;
  accent-color: var(--accent-blue);
  cursor: pointer;
}

.app-switcher-container label.switcher-pause-label {
  all: revert;
  display: inline-block;
  margin-bottom: 0.75rem;
  vertical-align: middle;
  color: var(--text-secondary);
  font-size: 0.85rem;
  cursor: pointer;
}

.app-switcher-container input.switcher-pause:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}

.switcher-pause:checked ~ .app-switcher-marquee { overflow-x: auto; }
.switcher-pause:checked ~ .app-switcher-marquee .app-switcher-track { animation: none; }

/* A footer link never breaks inside itself (the org.nr. did at 320 px) */
.footer-bottom p a { white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  /* Nothing slides, so there is nothing to pause. */
  .app-switcher-container input.switcher-pause,
  .app-switcher-container label.switcher-pause-label { display: none; }
}

/* ---- Footer -------------------------------------------------------- */
.site-footer {
  margin-top: auto;
  padding: 4rem 1.5rem 2rem;
  background: var(--bg-base);
  border-top: 1px solid var(--border);
  line-height: 1.6;
}

.site-footer p { margin: 0; }

.footer-inner {
  max-width: 680px;
  margin: 0 auto 3rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2rem;
}

.footer-brand { max-width: 320px; }

.footer-logo {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-family: inherit;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-primary);
  text-decoration: none;
}

.footer-logo:hover { color: var(--text-primary); }
.footer-dot { background: linear-gradient(135deg, #ffffff, #888888); -webkit-background-clip: text; background-clip: text; color: transparent; }

.footer-tagline {
  color: var(--text-secondary);
  font-size: 0.95rem;
  line-height: 1.5;
}

.footer-powered p {
  max-width: 250px;
  color: var(--text-secondary);
  font-size: 0.88rem;
  line-height: 1.6;
}

/* Credit links read as links, as the legal links do */
.footer-powered a,
.footer-bottom p a {
  color: var(--accent-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 150ms ease;
}

.footer-powered a:hover,
.footer-bottom p a:hover { color: var(--text-primary); }

.footer-bottom {
  max-width: 680px;
  margin: 0 auto;
  padding-top: 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  text-align: center;
}

.footer-social { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.25rem; }
.footer-social a { color: var(--text-secondary); transition: color 150ms ease, transform 150ms ease; }
.footer-social a:hover { color: var(--text-primary); transform: translateY(-2px); }
.footer-social svg { display: block; }

.footer-bottom p { color: var(--text-secondary); font-size: 0.85rem; }

/* The public test of an app's privacy claim, where it makes one */
.footer-bottom .footer-offline {
  color: var(--text-secondary);
  font-size: 0.9rem;
  font-weight: 600;
}

.footer-privacy, .footer-ai { opacity: 0.85; }

@media (min-width: 720px) {
  .switcher-title { padding: 0 2rem; }
  .app-switcher-marquee { padding: 0.5rem 2rem 1.5rem; }
  .footer-powered p { text-align: right; }
}

@media (prefers-reduced-motion: reduce) {
  /* No sliding: the carousel becomes a row the reader scrolls. */
  .app-switcher-track { animation: none; }
  .app-switcher-marquee { overflow-x: auto; }
  .switcher-card,
  .footer-social a { transition: none; }
  .switcher-card:hover,
  .footer-social a:hover { transform: none; }
}
