/* ==========================================================================
   Event Countdown — "30 Apps in 30 Days"
   Design: airport departures board. Sky Solutions is a
   contractor (see the airplane mark), so a split-flap board reads as an
   on-brand signature rather than a generic dashboard template — and the
   format itself (rows, rotating boards, an arrivals-style ticker) is a
   natural fit for "many teams, no single ranking, always something new."
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@500;600;700&family=Inter:wght@400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;0,700;0,900;1,400&display=swap');

:root {
  /* ---- Color tokens ---- */
  --navy-deep: #0a0f1e;
  --navy-panel: #10182b;
  --navy-raised: #182238;
  --hairline: rgba(237, 238, 242, 0.09);
  --sky-blue: #19b2ff;
  --sky-blue-dim: #005980;
  --teal: #2fe6c4;
  --coral: #FAFAD2;
  --ink: #edeef2;
  --slate: #8592ad;
  --slate-dim: #4d5875;

  /* ---- Brand guide tokens (Sky Solutions, 2025) — used by the finale
     screen so it reads as an official brand moment rather than more
     dashboard chrome. Kept separate from the tokens above because the
     rest of the dashboard's palette is a close-but-not-identical dark
     theme built around the same sky blue; only the finale needs to match
     the guide's exact hex values. ---- */
  --brand-deep-sea-blue: #00448c;
  --brand-blue-zodiac: #122444;
  --brand-cinder: #171921;
  --brand-davy-grey: #595959;
  --brand-mid-blue: #3063b4;
  --brand-water-blue: #0086d4;
  --brand-sky-blue: #19b2ff; /* identical to --sky-blue above */
  --brand-gradient: linear-gradient(90deg, #19b2ff, #3063b4);

  /* ---- Type ---- */
  --font-board: 'IBM Plex Mono', 'SF Mono', ui-monospace, monospace;
  --font-body: 'Inter', -apple-system, 'Helvetica Neue', sans-serif;
  --font-brand: 'Roboto', -apple-system, 'Helvetica Neue', sans-serif;

  /* ---- Scale: tuned so 1920x1080 at arm's length reads clearly ---- */
  font-size: clamp(14px, 1.05vw, 22px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  background: var(--navy-deep);
  color: var(--ink);
  font-family: var(--font-body);
  overflow: hidden;
}

#app {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  padding: 1.4rem 2rem 0;
  gap: 1rem;
}

/* ---------------------------------------------------------------------- */
/* Header: logo, title, countdown                                         */
/* ---------------------------------------------------------------------- */

.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid var(--hairline);
  padding-bottom: 1rem;
}

.header__brand {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.header__logo {
  width: 2.6rem;
  height: 2.6rem;
  object-fit: contain;
  filter: drop-shadow(0 0 6px rgba(245, 185, 66, 0.35));
}

.header__titles h1 {
  margin: 0;
  font-family: var(--font-board);
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.header__titles p {
  margin: 0.15rem 0 0;
  color: var(--slate);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.countdown {
  text-align: right;
}

.countdown__label {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 0.3rem;
}

.countdown__clock {
  display: flex;
  gap: 0.5rem;
  font-family: var(--font-board);
}

.countdown__unit {
  background: var(--navy-raised);
  border: 1px solid var(--hairline);
  border-radius: 0.4rem;
  padding: 0.35rem 0.7rem;
  min-width: 3.6rem;
  text-align: center;
}

.countdown__unit .value {
  display: block;
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--sky-blue);
  line-height: 1;
}

.countdown__unit .unit {
  display: block;
  font-size: 0.55rem;
  letter-spacing: 0.12em;
  color: var(--slate);
  margin-top: 0.2rem;
}

/* ---------------------------------------------------------------------- */
/* Company progress meter                                                  */
/* ---------------------------------------------------------------------- */

.progress-meter {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.progress-meter__label {
  font-family: var(--font-board);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--ink);
}

.progress-meter__label strong {
  color: var(--sky-blue);
}

.progress-meter__track {
  flex: 1;
  height: 0.85rem;
  background: var(--navy-raised);
  border-radius: 0.5rem;
  overflow: hidden;
  border: 1px solid var(--hairline);
}

.progress-meter__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--sky-blue-dim), var(--sky-blue));
  transition: width 1.2s ease;
}

