:root {
  --bg: #fffdf6;
  --ink: #1a0b05;
  --brown: #7a3518;
  --cream: #fffdf6;
  --chip-bg: #f5eae6;
  --border: #dedcd1;
  --muted: #998279;
  --footer-muted: #87867f;

  --op: #7acc29; /* operational */
  --minor: #ffcf33;
  --major: #ff7033;
  --down: #ff3333;
  --none: #998279;

  --font: -apple-system, "SF Pro", system-ui, "Segoe UI", sans-serif;
  --col: 850px;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.page {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  padding: 70px 20px;
}

.column {
  width: 100%;
  max-width: var(--col);
  display: flex;
  flex-direction: column;
}

/* ---------- Top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Tightened from Figma's 60px; 24px above the card still applies (see #content). */
  margin-bottom: 28px;
}

/* 24px above the card block (matches the Figma card-wrapper padding-top). */
#content {
  padding-top: 24px;
}

.brand {
  display: inline-flex;
  text-decoration: none;
  line-height: 0;
}

.brand-logo {
  display: block;
  height: 28px;
  width: auto;
}

.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--chip-bg);
  color: var(--brown);
  padding: 6px;
  border-radius: 10px;
  font-size: 17px;
  line-height: 1;
  min-width: 30px;
  min-height: 30px;
}

/* ---------- Overall banner ---------- */
.banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
  min-height: 30px;
}

.banner-dot {
  width: 14px;
  height: 14px;
  border-radius: 1000px;
  flex: 0 0 auto;
  box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 18%, transparent);
}

.banner-label {
  font-size: 22px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}

/* ---------- Card ---------- */
.card {
  border: 1px solid var(--border);
  border-radius: 20px;
  background: transparent;
  overflow: hidden;
}

.row {
  padding: 18px 20px 14px;
  border-top: 1px solid var(--border);
}

.row:first-child {
  border-top: none;
}

.row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.row-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15.9px;
  font-weight: 510;
  color: var(--ink);
  letter-spacing: -0.005em;
  cursor: default;
  /* Titles never wrap — WebKit otherwise breaks "Heart Rate" onto two lines
     on phones even with free space in the row head. */
  white-space: nowrap;
}

/* Fixed slot so titles left-align; each icon renders in an explicit 26x17 box
   and the viewBox letterboxes the glyph (preserveAspectRatio), so wide icons
   (bed, shoe) and tall icons (heart) read as one optical size. Explicit
   dimensions, not auto + max-*: WebKit/iOS resolves the auto pair to 0x0 and
   the icons vanish on iPhones. */
.row-icon {
  flex: 0 0 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  overflow: visible;
}

.row-icon svg {
  width: 26px;
  height: 17px;
  display: block;
  overflow: visible;
}

/* The bed's z's live above its cropped viewBox — let them show on hover. */
.bed-icon {
  overflow: visible;
}

/* The z's are hidden until the Sleep title/icon is hovered, then swirl upward
   in a staggered loop, like the SF Symbols sleep glyph. */
.bed-icon .z {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}
.row-sleep .row-name:hover .bed-icon .z {
  animation: zswirl 1.8s ease-in-out infinite;
}
.row-sleep .row-name:hover .bed-icon .zb {
  animation-delay: 0.36s;
}
.row-sleep .row-name:hover .bed-icon .zc {
  animation-delay: 0.72s;
}

/* Heart icon pulses (lub-dub) while the Heart Rate title/icon is hovered,
   timed to the ~0.95s heartbeat audio loop. */
.heart-icon {
  transform-origin: center;
}
/* 0.98s = exact length of one heartbeat.mp3 cycle; both the audio loop and this
   animation start on hover, so the lub/dub peaks land on the recorded beats
   (lub onset ~26.5%, dub onset ~62%). */
.row-heart .row-name:hover .heart-icon {
  animation: heartpulse 0.98s ease-out infinite;
}

@keyframes heartpulse {
  0% {
    transform: scale(1);
  }
  26% {
    transform: scale(1);
  }
  31% {
    transform: scale(1.28);
  } /* LUB */
  42% {
    transform: scale(1);
  }
  62% {
    transform: scale(1);
  }
  67% {
    transform: scale(1.17);
  } /* DUB */
  78% {
    transform: scale(1);
  }
  100% {
    transform: scale(1);
  }
}

