/* ═══════════════════════════════════════════════════════════════════════════
   Product-page hero art: a Daylight window with a miniature of the product.

   One namespace, .part. The window frame, title bar, stat tile, table and chip
   are primitives; a scene is just markup that uses them. Only the Nexus scene
   exists so far (.part-nexus). Studio, Spectrum, Lens and Platforms still use
   the older .pa drawings in styles.css.

   RULES THAT KEEP IT HONEST
     - Decoration: the markup is aria-hidden. The page text says what the
       product is, so nothing here may carry a claim that is not on the page.
     - Tokens only. Colours, radii and the shadow come from styles.css, so
       Daylight and Night both work with no theme rules here.
     - No beam: the rainbow is for publishing, and nothing is published here.
       No alarm colours either: this is a healthy gateway.
     - Motion is one ~10 s loop (a 2.5 s pulse divides it evenly), ease-in-out.
       It runs ONLY under .is-playing, which main.js toggles while the art is
       on screen. Without JS, or under reduced motion, the base styles are the
       finished still frame.
     - The ticking numbers are CSS counters driven by registered integer
       properties. The real text sits in .part-num; while playing it is hidden
       and the counter takes its place in the same font and width (tabular).
   ═══════════════════════════════════════════════════════════════════════════ */

@property --part-tags { syntax: "<integer>"; inherits: true; initial-value: 412; }
@property --part-devs { syntax: "<integer>"; inherits: true; initial-value: 3; }
@property --part-mem { syntax: "<integer>"; inherits: true; initial-value: 64; }
@property --part-tick { syntax: "<integer>"; inherits: true; initial-value: 0; }

/* ---------- placement: the hero grid gives the art half the width ---------- */
@media (min-width: 901px) {
  .hero-grid.part-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* ---------- the window ---------- */
.part {
  width: 100%;
  max-width: 600px;
  justify-self: end;
  position: relative;
  z-index: 1; /* the shadow paints over the next section instead of under it */
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  color: var(--text);
  font-size: 13px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 900px) {
  .part {
    justify-self: start;
    max-width: 560px;
  }
}

.part-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--glass);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
}

.part-dots {
  display: flex;
  gap: 6px;
}

.part-dots i {
  display: block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--border-strong);
}

.part-title {
  margin: 0 auto;
  padding-right: 41px; /* the three dots' width, so the title centres on the bar */
  color: var(--secondary);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.part-body {
  display: grid;
  gap: 16px;
  padding: 22px 24px 24px;
  min-height: 400px;
  align-content: start;
}

/* ---------- primitives: label, stat tile, table, chip ---------- */
.part-label {
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.2;
  text-transform: uppercase;
}

.part-stats {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
}

.part-stat {
  display: grid;
  gap: 6px;
  padding: 12px 12px 13px;
  background: var(--bg);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-md);
}

.part-v {
  color: var(--text-bright);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
}

.part-v small {
  margin-left: 2px;
  color: var(--secondary);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
}

.part-table {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}

.part-tr {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 64px 108px;
  gap: 12px;
  align-items: center;
  min-height: 54px;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
}

.part-tr:first-child {
  min-height: 0;
  padding-block: 10px;
  border-top: 0;
  background: var(--bg);
}

.part-dev {
  display: grid;
  min-width: 0;
}

.part-dev b {
  color: var(--text-bright);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.part-dev span {
  color: var(--muted);
  font-size: 12px;
}

.part-poll {
  color: var(--text);
  font-family: var(--f-mono);
  font-size: 12.5px;
  white-space: nowrap;
}

.part-st {
  display: grid;
  justify-items: end;
}

.part-chip {
  grid-area: 1 / 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 8px;
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--success) 13%, transparent);
  color: var(--success);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.part-chip::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

/* Neutral, not an alarm colour: a device that is still being reached. */
.part-chip-wait {
  background: var(--fill);
  color: var(--secondary);
  opacity: 0;
}

.part-chip-wait::before {
  background: transparent;
  border: 1.5px solid currentColor;
}

/* ---------- the Nexus scene ---------- */
.part-hero {
  display: flex;
  align-items: center;
  gap: 14px;
}

.part-live {
  position: relative;
  flex: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--success);
}

.part-live::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--success);
  opacity: 0;
}

.part-big {
  color: var(--text-bright);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
}

.part-sub {
  margin: -8px 0 0 28px;
  color: var(--muted);
  font-size: 12.5px;
}