/* ---------------------------------------------------------------------- */
/* Summary strip                                                           */
/* ---------------------------------------------------------------------- */

.summary-strip {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.9rem;
}

.stat-card {
  background: var(--navy-panel);
  border: 1px solid var(--hairline);
  border-radius: 0.6rem;
  padding: 0.7rem 1rem;
}

.stat-card__value {
  font-family: var(--font-board);
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.1;
}

.stat-card__label {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: 0.2rem;
}

/* ---------------------------------------------------------------------- */
/* Spotlight (main rotating panel)                                        */
/* ---------------------------------------------------------------------- */

/* ---------------------------------------------------------------------- */
/* Main row: spotlight + side panel                                       */
/* ---------------------------------------------------------------------- */

.main-row {
  flex: 1;
  display: flex;
  gap: 1rem;
  min-height: 0;
}

.spotlight {
  flex: 3;
  background: var(--navy-panel);
  border: 1px solid var(--hairline);
  border-radius: 0.8rem;
  padding: 1.1rem 1.4rem;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
  overflow: hidden;
}

.spotlight__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.7rem;
}

.spotlight__title {
  font-family: var(--font-board);
  font-size: 1.15rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sky-blue);
}

.spotlight__dots {
  display: flex;
  gap: 0.4rem;
}

.spotlight__dots span {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--slate-dim);
}

.spotlight__dots span.active {
  background: var(--sky-blue);
}

.spotlight__rows {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.board-row {
  display: grid;
  grid-template-columns: 1.4fr 2.2fr 1fr;
  align-items: center;
  gap: 1rem;
  background: var(--navy-raised);
  border: 1px solid var(--hairline);
  border-radius: 0.5rem;
  padding: 0.6rem 0.9rem;
  animation: flap-in 0.5s ease both;
}

.board-row__team {
  min-width: 0;
}

.board-row__app {
  font-family: var(--font-board);
  font-weight: 600;
  font-size: 1.02rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.board-row__meta {
  font-size: 0.72rem;
  color: var(--slate);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.board-row__desc {
  font-size: 0.8rem;
  color: var(--ink);
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0; /* lets a grid item actually clip instead of stretching the row */
}

/* Scrolling variant: used only when the description is too long to fit,
   so a short description just sits still instead of drifting for no
   reason. The text is duplicated once and the track scrolls to -50%,
   exactly like the activity ticker below, so the loop is seamless. Reading
   speed is set per-row from JS (based on how much text there is) via the
   --scroll-duration custom property, rather than one fixed speed for every
   description regardless of length. */
.board-row__desc--scroll {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: clip;
}

.board-row__desc__track {
  display: inline-flex;
  gap: 3rem;
  width: max-content;
  animation: desc-scroll linear infinite;
  animation-duration: var(--scroll-duration, 12s);
}

.board-row__desc__track span {
  flex-shrink: 0;
}

@keyframes desc-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.board-row__metric {
  text-align: right;
  font-family: var(--font-board);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--sky-blue);
  white-space: nowrap;
}

.board-row__metric.shipped { color: var(--teal); }
.board-row__metric.hot { color: var(--coral); }

.board-row__bar {
  height: 0.4rem;
  border-radius: 0.3rem;
  background: var(--slate-dim);
  overflow: hidden;
  margin-top: 0.3rem;
}
.board-row__bar-fill {
  height: 100%;
  background: var(--sky-blue);
}

/* Only "up" and "flat" are ever rendered (see app.js) -- no downward
   indicator exists here on purpose. "Flat" reads as steady/active rather
   than stalled: a solid dot in the brand blue, not a dim dash in grey. */
.trend-up::before   { content: "▲ "; color: var(--teal); }
.trend-flat::before { content: "● "; color: var(--sky-blue); }

@keyframes flap-in {
  0%   { opacity: 0; transform: perspective(400px) rotateX(-40deg); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: perspective(400px) rotateX(0deg); }
}

.celebrate {
  animation: celebrate-flash 1.4s ease;
}
@keyframes celebrate-flash {
  0%   { box-shadow: 0 0 0 rgba(245, 185, 66, 0); }
  25%  { box-shadow: 0 0 2rem rgba(245, 185, 66, 0.55); }
  100% { box-shadow: 0 0 0 rgba(245, 185, 66, 0); }
}

/* ---------------------------------------------------------------------- */
/* Finished project hero spotlight (one random shipped project, in depth) */
/* ---------------------------------------------------------------------- */

.finished-spotlight {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.6rem;
  padding: 1rem 2rem;
  animation: flap-in 0.6s ease both;
}

.finished-spotlight__badge {
  font-family: var(--font-board);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy-deep);
  background: var(--teal);
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
}

.finished-spotlight__app {
  font-family: var(--font-board);
  font-weight: 700;
  font-size: 2.1rem;
  margin-top: 0.3rem;
}

.finished-spotlight__team {
  color: var(--slate);
  font-size: 0.95rem;
}

.finished-spotlight__desc {
  max-width: 42rem;
  color: var(--ink);
  opacity: 0.9;
  font-size: 1.05rem;
  line-height: 1.5;
  margin-top: 0.2rem;
}

.finished-spotlight__facts {
  display: flex;
  gap: 1.2rem;
  margin-top: 0.6rem;
}

.fact-chip {
  background: var(--navy-raised);
  border: 1px solid var(--hairline);
  border-radius: 0.6rem;
  padding: 0.55rem 1.1rem;
  min-width: 6rem;
}

.fact-chip__value {
  font-family: var(--font-board);
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--sky-blue);
}