/* Discord logo does a full clockwise spin on hover: slow wind-up, fast
   middle (swelling to ~1.2x at peak speed), then a damped landing with a
   tiny overshoot wobble. Short holds at rest, repeat while hovered. */
.discord-icon {
  transform-origin: center;
}
.row-discord .row-name:hover .discord-icon {
  animation: discordspin 1.1s ease-in-out infinite;
}

@keyframes discordspin {
  0%,
  8% {
    transform: rotate(0deg) scale(1);
  }
  20% {
    transform: rotate(15deg) scale(1.04);
  }
  33% {
    transform: rotate(45deg) scale(1.12);
  }
  42% {
    transform: rotate(135deg) scale(1.2);
  }
  50% {
    transform: rotate(230deg) scale(1.22);
  }
  57% {
    transform: rotate(315deg) scale(1.14);
  }
  64% {
    transform: rotate(348deg) scale(1.06);
  }
  72% {
    transform: rotate(358deg) scale(1.02);
  }
  80% {
    transform: rotate(363deg) scale(1);
  }
  88%,
  100% {
    transform: rotate(360deg) scale(1);
  }
}

/* Swirl: each z fades in, drifts up while curving side to side and rotating,
   then fades out — a gentle rising swirl rather than a straight float. */
@keyframes zswirl {
  0% {
    opacity: 0;
    transform: translate(0, 55%) rotate(-12deg) scale(0.5);
  }
  20% {
    opacity: 1;
    transform: translate(-22%, 5%) rotate(6deg) scale(1);
  }
  55% {
    opacity: 1;
    transform: translate(18%, -45%) rotate(-6deg) scale(1.05);
  }
  100% {
    opacity: 0;
    transform: translate(-10%, -105%) rotate(8deg) scale(1.18);
  }
}

.row-status {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
}

/* ---------- 90-day bar ---------- */
.bar {
  display: flex;
  align-items: stretch;
  gap: 2px;
  height: 34px;
  margin-bottom: 10px;
}

.day {
  flex: 1 1 0;
  min-width: 2px;
  height: 34px;
  border-radius: 1000px;
  background: var(--none);
  transition: opacity 0.12s ease;
}

.day:hover {
  opacity: 0.7;
}

.subline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: var(--muted);
}

.subline-mid {
  color: color-mix(in srgb, var(--muted) 80%, var(--bg));
}

/* "30 days ago" variant of the range label — shown only on phones, where the
   bar is trimmed to the last 30 days (see the 640px media query). */
.range-short {
  display: none;
}

/* ---------- Status colors ---------- */
.lvl-operational {
  background: var(--op);
}
.lvl-minor {
  background: var(--minor);
}
.lvl-major {
  background: var(--major);
}
.lvl-down {
  background: var(--down);
}
.lvl-none {
  background: var(--none);
}

.txt-operational {
  color: var(--op);
}
.txt-minor {
  color: var(--minor);
}
.txt-major {
  color: var(--major);
}
.txt-down {
  color: var(--down);
}
.txt-none {
  color: var(--none);
}

.dot-operational {
  background: var(--op);
  color: var(--op);
}
.dot-minor {
  background: var(--minor);
  color: var(--minor);
}
.dot-major {
  background: var(--major);
  color: var(--major);
}
.dot-down {
  background: var(--down);
  color: var(--down);
}
.dot-none {
  background: var(--none);
  color: var(--none);
}

/* ---------- Connect screen ---------- */
.connect {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 80px 20px 90px;
}

.connect-title {
  font-size: 30px;
  font-weight: 640;
  color: var(--ink);
  letter-spacing: -0.02em;
  margin: 0;
}

.connect-sub {
  font-size: 16px;
  color: var(--muted);
  margin: 0;
}

.connect-btn {
  margin-top: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--brown);
  color: var(--cream);
  font-family: var(--font);
  font-size: 15.5px;
  font-weight: 560;
  text-decoration: none;
  padding: 12px 26px;
  border-radius: 1000px;
  border: none;
  cursor: pointer;
  transition:
    transform 0.12s ease,
    background 0.18s ease;
}

.connect-btn:hover {
  background: #682c13;
  transform: translateY(-1px);
}

.connect-btn:active {
  transform: translateY(0) scale(0.97);
}

