/* styles.css — Skycard demo weather app */

:root {
  --page-bg: #ece8f8;
  --page-bg-2: #dcd6f2;
  --card-w: 380px;
  --card-radius: 24px;
  --card-grad-1: #2b2350;
  --card-grad-2: #3a2d6b;
  --card-grad-3: #4a3a82;
  --text-hero: #f5f2ff;
  --text-soft: #cfc7ee;
  --text-dim: #a89fd0;
  --chip-bg: rgba(255, 255, 255, 0.08);
  --chip-border: rgba(255, 255, 255, 0.14);
  --strip-bg: rgba(15, 10, 35, 0.32);
  --pill-bg: rgba(255, 255, 255, 0.16);
  --accent: #ffd35c;
  --shadow-color: rgba(58, 40, 110, 0.45);
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --page-bg: #0b0912;
    --page-bg-2: #15101f;
  }
}

* {
  box-sizing: border-box;
}

html {
  /* min-height, not height (2026-09-06): with html/body at height:100% the
     body's radial gradient tiled at exactly one viewport height, so a tall
     page showed a hard horizontal seam where the second tile began. Let the
     root grow with the content, paint the gradient once, and back it with
     the gradient's own end colour so nothing can ever show a seam. */
  min-height: 100%;
  background: var(--page-bg);
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  /* Column flex + auto main-axis margins on .card (2026-09-06): a flex-
     centred child taller than the viewport overflows ABOVE the top edge
     where it can't be scrolled to (the Lunar card's search row + hero were
     clipped under the topbar on load). Main-axis auto margins centre the
     card when there is room and pin it to the top when there isn't. They
     must be MAIN-axis margins: cross-axis auto margins do nothing here
     because a min-height body has no definite cross size. */
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 32px 16px;
  font-family: var(--font-sans);
  background: radial-gradient(circle at 30% 20%, var(--page-bg-2), var(--page-bg) 70%);
  background-repeat: no-repeat;
  color: var(--text-hero);
}

.page-wrap {
  /* The flex item of the column-flex body (2026-09-06): main-axis auto
     margins centre the card when it fits the viewport and pin it to the
     top (below the fixed topbar) when it is taller, instead of
     align-items:center pushing its top off-screen. */
  margin-top: auto;
  margin-bottom: auto;
  width: 100%;
  max-width: var(--card-w);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.gallery-link {
  align-self: flex-start;
  font-size: 12.5px;
  color: var(--text-dim);
  text-decoration: none;
  font-family: var(--font-sans);
  padding: 4px 2px;
}

.gallery-link:hover,
.gallery-link:focus-visible {
  color: var(--text-hero);
}

#app {
  width: 100%;
}

/* ---------------------------------------------------------------------- */
/* Card                                                                    */
/* ---------------------------------------------------------------------- */

.card {
  position: relative;
  /* Its own stacking context (2026-09-06): keeps every effect the card
     draws — glow, blur, gradients — unambiguously below the fixed
     .topbar's z-index:30, whatever effects a future addition to the card
     brings in. overflow:hidden already clips the card's own content to its
     box; this is the belt to that braces. */
  isolation: isolate;
  width: 100%;
  min-height: 560px;
  border-radius: var(--card-radius);
  overflow: hidden;
  padding: 20px 20px 16px;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(160deg, var(--card-grad-3) 0%, var(--card-grad-2) 45%, var(--card-grad-1) 100%);
  box-shadow:
    0 24px 60px -12px var(--shadow-color),
    0 8px 24px -8px rgba(20, 12, 45, 0.5);
  animation: cardEnter 0.4s ease-out both;
}

.card.no-enter {
  animation: none;
}

.cloud-silhouette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(ellipse 220px 90px at 15% 78%, rgba(20, 14, 46, 0.55), transparent 70%),
    radial-gradient(ellipse 260px 110px at 85% 70%, rgba(20, 14, 46, 0.5), transparent 70%),
    radial-gradient(ellipse 300px 120px at 50% 92%, rgba(15, 10, 38, 0.6), transparent 70%),
    radial-gradient(ellipse 180px 70px at 60% 60%, rgba(255, 255, 255, 0.03), transparent 70%);
}

.card > * {
  position: relative;
  z-index: 1;
}

@keyframes cardEnter {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------------------------------------------------------------------- */
/* Search row                                                              */
/* ---------------------------------------------------------------------- */

.search-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  /* Must sit above the hero (a later sibling): `.card > *` gives every child
     z-index:1, so the dropdown's own z-index was trapped underneath the hero
     icon and clicks on city options landed on the SVG instead (2026-09-05). */
  z-index: 5;
}

