/* ST Tracker — landing page.
   Token-driven, no framework, no build step. Same discipline as the app itself: every colour
   comes from the scale below so light and dark stay in step by construction. */

/* The app's own tokens, copied from web/styles.css so the two surfaces are the same product.
   The brand here is the app's deep navy, not a lighter blue of the landing page's own
   invention — a marketing page in different colours from the thing it is selling reads as a
   different thing. Keep these in step if the app's palette ever moves. */
:root {
  --bg: #f5f7fa;
  --bg-grad: radial-gradient(1200px 420px at 50% -180px, #e6ecf8 0%, transparent 70%);
  --surface: #ffffff;
  --surface-2: #f1f3f8;
  --surface-3: #e6eaf2;

  --ink: #0f172a;
  --ink-2: #4a5568;
  --ink-3: #78839a;

  --line: #e2e7f0;
  --line-2: #edf0f6;

  --brand: #1b3c77;
  --brand-2: #2b5aa8;
  --brand-ink: #ffffff;
  --brand-soft: #e9eff9;
  --brand-soft-ink: #1b3c77;

  --accent: #a8590a;
  --live: #05704a;
  --live-dot: #12b76a;
  --live-soft: #e2f5ec;
  --danger: #a52218;
  --danger-soft: #fdecea;

  --shadow-1: 0 1px 2px rgba(16, 24, 40, .05);
  --shadow-2: 0 1px 3px rgba(16, 24, 40, .07), 0 8px 24px -8px rgba(16, 24, 40, .12);
  --shadow-3: 0 12px 40px -12px rgba(16, 24, 40, .28);

  --r-lg: 18px;
  --r: 14px;
  --r-sm: 10px;
  --tap: 44px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans Gujarati",
          "Helvetica Neue", Arial, sans-serif;

  --wrap: 1120px;

  /* One duration scale, so nothing on the page animates at a speed of its own invention. */
  --fast: 140ms;
  --mid: 320ms;
  --slow: 620ms;
  --ease: cubic-bezier(.22, .78, .3, 1);
}

/* The app switches on `[data-theme]` only, with no media query — it has an explicit setting.
   This page has to serve people who have never chosen, so the same palette is applied twice:
   once for the system preference, once for a deliberate choice. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e1013;
    --bg-grad: radial-gradient(1200px 420px at 50% -200px, #191c21 0%, transparent 70%);
    --surface: #17191d;
    --surface-2: #1e2126;
    --surface-3: #2a2e34;
    --ink: #edeef0;
    --ink-2: #a8abb2;
    --ink-3: #7a7e86;
    --line: #2b2f36;
    --line-2: #212429;
    --brand: #7ea6f0;
    --brand-2: #9dbcff;
    --brand-ink: #10131a;
    --brand-soft: #1e2530;
    --brand-soft-ink: #b3caf5;
    --accent: #f0a44b;
    --live: #3ddda4;
    --live-soft: #14241d;
    --danger: #ff8f85;
    --danger-soft: #2b1a18;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .5);
    --shadow-2: 0 1px 3px rgba(0, 0, 0, .5), 0 8px 24px -8px rgba(0, 0, 0, .6);
    --shadow-3: 0 12px 40px -12px rgba(0, 0, 0, .8);
  }
}
:root[data-theme="dark"] {
  --bg: #0e1013;
  --bg-grad: radial-gradient(1200px 420px at 50% -200px, #191c21 0%, transparent 70%);
  --surface: #17191d;
  --surface-2: #1e2126;
  --surface-3: #2a2e34;
  --ink: #edeef0;
  --ink-2: #a8abb2;
  --ink-3: #7a7e86;
  --line: #2b2f36;
  --line-2: #212429;
  --brand: #7ea6f0;
  --brand-2: #9dbcff;
  --brand-ink: #10131a;
  --brand-soft: #1e2530;
  --brand-soft-ink: #b3caf5;
  --accent: #f0a44b;
  --live: #3ddda4;
  --live-soft: #14241d;
  --danger: #ff8f85;
  --danger-soft: #2b1a18;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-2: 0 1px 3px rgba(0, 0, 0, .5), 0 8px 24px -8px rgba(0, 0, 0, .6);
  --shadow-3: 0 12px 40px -12px rgba(0, 0, 0, .8);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  /* The app paints this same wash behind its shell; without it the landing page reads as a
     flat sheet next to a product with depth. */
  background-image: var(--bg-grad);
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
h1, h2, h3 { line-height: 1.18; letter-spacing: -.02em; margin: 0 0 .4em; }
h1 { font-size: clamp(2rem, 1.2rem + 3.4vw, 3.6rem); font-weight: 800; }
h2 { font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.3rem); font-weight: 750; }
h3 { font-size: 1.08rem; font-weight: 700; }
p { margin: 0 0 1em; color: var(--ink-2); }
a { color: inherit; }