/* ---------- Error ---------- */
.error-state {
  padding: 60px 20px;
  text-align: center;
  font-size: 14px;
  color: var(--muted);
}

/* ---------- Footer ---------- */
.footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 30px;
  padding-top: 11px;
  border-top: 1px solid var(--border);
  font-size: 13.9px;
  color: var(--footer-muted);
}

/* ---------- Skeleton ---------- */
.skel {
  display: inline-block;
  background: linear-gradient(90deg, #f0ece2 25%, #e7e2d6 37%, #f0ece2 63%);
  background-size: 400% 100%;
  border-radius: 6px;
  animation: shimmer 1.4s ease infinite;
}

.skel-dot {
  width: 14px;
  height: 14px;
  border-radius: 1000px;
}
.skel-line {
  width: 280px;
  height: 20px;
}
.skel-pill {
  width: 120px;
  height: 16px;
}
.skel-status {
  width: 80px;
  height: 14px;
}

.bar--skeleton {
  background: linear-gradient(90deg, #f0ece2 25%, #e7e2d6 37%, #f0ece2 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: 6px;
}

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

/* ---------- Entrance animation ---------- */
.enter {
  animation: enterUp 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

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

/* ---------- Responsive ---------- */
@media (max-width: 880px) {
  .page {
    padding: 48px 20px;
  }
  .skel-line {
    width: 60%;
  }
  .day {
    min-width: 1px;
  }
}

/* Phones: 90 segments compress into unreadable ~1px hairlines — show the
   last 30 days as chunky pills instead (desktop-sized), and swap the range
   label to match. */
@media (max-width: 640px) {
  .bar .day:nth-child(-n + 60) {
    display: none;
  }
  .range-full {
    display: none;
  }
  .range-short {
    display: inline;
  }
}

/* Very narrow phones: long titles ("X (Twitter) Activity") truncate with an
   ellipsis instead of pushing the status label out of the card. The name
   grows into all free space (not space-between shrink negotiation — WebKit
   over-shrinks and truncates titles that have room), so the ellipsis only
   appears when space genuinely runs out. */
@media (max-width: 360px) {
  .row-name {
    flex: 1 1 auto;
    min-width: 0;
  }
  .row-name > span:not(.row-icon) {
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .row-status {
    flex: 0 0 auto;
  }
}

@media (max-width: 520px) {
  .banner-label {
    font-size: 19px;
  }
  .subline {
    font-size: 12.5px;
  }
  .bar,
  .day {
    height: 30px;
  }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .enter,
  .skel,
  .bar--skeleton {
    animation: none;
  }
  .connect-btn,
  .day {
    transition: none;
  }
  .row-sleep .row-name:hover .bed-icon .z,
  .row-heart .row-name:hover .heart-icon,
  .row-discord .row-name:hover .discord-icon {
    animation: none;
  }
  .enter {
    opacity: 1;
    transform: none;
  }
  .tip {
    transition: none;
  }
}

/* ---------- Day tooltip (light) ---------- */
.tip {
  position: fixed;
  z-index: 50;
  top: 0;
  left: 0;
  min-width: 184px;
  max-width: 260px;
  padding: 10px 12px;
  background: #fffefa;
  color: var(--ink);
  border: 1px solid #e7e1d4;
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(77, 33, 15, 0.16);
  font-size: 12.5px;
  line-height: 1.35;
  pointer-events: none;
  opacity: 0;
  transform: translateY(2px);
  transition:
    opacity 0.12s ease,
    transform 0.12s ease;
}
.tip.show {
  opacity: 1;
  transform: translateY(0);
}
.tip-head {
  display: flex;
  align-items: center;
  gap: 7px;
}
.tip-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 8px;
}
.tip-name {
  font-weight: 600;
}
.tip-status {
  margin-left: auto;
  font-size: 11.5px;
  color: var(--muted);
}
.tip-date {
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
}
.tip-summary {
  margin-top: 6px;
  font-weight: 500;
}
.tip-metrics {
  list-style: none;
  margin: 7px 0 0;
  padding: 7px 0 0;
  border-top: 1px solid #efe9dd;
}
.tip-metrics li {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 1.5px 0;
}
.tip-metrics li span:first-child {
  color: var(--muted);
}
.tip-metrics li span:last-child {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