.search-field {
  position: relative;
  flex: 1;
  min-width: 0;
}

.search-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-dim);
  display: flex;
  pointer-events: none;
}

.search-input {
  width: 100%;
  height: 44px;
  border-radius: 22px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-hero);
  padding: 0 16px 0 42px;
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.search-input::placeholder {
  color: var(--text-dim);
}

.search-input:focus {
  background: rgba(255, 255, 255, 0.13);
  border-color: rgba(255, 255, 255, 0.28);
}

.locate-btn {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-hero);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease;
}

.locate-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}

.locate-btn:active {
  transform: scale(0.94);
}

.locate-btn.is-locating svg {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.city-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: rgba(30, 22, 58, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  box-shadow: 0 16px 40px -8px rgba(10, 6, 26, 0.6);
  max-height: 260px;
  overflow-y: auto;
  z-index: 20;
}

.city-option {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  background: none;
  border: none;
  color: var(--text-hero);
  padding: 9px 10px;
  border-radius: 10px;
  font-size: 13.5px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}

.city-option:hover,
.city-option:focus-visible {
  background: rgba(255, 255, 255, 0.1);
}

.city-name {
  font-weight: 600;
}

.city-country {
  color: var(--text-dim);
  font-size: 12px;
}

/* ---------------------------------------------------------------------- */
/* Hero                                                                     */
/* ---------------------------------------------------------------------- */

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 18px 0 6px;
  animation: heroFade 0.2s ease-out both;
}

@keyframes heroFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.hero-icon {
  width: 140px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-temp {
  font-size: 64px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-hero);
  margin-top: 4px;
  letter-spacing: -1px;
}

.hero-temp-unit {
  font-size: 26px;
  font-weight: 600;
  vertical-align: super;
  margin-left: 2px;
  color: var(--text-soft);
}

.hero-label {
  margin-top: 6px;
  font-size: 16px;
  color: var(--text-soft);
}

.hero-city {
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--text-dim);
  letter-spacing: 0.02em;
}

/* ---------------------------------------------------------------------- */
/* Moon line (ADR-0004 §4 D3) — MoonPill (demo/mould/components/MoonPill.js)  */
/* rendered inline as one truncating line; absent entirely when the API     */
/* doesn't carry moon data (feature not deployed yet, or the fetch failed). */
/* ---------------------------------------------------------------------- */

.moon-line {
  display: flex;
  justify-content: center;
  margin-top: 6px;
  max-width: 100%;
  min-width: 0;
}

.moon-line .moonpill {
  /* Skycard does not load shared.css (see index.html), so MoonPill's base
     layout is restated here — without it the glyph stacked above the text. */
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-width: 0;
}

.moon-line .moonpill-glyph {
  display: block;
  flex: none;
}

.moon-line .moonpill-text {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
}

.moon-line .moonpill-phase {
  font-size: 12px;
  color: var(--text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.moon-line .moonpill-illum {
  font-size: 12px;
  font-family: var(--font-sans);
  color: var(--text-dim);
  white-space: nowrap;
  flex: none;
}

.moon-line .moonpill-illum::before {
  content: '· ';
}

.chip-row {
  display: flex;
  gap: 10px;
  margin-top: 18px;
  width: 100%;
}

.chip {
  flex: 1;
  background: var(--chip-bg);
  border: 1px solid var(--chip-border);
  border-radius: 14px;
  padding: 8px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.chip-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.chip-value {
  font-family: var(--font-mono);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text-hero);
}

/* ---------------------------------------------------------------------- */
/* Forecast strip                                                          */
/* ---------------------------------------------------------------------- */

.forecast-strip {
  margin-top: 20px;
  display: flex;
  background: var(--strip-bg);
  border-radius: 18px;
  padding: 10px 6px;
  gap: 2px;
}

.day-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  color: var(--text-soft);
  padding: 8px 2px;
  border-radius: 14px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease;
}

.day-col:hover {
  background: rgba(255, 255, 255, 0.06);
}

.day-col.is-selected {
  background: var(--pill-bg);
}

.day-name {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-soft);
}

.day-col.is-selected .day-name {
  color: var(--text-hero);
}