.fact-chip__label {
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: 0.15rem;
}

.finished-spotlight__stack {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
}

.stack-pill {
  font-family: var(--font-board);
  font-size: 0.68rem;
  color: var(--slate);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
}

.finished-spotlight__note {
  margin-top: 0.4rem;
  max-width: 36rem;
  font-style: italic;
  color: var(--slate);
  font-size: 0.9rem;
}

.finished-spotlight--empty .finished-spotlight__app {
  font-size: 1.6rem;
}

/* ---------------------------------------------------------------------- */
/* Side panel: language breakdown + AI-adoption footnote                  */
/* ---------------------------------------------------------------------- */

.side-panel {
  flex: 1;
  min-width: 15rem;
  max-width: 18rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.side-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: var(--navy-panel);
  border: 1px solid var(--hairline);
  border-radius: 0.8rem;
  padding: 0.9rem 1.05rem;
}

.side-card__title {
  font-family: var(--font-board);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 0.7rem;
}

.side-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.lang-row {
  display: grid;
  grid-template-columns: 5.6rem 1fr 1.4rem;
  align-items: center;
  gap: 0.5rem;
}

.lang-row__name {
  font-family: var(--font-board);
  font-size: 0.72rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lang-row__track {
  height: 0.35rem;
  border-radius: 0.25rem;
  background: var(--navy-raised);
  overflow: hidden;
}

.lang-row__fill {
  display: block;
  height: 100%;
  background: var(--sky-blue);
}

.lang-row__count {
  font-family: var(--font-board);
  font-size: 0.72rem;
  text-align: right;
  color: var(--slate);
}

.side-empty {
  font-size: 0.75rem;
  color: var(--slate);
}

.lang-row__more {
  font-size: 0.68rem;
  color: var(--slate-dim);
  text-align: right;
  padding-top: 0.15rem;
}

/* ---------------------------------------------------------------------- */
/* Shout-outs                                                              */
/* ---------------------------------------------------------------------- */

.shoutout {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.4rem 0.2rem;
  font-size: 0.85rem;
  color: var(--slate);
  min-height: 1.6rem;
}

.shoutout__badge {
  font-family: var(--font-board);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy-deep);
  background: var(--sky-blue);
  border-radius: 0.3rem;
  padding: 0.15rem 0.5rem;
  white-space: nowrap;
}

.shoutout__text {
  color: var(--ink);
  opacity: 0.9;
}

/* ---------------------------------------------------------------------- */
/* Activity ticker                                                        */
/* ---------------------------------------------------------------------- */

.ticker {
  border-top: 2px solid var(--hairline);
  background: var(--navy-panel);
  padding: 0.55rem 0;
  overflow: hidden;
  white-space: nowrap;
  position: relative;
  margin: 0 -2rem;
  padding-left: 2rem;
}