.wrap { width: min(var(--wrap), 100% - 2.5rem); margin-inline: auto; }
.section { padding: clamp(3.5rem, 8vw, 6.5rem) 0; }
.narrow { max-width: 760px; margin-inline: auto; }
.sub { color: var(--ink-2); font-size: 1.05rem; max-width: 60ch; margin-bottom: 2.4rem; }
.sr, .skip:not(:focus) {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip:focus {
  position: fixed; z-index: 99; top: 12px; left: 12px; width: auto; height: auto;
  clip: auto; clip-path: none; padding: .6rem 1rem; border-radius: var(--r-sm);
  background: var(--brand); color: var(--brand-ink);
}

/* ------------------------------------------------------------------ buttons */
.btn {
  --pad: .78rem 1.3rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: var(--pad); border: 1px solid transparent; border-radius: 999px;
  font: inherit; font-weight: 650; text-decoration: none; cursor: pointer;
  /* A pill that wraps stops being a pill: at 375px "Open the app" folded onto three lines and
     rendered as a circle with text spilling out of it. */
  white-space: nowrap;
  transition: transform var(--fast) var(--ease), box-shadow var(--mid) var(--ease),
              background var(--fast) var(--ease);
  min-height: var(--tap);
}
.btn.primary { background: var(--brand); color: var(--brand-ink); box-shadow: var(--shadow-2); }
.btn.primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-3); }
.btn.primary:active { transform: translateY(0); }
.btn.sm { --pad: .5rem 1rem; min-height: 38px; font-size: .93rem; }
.btn.lg { --pad: 1rem 1.9rem; font-size: 1.06rem; }

/* ------------------------------------------------------------------ header */
.bar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: .7rem;
  padding: .7rem clamp(1rem, 4vw, 2rem);
  /* Nothing at rest. A translucent panel laid over the hero's glow met it along a hard line
     across the full width — the page looked cropped rather than continuous. The bar only
     acquires a surface once there is content behind it to separate from. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color var(--mid) var(--ease), background var(--mid) var(--ease),
              backdrop-filter var(--mid) var(--ease);
}
.bar.stuck {
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom-color: var(--line);
}
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; font-size: .95rem; }
.brand b { display: block; font-weight: 750; letter-spacing: -.01em; }
.brand small { display: none; color: var(--ink-3); font-size: .76rem; }
/* The tagline is the first thing to go when the bar is tight — the logo and name already say
   what this is, and the header has to hold a language switch and a call to action as well. */
@media (min-width: 560px) { .brand small { display: block; } }
.bar-nav { display: none; gap: 1.4rem; margin-inline: auto; }
.bar-nav a { text-decoration: none; color: var(--ink-2); font-size: .94rem; font-weight: 550; }
.bar-nav a:hover { color: var(--ink); }
.bar-end { display: flex; align-items: center; gap: .5rem; margin-left: auto; min-width: 0; }
.bar-end .btn { display: none; }
@media (min-width: 620px) { .bar-end .btn { display: inline-flex; } }
@media (min-width: 900px) { .bar-nav { display: flex; } .bar-end { margin-left: 0; } }

.lang { display: inline-flex; background: var(--surface-2); border-radius: 999px; padding: 3px; }
.lang button {
  border: 0; background: none; color: var(--ink-2); font: inherit; font-size: .84rem;
  font-weight: 600; padding: .35rem .6rem; border-radius: 999px; cursor: pointer;
  white-space: nowrap;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.lang button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-1); }

/* ------------------------------------------------------------------ hero */
.hero { position: relative; padding: clamp(2.5rem, 7vw, 5.5rem) 0 clamp(2rem, 5vw, 4rem); }
/* A soft wash behind the hero rather than a hard band, so the fold is not a visible seam. */
.hero::before {
  /* Bleeds vertically only. Pulling it past the left and right edges made the *document*
     37px wider than the viewport — `overflow-x: hidden` on body does not stop the root
     scrolling, and a decorative glow that lets the whole page slide sideways is a bad trade. */
  content: ''; position: absolute; inset: -60% 0 30%;
  background: radial-gradient(60% 60% at 25% 30%, color-mix(in srgb, var(--brand) 18%, transparent), transparent 70%);
  pointer-events: none; z-index: -1;
}
.hero-grid { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 1.05fr .95fr; } }