.day-icon {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.day-temps {
  display: flex;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.day-max {
  color: var(--text-hero);
}

.day-min {
  color: var(--text-dim);
}

/* ---------------------------------------------------------------------- */
/* Footer                                                                   */
/* ---------------------------------------------------------------------- */

.card-footer {
  margin-top: auto;
  padding-top: 14px;
  text-align: center;
  font-size: 10.5px;
  color: var(--text-dim);
  display: flex;
  justify-content: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------------- */
/* Error card                                                              */
/* ---------------------------------------------------------------------- */

.error-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 12px;
  padding: 40px 12px;
}

.error-icon {
  font-size: 32px;
}

.error-message {
  color: var(--text-soft);
  font-size: 14px;
  max-width: 260px;
  margin: 0;
}

.btn-retry {
  background: var(--pill-bg);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--text-hero);
  padding: 10px 22px;
  border-radius: 20px;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}

.btn-retry:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* ---------------------------------------------------------------------- */
/* Skeleton                                                                 */
/* ---------------------------------------------------------------------- */

.skeleton {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 28px;
}

.skel-bar {
  border-radius: 12px;
  background: linear-gradient(90deg, rgba(255,255,255,0.06) 25%, rgba(255,255,255,0.14) 37%, rgba(255,255,255,0.06) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}

.skel-icon {
  width: 120px;
  height: 120px;
  border-radius: 50%;
}

.skel-temp {
  width: 140px;
  height: 48px;
  margin-top: 18px;
}

.skel-label {
  width: 110px;
  height: 16px;
  margin-top: 12px;
}

.skel-row {
  display: flex;
  gap: 10px;
  width: 100%;
  margin-top: 22px;
}

.skel-chip {
  flex: 1;
  height: 46px;
  border-radius: 14px;
  background: linear-gradient(90deg, rgba(255,255,255,0.06) 25%, rgba(255,255,255,0.14) 37%, rgba(255,255,255,0.06) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}

.skel-strip {
  display: flex;
  gap: 6px;
  width: 100%;
  margin-top: 24px;
}

.skel-day {
  flex: 1;
  height: 78px;
  border-radius: 14px;
  background: linear-gradient(90deg, rgba(255,255,255,0.05) 25%, rgba(255,255,255,0.12) 37%, rgba(255,255,255,0.05) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}

@keyframes shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* ---------------------------------------------------------------------- */
/* Weather icon animations                                                 */
/* ---------------------------------------------------------------------- */

.wicon {
  width: 100%;
  height: 100%;
}

.sun-rays {
  transform-origin: 50px 50px;
}

/* The sun+cloud composite's sun is off-center at (64,28) — its rays must
   spin around that point, not the icon center. */
.wicon-sun-cloud .sun-rays {
  transform-origin: 64px 28px;
}

.anim-rotate {
  animation: rotateSlow 20s linear infinite;
}

@keyframes rotateSlow {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.anim-drift {
  animation: driftCloud 6s ease-in-out infinite;
}

.anim-drift-slow {
  animation: driftCloud 9s ease-in-out infinite;
  animation-delay: -3s;
}

@keyframes driftCloud {
  0%, 100% { transform: translateX(-6px); }
  50% { transform: translateX(6px); }
}

.anim-rain-drops line,
.anim-rain-drops circle {
  animation: dropFall 1s ease-in infinite;
  animation-delay: var(--drop-delay, 0s);
  opacity: 0;
}

@keyframes dropFall {
  0% { opacity: 0; transform: translateY(0); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translateY(10px); }
}

.anim-snow-drift circle {
  animation: snowDrift 2.6s ease-in-out infinite;
  animation-delay: var(--flake-delay, 0s);
}

@keyframes snowDrift {
  0%, 100% { transform: translate(0, 0); opacity: 0.7; }
  50% { transform: translate(4px, 6px); opacity: 1; }
}

.anim-flash {
  animation: flash 2.4s ease-in-out infinite;
}

@keyframes flash {
  0%, 88%, 100% { opacity: 1; }
  92% { opacity: 0.3; }
  96% { opacity: 1; }
}

/* ---------------------------------------------------------------------- */
/* Reduced motion                                                          */
/* ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .card,
  .hero,
  .sun-rays,
  .anim-rotate,
  .anim-drift,
  .anim-drift-slow,
  .anim-rain-drops line,
  .anim-rain-drops circle,
  .anim-snow-drift circle,
  .anim-flash,
  .skel-bar,
  .skel-chip,
  .skel-day,
  .locate-btn.is-locating svg {
    animation: none !important;
  }
}

/* ---------------------------------------------------------------------- */
/* Small screens                                                           */
/* ---------------------------------------------------------------------- */

@media (max-width: 400px) {
  :root {
    --card-w: 100%;
  }
  .hero-temp {
    font-size: 54px;
  }
}