.ticker__track {
  display: inline-flex;
  gap: 3rem;
  /* 162.5s = 65s slowed down 60% (i.e. new speed is 40% of the old speed:
     65 / 0.4 = 162.5). This is a fixed duration for a fixed-length track,
     which is also why the ticker used to feel like it sped up as more
     events piled up during the day -- see MAX_TICKER_EVENTS in app.js,
     which now caps the track length so this duration stays meaningful. */
  animation: ticker-scroll 162.5s linear infinite;
}

.ticker__item {
  font-family: var(--font-board);
  font-size: 0.82rem;
  color: var(--slate);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.ticker__item .dot {
  color: var(--sky-blue);
}

@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------------------------------------------------------------------- */
/* Status / last-updated indicator                                        */
/* ---------------------------------------------------------------------- */

.status-line {
  position: absolute;
  bottom: 0.5rem;
  right: 1rem;
  font-size: 0.65rem;
  color: var(--slate-dim);
  font-family: var(--font-board);
  letter-spacing: 0.05em;
}

/* ---------------------------------------------------------------------- */
/* Finale screen: shown once the countdown reaches 0, replacing #app       */
/* ---------------------------------------------------------------------- */

.finale {
  width: 100vw;
  height: 100vh;
  background: var(--brand-cinder);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-family: var(--font-brand);
}

.finale.hidden {
  display: none;
}

.finale__inner {
  width: min(70rem, 92vw);
  height: min(94vh, 56rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 1.6rem 2rem 1.2rem;
  animation: flap-in 0.7s ease both;
}

.finale__logo {
  width: min(20rem, 60vw);
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 0 14px rgba(25, 178, 255, 0.35));
}

.finale__eyebrow {
  margin-top: 0.9rem;
  font-family: var(--font-brand);
  font-weight: 500;
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand-sky-blue);
}

.finale__headline {
  margin: 0.5rem 0 0;
  font-family: var(--font-brand);
  font-size: clamp(1.5rem, 2.6vw, 2.3rem);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink);
  max-width: 44rem;
}

.finale__subhead {
  margin: 0.5rem 0 0;
  font-family: var(--font-brand);
  color: var(--slate);
  font-size: 0.95rem;
}

.finale-stats {
  margin-top: 1.4rem;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 2fr;
  gap: 0.9rem;
}

.finale-stat {
  background: var(--brand-blue-zodiac);
  border: 1px solid var(--hairline);
  border-radius: 0.8rem;
  padding: 0.9rem 1rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.finale-stat__value {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 2.1rem;
  color: var(--brand-sky-blue);
  line-height: 1;
}

.finale-stat__label {
  margin-top: 0.35rem;
  font-family: var(--font-brand);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
}

.finale-stat__label--top {
  margin-top: 0;
  margin-bottom: 0.55rem;
}

.finale-stat--wide {
  align-items: flex-start;
  text-align: left;
}

.finale-top-langs {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.finale-lang-pill {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  font-family: var(--font-brand);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--brand-cinder);
  background: #ffffff;
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
}

.finale-lang-pill__rank {
  opacity: 0.75;
  font-weight: 500;
  font-size: 0.68rem;
}

/* Vertically auto-scrolling roster of every app + team, so a long list of
   30 teams stays glanceable in a fixed-height box instead of breaking the
   page layout. Track is duplicated once and animated to -50% translateY,
   same seamless-loop trick as the horizontal ticker. */
.finale-roster {
  margin-top: 1.2rem;
  width: 100%;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--brand-blue-zodiac);
  border: 1px solid var(--hairline);
  border-radius: 0.8rem;
  padding: 0.9rem 1.1rem;
}

.finale-roster__title {
  font-family: var(--font-brand);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 0.6rem;
  flex-shrink: 0;
}

.finale-roster__viewport {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 8%, black 92%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black 8%, black 92%, transparent 100%);
}

.finale-roster__track {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  animation: roster-scroll linear infinite;
  animation-duration: var(--roster-duration, 30s);
}

.finale-roster__row {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0.7rem;
  background: var(--navy-raised);
  border: 1px solid var(--hairline);
  border-radius: 0.5rem;
}

.finale-roster__app {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.finale-roster__team {
  font-family: var(--font-brand);
  font-size: 0.72rem;
  color: var(--slate);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@keyframes roster-scroll {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}

@media (max-width: 900px) {
  .finale-stats {
    grid-template-columns: 1fr 1fr;
  }
  .finale-stat--wide {
    grid-column: 1 / -1;
  }
}