.eyebrow {
  display: inline-block; margin: 0 0 1rem; padding: .3rem .8rem;
  background: var(--brand-soft); color: var(--brand);
  border-radius: 999px; font-size: .8rem; font-weight: 700; letter-spacing: .02em;
}
.lede { font-size: clamp(1.02rem, .95rem + .4vw, 1.2rem); max-width: 56ch; }

.plate { display: flex; gap: .6rem; margin: 1.8rem 0 .6rem; flex-wrap: wrap; }
.plate input {
  flex: 1 1 240px; min-width: 0; padding: .85rem 1.1rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px;
  font: inherit; font-weight: 600; letter-spacing: .04em;
  box-shadow: var(--shadow-1);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.plate input:focus {
  outline: 0; border-color: var(--brand);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 18%, transparent);
}
/* Once the button has wrapped onto its own row it should look chosen rather than left over,
   so it takes the full width instead of sitting as a small pill against the left edge. */
@media (max-width: 520px) { .plate .btn { flex: 1 0 100%; } }
.hint { color: var(--ink-3); font-size: .88rem; }

/* ------------------------------------------------------------------ phone */
.hero-art { display: flex; justify-content: center; }
.phone {
  width: min(300px, 78vw); aspect-ratio: 300 / 600;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 30px; padding: 12px; box-shadow: var(--shadow-3);
  /* Drifts very slightly, so the page feels alive without anything actually moving about. */
  animation: float 7s ease-in-out infinite;
}
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

.phone-screen {
  height: 100%; border-radius: 24px; background: var(--surface-2);
  display: grid; grid-template-rows: auto 1fr auto; overflow: hidden;
}
.mini-bar {
  display: flex; align-items: center; gap: .5rem; padding: .7rem .9rem;
  font-size: .82rem; font-weight: 700; border-bottom: 1px solid var(--line);
}
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--live-dot); }
.dot.live { animation: pulse 1.8s ease-out infinite; }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--live-dot) 50%, transparent); }
  70% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.route { width: 100%; height: 100%; }
.route .road { fill: none; stroke: var(--line); stroke-width: 7; stroke-linecap: round; }
.route .road-done {
  fill: none; stroke: var(--brand); stroke-width: 7; stroke-linecap: round;
  /* Drawn in, then held — the line "fills" the way the bus has actually covered it. */
  stroke-dasharray: 460; stroke-dashoffset: 460;
  animation: draw 7s var(--ease) infinite;
}
@keyframes draw {
  0% { stroke-dashoffset: 460; }
  55%, 100% { stroke-dashoffset: 150; }
}
.route .stop { fill: var(--surface); stroke: var(--ink-3); stroke-width: 2.5; }
.bus-marker circle { fill: var(--brand); }
.bus-marker text { fill: var(--brand-ink); font-size: 11px; text-anchor: middle; }
.bus-marker {
  offset-path: path("M40 280 C 60 210, 120 200, 130 150 S 190 70, 220 24");
  offset-distance: 0%;
  animation: ride 7s var(--ease) infinite;
}
@keyframes ride { 0% { offset-distance: 0%; } 55%, 100% { offset-distance: 68%; } }

.mini-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .3rem;
  padding: .8rem .6rem; border-top: 1px solid var(--line); text-align: center;
}
.mini-stats b { display: block; font-size: .95rem; }
.mini-stats small { color: var(--ink-3); font-size: .68rem; }

/* ------------------------------------------------------------------ strip */
.strip { border-block: 1px solid var(--line); background: var(--surface); }
.strip-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.6rem 1rem;
  padding: 2.2rem 0; text-align: center;
}
@media (min-width: 760px) { .strip-grid { grid-template-columns: repeat(4, 1fr); } }
.strip b { display: block; font-size: clamp(1.4rem, 1.1rem + 1vw, 2rem); font-weight: 800; }
.strip span { color: var(--ink-3); font-size: .85rem; }

/* ------------------------------------------------------------------ cards */
.cards { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.card {
  padding: 1.5rem; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  transition: transform var(--mid) var(--ease), box-shadow var(--mid) var(--ease),
              border-color var(--mid) var(--ease);
}
/* Sized off the tap scale so it reads as the same family of object as the app's row glyphs. */
.card-icon {
  display: grid; place-items: center;
  width: var(--tap); height: var(--tap); margin-bottom: 1rem;
  background: var(--brand-soft); color: var(--brand-soft-ink);
  border-radius: var(--r-sm);
}
.card-icon svg { width: 22px; height: 22px; }
.card:hover .card-icon { background: var(--brand); color: var(--brand-ink); }
.card-icon { transition: background var(--mid) var(--ease), color var(--mid) var(--ease); }

.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); border-color: color-mix(in srgb, var(--brand) 35%, var(--line)); }
.card p { margin: 0; font-size: .95rem; }

