/* =========================================================
   Tokens
   ========================================================= */
:root {
  --bg: #f5f5f5;          /* page background */
  --bubble: #ebebeb;      /* chat bubbles */
  --bubble-dark: #1c1c1e; /* spotify card */
  --text: #111;
  --muted: #8a8a8a;
  --green: #1ed760;
  --divider: rgba(0, 0, 0, 0.08);

  /* Tell the UA we support both schemes so native UI (scrollbars, form
     controls, default fonts) auto-switches alongside our custom palette. */
  color-scheme: light dark;
}

/* =========================================================
   Reset
   ========================================================= */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; }
img, svg { display: block; }

/* =========================================================
   Page
   ========================================================= */
body {
  background: var(--bg);
  color: var(--text);
  font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "SF Pro Text",
               "Segoe UI", "Helvetica Neue", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  display: grid;
  place-items: center;
  padding: 80px 24px 144px;
  /* Respect notches / home-indicator on mobile */
  padding-left:  max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
}

main.chat {
  width: 100%;
  max-width: 540px;
  display: flex;
  flex-direction: column;
  /* Default tight spacing for stacked bubbles in the same cluster */
  gap: 4px;
  /* Ensures the chat can shrink fully inside narrow viewports */
  min-width: 0;
}

/* =========================================================
   Bubble row
   - Avatar (or placeholder) + bubble, baseline-aligned to the bubble bottom
   - The avatar and bubble are individually hidden until animateIntro() in
     index.js fades them in. The avatar leads the bubble by a few ms so the
     row reads as "person → message" rather than appearing all at once.
   ========================================================= */
.row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}

.row .avatar,
.row .bubble { opacity: 0; }   /* JS animates to 1 */

/* Cluster boundary — adds extra spacing above to separate groups */
.row.cluster { margin-top: 10px; }

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-bottom: 4px;
  background: #ddd;
  object-fit: cover;
}

/* Reserves the avatar slot so grouped bubbles align with avatar'd ones — must match .avatar width */
.avatar-placeholder {
  width: 36px;
  flex-shrink: 0;
}

/* =========================================================
   Bubble
   ========================================================= */
.bubble {
  background: var(--bubble);
  border-radius: 20px;
  padding: 10px 16px;
  max-width: 460px;
  /* Allow long words / URLs to break instead of forcing horizontal scroll */
  overflow-wrap: anywhere;
  min-width: 0;
}

.bubble em {
  font-family: "Cantata One", "Iowan Old Style", "Hoefler Text", Georgia, "Times New Roman", serif;
  font-style: normal;
  font-weight: 600;
}