/* ---------- motion: only while on screen ---------- */
.part.is-playing {
  animation: part-load 10s ease-in-out infinite, part-devs 10s ease-in-out infinite;
}

.part.is-playing .part-num {
  display: none;
}

.part.is-playing .part-n-tags::before {
  counter-reset: part-n var(--part-tags);
  content: counter(part-n);
}

.part.is-playing .part-n-devs::before {
  counter-reset: part-n var(--part-devs);
  content: counter(part-n) " / 3";
}

.part.is-playing .part-n-mem::before {
  counter-reset: part-n var(--part-mem);
  content: counter(part-n);
}

.part.is-playing .part-n-p1::before,
.part.is-playing .part-n-p2::before,
.part.is-playing .part-n-p3::before {
  counter-reset: part-n calc(var(--base) + var(--part-tick));
  content: counter(part-n);
}

.part-n-p1 { --base: 7; }
.part-n-p2 { --base: 12; }
.part-n-p3 { --base: 18; }

.part.is-playing .part-poll {
  animation: part-tick 10s ease-in-out infinite;
}

.part.is-playing .part-p2 { animation-delay: -3.3s; }
.part.is-playing .part-p3 { animation-delay: -6.6s; }

.part.is-playing .part-live::after {
  animation: part-pulse 2.5s ease-out infinite;
}

/* The third device arrives: it fades in as "connecting…", the tag count and
   memory climb, the device count reaches 3 / 3, then the chip turns
   "connected". The tail of the loop eases back so the seam is not a jump. */
.part.is-playing .part-tr-new {
  animation: part-row 10s ease-in-out infinite;
}

.part.is-playing .part-chip-wait {
  animation: part-wait 10s ease-in-out infinite;
}

.part.is-playing .part-chip-ok-late {
  animation: part-ok 10s ease-in-out infinite;
}

@keyframes part-pulse {
  0% { transform: scale(1); opacity: 0.4; }
  100% { transform: scale(2.4); opacity: 0; }
}

@keyframes part-load {
  0%, 12% { --part-tags: 268; --part-mem: 62; }
  44%, 90% { --part-tags: 412; --part-mem: 64; }
  98%, 100% { --part-tags: 268; --part-mem: 62; }
}

@keyframes part-devs {
  0%, 40% { --part-devs: 2; }
  46%, 90% { --part-devs: 3; }
  98%, 100% { --part-devs: 2; }
}

@keyframes part-tick {
  0%, 100% { --part-tick: 0; }
  25% { --part-tick: 1; }
  50% { --part-tick: 0; }
  75% { --part-tick: -1; }
}

@keyframes part-row {
  0% { opacity: 0; transform: translateY(6px); }
  12%, 90% { opacity: 1; transform: none; }
  98%, 100% { opacity: 0; transform: translateY(6px); }
}

/* One after the other, not a crossfade: the two labels differ in width and
   would overprint mid-fade. */
@keyframes part-wait {
  0%, 36% { opacity: 1; }
  41%, 100% { opacity: 0; }
}

@keyframes part-ok {
  0%, 41% { opacity: 0; }
  47%, 100% { opacity: 1; }
}

/* Reduced motion: the base styles above are the finished frame. */
@media (prefers-reduced-motion: reduce) {
  .part,
  .part *,
  .part *::before,
  .part *::after {
    animation: none !important;
  }

  .part .part-num {
    display: inline !important;
  }

  .part .part-n-tags::before,
  .part .part-n-devs::before,
  .part .part-n-mem::before,
  .part .part-n-p1::before,
  .part .part-n-p2::before,
  .part .part-n-p3::before {
    content: none !important;
  }
}

/* ---------- phone ---------- */
@media (max-width: 560px) {
  .part-body {
    gap: 14px;
    padding: 18px 16px 18px;
    min-height: 0;
  }

  .part-big {
    font-size: 22px;
  }

  .part-sub {
    margin-left: 28px;
  }

  /* Five tiles: three across, then two wider ones. */
  .part-stats {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
  }

  .part-stat {
    grid-column: span 2;
    padding: 10px 10px 11px;
  }

  .part-stat:nth-child(n + 4) {
    grid-column: span 3;
  }

  .part-v {
    font-size: 20px;
  }

  .part-tr {
    grid-template-columns: minmax(0, 1fr) 50px 96px;
    gap: 8px;
    padding-inline: 12px;
  }

  .part-chip {
    padding-inline: 8px;
  }

  .part-title {
    padding-right: 0;
  }
}