.band { background: var(--surface); border-block: 1px solid var(--line); }

.steps { list-style: none; counter-reset: s; padding: 0; margin: 0 0 2.4rem; display: grid; gap: 1.1rem; }
@media (min-width: 800px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li { counter-increment: s; padding-left: 3.2rem; position: relative; }
.steps li::before {
  content: counter(s); position: absolute; left: 0; top: 0;
  width: 2.3rem; height: 2.3rem; display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
  border-radius: 50%; font-weight: 800;
}
.steps b { display: block; margin-bottom: .2rem; }
.steps span { color: var(--ink-2); font-size: .95rem; }
.cta-row { margin: 0; }

/* ------------------------------------------------------------------ chips */
.chips { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .6rem; }
.chips a {
  display: inline-block; padding: .55rem 1.05rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  text-decoration: none; font-size: .93rem; font-weight: 600;
  transition: transform var(--fast) var(--ease), border-color var(--fast) var(--ease),
              color var(--fast) var(--ease);
}
.chips a:hover { transform: translateY(-2px); border-color: var(--brand); color: var(--brand); }

/* ------------------------------------------------------------------ faq */
.faq { display: grid; gap: .7rem; }
.faq details {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 0 1.1rem;
  transition: border-color var(--fast) var(--ease);
}
.faq details[open] { border-color: color-mix(in srgb, var(--brand) 40%, var(--line)); }
.faq summary {
  padding: 1rem 0; font-weight: 650; cursor: pointer; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: 44px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; font-size: 1.3rem; color: var(--ink-3); line-height: 1;
  transition: transform var(--mid) var(--ease);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq p { margin: 0 0 1.1rem; font-size: .95rem; }

.closer { text-align: center; }
.closer .sub { margin-inline: auto; }

/* ------------------------------------------------------------------ footer */
.foot { background: var(--surface); border-top: 1px solid var(--line); padding: 2.6rem 0; }
.foot-grid { display: grid; gap: 1.2rem; }
.foot nav { display: flex; flex-wrap: wrap; gap: 1.1rem; }
.foot nav a { color: var(--ink-2); text-decoration: none; font-size: .93rem; }
.foot nav a:hover { color: var(--brand); }
.fine { color: var(--ink-3); font-size: .82rem; margin: 0; }

/* ------------------------------------------------------------------ motion */
/* Everything that moves on scroll starts here and is released by the observer in app.js.
   Without JS the element must still be visible, so this is applied only once JS marks the
   document ready — a page that hides its own content when a script fails is worse than a
   page with no animation at all. */
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.in {
  opacity: 1; transform: none;
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Not merely shortened: an infinite animation still spins at any duration, so the ones that
     loop have to be switched off outright. */
  .phone, .route .road-done, .bus-marker, .dot.live { animation: none; }
  .route .road-done { stroke-dashoffset: 150; }
  .bus-marker { offset-distance: 68%; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .btn.primary:hover, .card:hover, .chips a:hover { transform: none; }
}

/* ------------------------------------------------------------------ theme button */
.theme-btn {
  display: grid; place-items: center; width: 38px; height: 38px;
  background: var(--surface-2); border: 0; border-radius: 999px;
  color: var(--ink-2); cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.theme-btn:hover { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-1); }
/* The icon shows what you would get by pressing, not what you are already looking at:
   a sun on a dark page, a moon on a light one. */
.t-moon { display: none; }
:root[data-theme="light"] .t-sun { display: none; }
:root[data-theme="light"] .t-moon { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .t-sun { display: none; }
  :root:not([data-theme="dark"]) .t-moon { display: block; }
}

/* ------------------------------------------------------------------ screens */
.screens {
  display: grid; gap: 1.8rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  align-items: start;
}
/* A column each, so every caption sits on the same line however tall its screen is. Left to
   themselves the three cards took their own heights and the captions stepped down the page. */
.shot { margin: 0; display: flex; flex-direction: column; height: 100%; }

/* A real capture of the live app, framed like a handset. Capped and centred: left to fill a
   single-column layout the "phone" becomes a 370px-wide slab and stops reading as one.
   Regenerate with `node scripts/shoot.mjs` whenever the app's look changes — that is the cost
   of using photographs of software rather than a drawing of it. */
.device {
  display: block;
  width: 100%; max-width: 258px; height: auto; margin-inline: auto;
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: 22px;
  box-shadow: var(--shadow-2);
  transition: transform var(--mid) var(--ease), box-shadow var(--mid) var(--ease);
}
.shot:hover .device { transform: translateY(-6px); box-shadow: var(--shadow-3); }
.shot figcaption { margin-top: 1rem; color: var(--ink-2); font-size: .9rem; }

/* The interface rebuilt in markup rather than pasted in as a picture: sharp at any size, no
   image weight, it follows the reader's theme, and it cannot go stale the way a screenshot of
   last month's build does. */
.ui {
  height: 100%; border-radius: 19px; overflow: hidden;
  background: var(--bg);
  display: grid; grid-template-rows: auto 1fr auto;
  font-size: 8.5px; line-height: 1.4;
}
.ui-head {
  display: flex; align-items: center; gap: 5px;
  padding: 7px 9px; background: var(--surface); border-bottom: 1px solid var(--line);
  font-size: 9px;
}
.ui-logo {
  width: 13px; height: 13px; border-radius: 4px;
  background: var(--brand); flex: none;
}
.ui-body { padding: 8px; display: flex; flex-direction: column; gap: 6px; min-height: 0; }
.ui-title { font-weight: 700; font-size: 9px; }

.ui-field {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px;
  font-weight: 650; letter-spacing: .02em;
}
.ui-field.sm { padding: 5px 8px; }
.ui-go {
  background: var(--brand); color: var(--brand-ink);
  padding: 2px 7px; border-radius: 999px; font-size: 7.5px; font-weight: 700;
}

.ui-chips { display: flex; gap: 4px; overflow: hidden; }
.ui-chips span {
  padding: 3px 7px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); font-size: 7.5px; font-weight: 650; white-space: nowrap;
}
.ui-chips span.on { background: var(--brand); color: var(--brand-ink); border-color: transparent; }

.ui-map {
  position: relative; flex: 1 1 auto; min-height: 62px;
  border-radius: 10px; overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--line);
}
.ui-map.tall { min-height: 96px; }
.ui-grid {
  position: absolute; inset: 0;
  background-image: linear-gradient(var(--line) 1px, transparent 1px),
                    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 18px 18px; opacity: .7;
}
.ui-route {
  position: absolute; left: 16%; right: 16%; top: 52%; height: 4px;
  background: var(--brand); opacity: .55; border-radius: 4px; transform: rotate(-19deg);
}
.ui-bus {
  position: absolute; left: 46%; top: 46%; width: 13px; height: 13px;
  background: var(--brand); border: 2.5px solid var(--surface); border-radius: 50%;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 20%, transparent);
}
.ui-me {
  position: absolute; left: 47%; top: 48%; width: 11px; height: 11px;
  background: var(--brand); border: 2.5px solid var(--surface); border-radius: 50%;
}
.ui-stand {
  position: absolute; width: 7px; height: 7px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--ink-3);
}
.ui-label {
  position: absolute; left: 50%; top: 16%; transform: translateX(-50%);
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  padding: 2px 5px; font-size: 7.5px; font-weight: 700; white-space: nowrap;
}