.bubble a {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

.brand-icon {
  display: inline-block;
  vertical-align: -1px;
  margin-left: 2px;
}

/* Small inline brand logos (e.g., Plany, Sabora) — original colors preserved */
.brand-logo {
  display: inline-block;
  width: 20px;
  height: 20px;
  padding: 1px;
  margin-right: 2px;
  vertical-align: -3px;
  object-fit: contain;
}

/* =========================================================
   Articles bubble
   ========================================================= */
.bubble.articles { cursor: default; }

.articles-header {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.articles-header p { flex: 1; }

.eye {
  display: inline-flex;
  align-items: flex-start;
  color: rgba(0, 0, 0, 0.55);
  margin-top: 2px;
  flex-shrink: 0;
}

/* Outer collapsing element — height/opacity are animated by JS */
.articles-list {
  height: 0;
  opacity: 0;
  overflow: hidden;
}

/* Inner element holds spacing/border so they reveal smoothly with the height */
.articles-list-inner {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.articles-list article h3 {
  font-family: "Cantata One", "Iowan Old Style", "Hoefler Text", Georgia, "Times New Roman", serif;
  font-style: normal;
  font-weight: 400;
  font-size: 16px;
  margin-bottom: 2px;
}

.articles-list article p {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.4;
}

/* =========================================================
   Music (Spotify-style) widget
   - Lives inside a "framed" bubble that gives it a small light border
   ========================================================= */
.bubble-frame { padding: 6px; }

.spotify {
  display: flex;
  align-items: stretch;
  background: var(--bubble-dark);
  color: #fff;
  border-radius: 14px;
  padding: 0;
  overflow: hidden;
  /* Fluid up to 340px so it never overflows narrow bubbles on mobile */
  width: 100%;
  min-width: 225px;
  max-width: 340px;
  text-align: left;
}

/* States — only one is visible at a time, driven by data-state on .spotify.
   "playing" / "paused" both reveal .state-track; the difference is conveyed
   by the equalizer vs. "Paused" label inside the right-stack. */
.state {
  display: none;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 12px 8px 8px;
}

.spotify[data-state="playing"] .state-track,
.spotify[data-state="paused"]  .state-track { display: flex; }
.spotify[data-state="idle"]    .state-idle  { display: flex; }
.spotify[data-state="login"]   .state-login { display: flex; }

.state-idle, .state-login { padding: 12px 14px; }

.album-art {
  width: 44px;
  height: 44px;
  /* Squircle — ~27% of the side, close to iOS app-icon curvature */
  border-radius: 12px;
  flex-shrink: 0;
  object-fit: cover;
  background: #2a2a2a;
}

.track {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}

.track-title {
  font-size: 15px;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-artist {
  font-size: 14px;
  font-weight: 500;
  color: #9a9a9a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.right-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.spotify-logo { display: inline-flex; line-height: 0; }

/* Equalizer bars — heights are animated by JS each frame */
.equalizer {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
}

.equalizer span {
  display: block;
  width: 3px;
  height: 3px;
  background: var(--green);
  /* Fully rounded ends — pill shape regardless of height */
  border-radius: 999px;
}

/* Static "Paused" indicator — sits where the equalizer normally goes. The
   two are mutually exclusive based on data-state. */
.paused-label {
  display: none;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green);
  line-height: 1;
}
.spotify[data-state="paused"] .equalizer    { display: none; }
.spotify[data-state="paused"] .paused-label { display: inline-block; }

/* =========================================================
   Book widget — cover + title + author
   ========================================================= */
.bubble-book { padding: 12px 12px; }

.book {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.book-cover {
  width: 92px;
  height: 128px;
  border-radius: 10px;
  flex-shrink: 0;
  object-fit: cover;
  background: #ddd;
  /* Subtle drop-shadow gives the cover a sense of physical depth */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

.book-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.book-title {
  font-family: "Cantata One", "Iowan Old Style", "Hoefler Text", Georgia, "Times New Roman", serif;
  font-style: normal;
  font-size: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.book-author {
  font-size: 14px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* =========================================================
   Responsive — layered breakpoints
   ========================================================= */

/* Tablet / small laptop */
@media (max-width: 720px) {
  body { padding: 56px 20px; }
}

/* Phones */
@media (max-width: 480px) {
  body {
    padding-top: 32px;
    padding-bottom: 32px;
    padding-left:  max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
    font-size: 15px;
    line-height: 1.45;
  }
  .bubble { padding: 9px 14px; border-radius: 18px; }
  .row.cluster { margin-top: 8px; }
  .articles-list-inner { gap: 12px; }
  .articles-list article h3 { font-size: 15px; }
  .articles-list article p  { font-size: 13.5px; }
  .track-title { font-size: 14.5px; }
  .track-artist { font-size: 12.5px; }
}

/* Very small phones (iPhone SE 1st gen / 320px etc.) */
@media (max-width: 360px) {
  body { padding-top: 24px; padding-bottom: 24px; }
  .avatar,
  .avatar-placeholder { width: 22px; }
  .avatar { height: 22px; }
  .row { gap: 6px; }
  .bubble { padding: 8px 12px; border-radius: 16px; }
  .album-art { width: 38px; height: 38px; border-radius: 10px; }
  .state-track { padding: 7px 10px 7px 7px; gap: 10px; }
  .state-idle, .state-login { padding: 10px 12px; }
}

/* =========================================================
   Dark mode
   - Auto-applied when the user's OS is set to dark; light is
     the default and there's no in-page toggle.
   - prefers-color-scheme is supported on Chrome 76+, Firefox 67+,
     Safari 12.1+, iOS Safari 13+, Edge 79+, Android Chrome 76+.
     Browsers that don't recognize it just keep the light styles.
   - The .spotify card keeps its existing --bubble-dark value; the
     surrounding bubble-frame (--bubble, lightened in dark mode)
     provides the visual edge instead of a darker card.
   ========================================================= */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1A1A1A;
    --bubble: #2c2c2e;       /* iMessage-style: a touch lighter than bg */
    --bubble-dark: #1c1c1e;  /* unchanged — bubble-frame around it provides separation */
    --text: #f2f2f2;
    --muted: #8e8e93;
    --divider: rgba(255, 255, 255, 0.09);
  }

  /* Avatar / book-cover fallback backgrounds — the hardcoded #ddd would
     flash a light circle/rect against the dark page if the image is
     missing, transparent, or still loading. */
  .avatar { background: #2a2a2a; }
  .book-cover {
    background: #2a2a2a;
    /* Original 0.18-alpha shadow disappears on dark bg; deepen for depth */
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  }

  /* Eye toggle icon — same subtle alpha treatment, flipped to white */
  .eye { color: rgba(255, 255, 255, 0.55); }
}