.ui-card { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.ui-cardtop {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px; border-bottom: 1px solid var(--line); font-size: 9px;
}
.ui-badge {
  background: var(--live-soft); color: var(--live);
  border-radius: 999px; padding: 1px 6px; font-size: 7.5px; font-weight: 700;
}
.ui-stats { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; padding: 6px 2px; }
.ui-stats b { display: block; font-size: 8.5px; }
.ui-stats small { color: var(--ink-3); font-size: 7px; }

.ui-list {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden;
}
.ui-list li {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 8px; border-top: 1px solid var(--line);
}
.ui-list li:first-child { border-top: 0; }
.ui-list li > span { display: flex; align-items: center; gap: 4px; min-width: 0; }
.ui-list b { font-weight: 700; letter-spacing: .01em; }
.ui-list em { margin-left: auto; font-style: normal; font-weight: 700; }
.ui-dim { color: var(--ink-3); font-style: normal; }
.ui-chip {
  font-style: normal; border-radius: 999px;
  padding: 1px 5px; font-size: 7px; font-weight: 700; white-space: nowrap;
}
.ui-chip.full, .ui-chip.gone { background: var(--danger-soft); color: var(--danger); }
.ui-chip.ok { background: var(--live-soft); color: var(--live); }

.ui-tabs {
  display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 6px 0; background: var(--surface); border-top: 1px solid var(--line);
  text-align: center; color: var(--ink-3); font-size: 7.5px; font-weight: 650;
}
.ui-tabs .on { color: var(--brand); }

@media (prefers-reduced-motion: reduce) {
  .shot:hover .device { transform: none; }
}
