/*
 * BOTCOIN Mining Rig UI — shared design system.
 *
 * Codifies the tokens + component patterns already used on the main site
 * (index.html, migrate.html, faucet.html): monospace-only, paper/ink hairline
 * aesthetic, no border-radius, corner-tick bracket decorations. New rig pages
 * (Foundry, Rigs, Market, Rentals, Pools, Swap) should link this stylesheet
 * plus /rig/shared/chrome.js and build on the classes below rather than
 * re-declaring tokens.
 *
 * Usage:
 *   <link rel="stylesheet" href="/rig/shared/rig.css">
 *   <script src="/rig/shared/chrome.js"></script>
 *   <body class="rig-body"> ... <main class="rig-shell"> ... </main> </body>
 */

:root {
  --paper: #f4f3ee;
  --ink: #090909;
  /* 0.56 alpha over the pale paper landed near 4:1 contrast at the 9-11px
     mono sizes this system runs on — readable on a good panel, murky on
     everything else. 0.70 (~7:1) keeps the muted register clearly
     subordinate to full ink while staying comfortably legible. */
  --muted: rgba(9, 9, 9, 0.7);
  /* Uppercase micro-headers (card titles, stat labels, table headers, spec
     labels). One step darker than --muted so labels read as structure, not
     body copy — but still visibly lighter than --ink values/prose. */
  --heading: rgba(9, 9, 9, 0.84);
  --line: rgba(9, 9, 9, 0.88);
  --soft-line: rgba(9, 9, 9, 0.14);
  --yellow: #f8ff25;
  --panel: rgba(244, 243, 238, 0.9);
  --success: #0f7b45;
  --error: #9d2f2f;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  --ease: cubic-bezier(0.2, 0.82, 0.22, 1);

  /* Tells the browser which palette native, OS-rendered form chrome
     (select/option popups, date/number spinners, scrollbars) should use.
     Without this, a <select> with an unset or transparent background
     falls back to the OS default (usually light), which is how the dark
     theme's light-on-light "expires in" popup bug happened — the select
     inherited --ink (pale) as its text color but had no explicit
     background, so the native popup rendered pale text on its default
     white surface. Flipped to `dark` below in the dark theme. */
  color-scheme: light;

  /* Rig tier palette — drives the animated border glow on .rig-card (see
     "Rig card" below) plus small accent dots/text. tier-1 = white/pale
     glow, tier-2 = green, tier-3 = light blue, tier-4 = light red,
     tier-5 = light orange. Light-theme values are pulled a shade deeper
     than their literal name (same hue family) so the glow still reads
     against the pale #f4f3ee paper; dark-theme values below brighten back
     up toward the literal pastel/white since #050505 gives them room. */
  --tier-1: #9c9a8d;
  --tier-2: #2f9d5c;
  --tier-3: #2f8fc2;
  --tier-4: #c94f4a;
  --tier-5: #cc7a1f;

  /* Status chip accents — same desaturated register as the tier palette. */
  --status-active: #3f7a52;
  --status-inactive: rgba(9, 9, 9, 0.55);
  --status-listed: #4a6a91;
  --status-lease: #a3793f;
  --status-epoch-locked: #9d5b3d;
}

html[data-theme="dark"] {
  color-scheme: dark;

  --paper: #050505;
  --ink: #f4f3ee;
  --muted: rgba(244, 243, 238, 0.62);
  --heading: rgba(244, 243, 238, 0.8);
  --line: rgba(244, 243, 238, 0.9);
  --soft-line: rgba(244, 243, 238, 0.16);
  --yellow: #f4f3ee;
  --panel: rgba(5, 5, 5, 0.9);
  --success: #72d59c;
  --error: #e56b6b;

  --tier-1: #f2f1ea;
  --tier-2: #5fe090;
  --tier-3: #6fc3f0;
  --tier-4: #f2827a;
  --tier-5: #f5a955;

  --status-active: #72d59c;
  --status-inactive: rgba(244, 243, 238, 0.46);
  --status-listed: #8fb0da;
  --status-lease: #d9ac6c;
  --status-epoch-locked: #e0906f;
}

/* ── Reset / base ────────────────────────────────────────────────────── */

.rig-body,
.rig-body * {
  box-sizing: border-box;
}

.rig-body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--mono);
  letter-spacing: 0;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

.rig-body a {
  color: inherit;
}

.rig-body button,
.rig-body input,
.rig-body select,
.rig-body textarea {
  font-family: var(--mono);
}

/* Optional faint grid backdrop, matches migrate.html's .grid-build. */
.grid-build {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: linear-gradient(var(--soft-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--soft-line) 1px, transparent 1px);
  background-size: 48px 48px;
  opacity: 0.86;
}

/* ── Site nav / brand / dropdown / tab bar (chrome.js injects this exact
   markup) ────────────────────────────────────────────────────────────────
   Structure:
     <nav class="site-nav">
       <a class="site-brand">MINING</a>                 (→ /foundry)
       <div class="site-menu"> ...corner ticks + 5 links... </div>
       <a class="site-nav-back">← agentmoney.net</a>
     </nav>
     <div class="site-tabbar" role="tablist"> ...6 rig-page tabs... </div>

   .site-nav (brand + dropdown + back-link) is fixed top-left. .site-menu
   is a hover/focus dropdown positioned absolute against .site-nav — same
   pattern as the brand menu on migrate.html/index.html/faucet.html/
   dashboard.html, reusing the shared .corner/.site-corner tick decoration.

   .site-tabbar is a separate, independently fixed element, horizontally
   centered in the viewport (left: 50%; transform: translateX(-50%)) at
   top: 18px on wide viewports. Below ~900px the brand box and the fixed
   wallet box (right: 58px, min-width 148px) get too close to a centered
   tab bar's edges for it to safely share that row, so it drops to its own
   row beneath (top: 60px); at ≤620px it becomes the 2-column grid (see
   the mobile breakpoint below), still centered, dropped further to clear
   the brand/dropdown column. See rig.css's .rig-shell padding-top rules,
   tuned to match each tier's total nav height. */

/* Full-width opaque band behind the fixed top chrome (brand, tab bar,
   wallet box, theme toggle) so page content scrolls under a solid header
   instead of sliding visibly behind and between the floating pieces. The
   <=708px breakpoint drops it because there the tab bar itself becomes the
   opaque full-width band. */
.rig-body.rig-chrome-tabs::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 66px;
  background: var(--paper);
  border-bottom: 1px solid var(--soft-line);
  z-index: 38;
}

@media (max-width: 900px) {
  .rig-body.rig-chrome-tabs::before {
    height: 104px;
  }
}

@media (max-width: 708px) {
  .rig-body.rig-chrome-tabs::before {
    content: none;
  }
}

.site-nav {
  position: fixed;
  top: 18px;
  left: 18px;
  z-index: 41;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
}

.site-brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 8px;
  background: rgba(244, 243, 238, 0.94);
  border: 1px solid rgba(10, 10, 10, 0.2);
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}

html[data-theme="dark"] .site-brand {
  background: rgba(5, 5, 5, 0.94);
  border-color: rgba(244, 243, 238, 0.22);
}

.site-brand img {
  width: 18px;
  height: 18px;
  display: block;
  filter: grayscale(1);
}

html[data-theme="dark"] .site-brand img {
  filter: grayscale(1) invert(1);
}

.site-brand span {
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Hover/focus dropdown — clicking .site-brand still navigates to
   /foundry; hovering or focusing anywhere in .site-nav (including
   tabbing into a menu link) reveals this instead. */
.site-menu {
  position: absolute;
  top: 40px;
  left: 2px;
  min-width: 136px;
  padding: 14px 14px 12px;
  background: rgba(244, 243, 238, 0.95);
  border: 1px solid var(--line);
  opacity: 0;
  transform: translateY(-7px);
  transition:
    opacity 0.55s var(--ease),
    transform 0.55s var(--ease);
  pointer-events: none;
}

/* Invisible bridge spanning the gap between the brand and the dropdown.
   Without it the pointer leaves .site-nav on the way down and the menu
   closes before it can be reached. Hovering a descendant still counts as
   hovering .site-nav, so the bridge holds the menu open. */
.site-menu::before {
  content: "";
  position: absolute;
  top: -18px;
  left: 0;
  right: 0;
  height: 18px;
}

html[data-theme="dark"] .site-menu {
  background: rgba(5, 5, 5, 0.95);
}

.site-nav:hover .site-menu,
.site-nav:focus-within .site-menu {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.site-menu a {
  display: block;
  padding: 6px 0;
  color: var(--ink);
  text-decoration: none;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: transform 0.45s var(--ease);
}

.site-menu a:hover {
  transform: translateX(3px);
}

/* Tab bar — hairline grid built the same way as .stat-grid: a 1px gap over
   a --soft-line background stands in for cell borders. Independently
   fixed and centered; see the breakpoints below for how it avoids the
   brand box and the wallet box / theme toggle on the right. */
.site-tabbar {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  flex-wrap: nowrap;
  gap: 1px;
  background: var(--soft-line);
  border: 1px solid var(--soft-line);
}

.site-tabbar a {
  display: inline-flex;
  align-items: center;
  padding: 7px 10px;
  background: rgba(244, 243, 238, 0.94);
  color: var(--muted);
  text-decoration: none;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: inset 0 -2px 0 0 transparent;
  transition:
    background 0.35s var(--ease),
    color 0.35s var(--ease),
    box-shadow 0.35s var(--ease);
}

html[data-theme="dark"] .site-tabbar a {
  background: rgba(5, 5, 5, 0.94);
}

.site-tabbar a:hover {
  color: var(--ink);
  background: var(--soft-line);
}

.site-tabbar a.is-active {
  color: var(--ink);
  background: var(--soft-line);
  box-shadow: inset 0 -2px 0 0 var(--ink);
}

/* Collision guards, computed against this tab bar's actual rendered
   footprint (6 tabs, ~396px wide unwrapped, ~29px tall) and the other
   fixed chrome it has to coexist with:
     - .site-brand: left 18 → ~117px.
     - .rig-wallet-button: right 58px, ~183px wide (its "Connect wallet"
       label, not just its 148px min-width) → left edge at (viewport -
       241)px, top 15 → 49.
     - .site-menu, open: left ~20 → ~156px, top ~58 → ~216px (its own
       top: 40px offset already clears the wallet box's bottom edge (49)
       regardless of viewport width, so brand-menu vs. wallet-box never
       needs a guard here).
   On the shared top: 18px row, a centered ~396px bar's right edge
   (viewport/2 + 198) reaches the wallet box's left edge below ~878px
   viewport width — drop to its own row beneath at 900px for margin.
   Below ~708px (viewport/2 - 198 < ~156px), that dropped row's left edge
   would instead reach into the *open* dropdown's column, and at that
   width the two are also close enough vertically (dropped-row top 60,
   bottom 89 vs. the dropdown's 58–216 span) to actually intersect — so
   under 708px the tab bar drops further still (top: 226px, past the
   dropdown's own bottom edge with margin) rather than merely past the
   brand row. */
@media (max-width: 900px) {
  .site-tabbar {
    top: 60px;
  }
}

/* Narrow screens: the tab bar sits directly under the brand rather than
   being pushed below the dropdown's full height. The dropdown is transient
   (hover/focus only) while the tab bar is permanent, so the dropdown wins
   the z-order instead of the tab bar losing the position — a fixed bar
   parked mid-viewport reads as "scrolling content passing over it". */
/* Narrow screens: the tab bar becomes a full-width, fully opaque header
   band rather than a floating 208px island. As an island it was already
   `fixed`, but page content scrolled past on both sides of it and through
   the 1px gaps between tabs, which reads as content sliding over the tabs.
   The band spans the viewport and starts at top:0 (its padding-top leaves
   room for the brand, which sits above it in z-order), so nothing can pass
   behind or beside it. */
@media (max-width: 708px) {
  .site-tabbar {
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    max-width: none;
    transform: none;
    z-index: 39;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 58px 12px 10px;
    background: var(--paper);
    border: 0;
    border-bottom: 1px solid var(--soft-line);
  }

  .site-nav {
    z-index: 41;
  }

  /* Opaque tabs; the container's paper background replaced the hairline
     grid the 1px gap used to draw, so each tab carries its own hairline. */
  .site-tabbar a {
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--soft-line);
    justify-content: center;
    padding: 8px 6px;
  }

  .site-tabbar a.is-active {
    box-shadow:
      inset 0 0 0 1px var(--soft-line),
      inset 0 -2px 0 0 var(--ink);
  }
}

.site-nav-back {
  padding-left: 2px;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-decoration: none;
  opacity: 0.75;
  transition: opacity 0.35s var(--ease);
}

.site-nav-back:hover {
  opacity: 1;
  text-decoration: underline;
}

.theme-toggle {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 42;
  width: 28px;
  height: 28px;
  border: 0;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font: inherit;
}

/* ── Top-right wallet connect box (migrate.html pattern) ────────────────
   Doubled class (.frame-button.rig-wallet-button) so `position: fixed`
   outranks the later `.frame-button { position: relative }` rule. */
.frame-button.rig-wallet-button {
  position: fixed;
  top: 15px;
  right: 58px;
  z-index: 42;
  min-width: 148px;
  min-height: 34px;
  padding: 8px 13px;
  font-size: 11px;
  background: rgba(244, 243, 238, 0.94);
}

html[data-theme="dark"] .frame-button.rig-wallet-button {
  background: rgba(5, 5, 5, 0.94);
}

.rig-wallet-button.is-connected {
  cursor: default;
}

@media (max-width: 620px) {
  .frame-button.rig-wallet-button {
    min-width: 0;
    right: 54px;
  }
}

.theme-toggle::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50% 100%);
  transition: transform 0.55s var(--ease);
}

.theme-toggle:hover::before {
  transform: rotate(180deg);
}

/* ── Corner-tick bracket decoration ─────────────────────────────────────
   Used on frame cards, menus, rig cards. Requires four child spans:
   <span class="corner tl"></span> <span class="corner tr"></span>
   <span class="corner br"></span> <span class="corner bl"></span>          */

.corner,
.site-corner {
  position: absolute;
  width: 18px;
  height: 18px;
  pointer-events: none;
}

.corner::before,
.corner::after,
.site-corner::before,
.site-corner::after {
  content: "";
  position: absolute;
  background: var(--line);
}

.corner::before,
.site-corner::before {
  width: 18px;
  height: 1px;
}

.corner::after,
.site-corner::after {
  width: 1px;
  height: 18px;
}

.corner.tl,
.site-corner.tl { top: -1px; left: -1px; }
.corner.tr,
.site-corner.tr { top: -1px; right: -1px; transform: rotate(90deg); }
.corner.br,
.site-corner.br { bottom: -1px; right: -1px; transform: rotate(180deg); }
.corner.bl,
.site-corner.bl { bottom: -1px; left: -1px; transform: rotate(270deg); }

/* Small corner-tick variant (10px), used inside compact components like rig cards. */
.corner.sm { width: 10px; height: 10px; }
.corner.sm::before { width: 10px; height: 1px; }
.corner.sm::after { width: 1px; height: 10px; }

/* ── Page shell ──────────────────────────────────────────────────────── */

.rig-shell {
  position: relative;
  z-index: 1;
  max-width: 1080px;
  margin: 0 auto;
  padding: 96px 24px 72px;
}

.rig-shell--wide {
  max-width: 1280px;
}

/* The nav chrome.js injects reserves top clearance for whichever fixed
   chrome element sits lowest: the brand + back-link column on the left,
   or the independently-positioned tab bar (see the .site-tabbar
   breakpoints above). chrome.js always sets `rig-chrome-tabs` on <body>,
   so this rule is effectively the real default for every page that mounts
   the shared chrome. Tuned per breakpoint alongside .site-tabbar's own
   `top` offset — see the @media blocks below. */
.rig-body.rig-chrome-tabs .rig-shell {
  padding-top: 92px;
}

@media (max-width: 900px) {
  .rig-body.rig-chrome-tabs .rig-shell {
    padding-top: 114px;
  }
}

@media (max-width: 708px) {
  .rig-body.rig-chrome-tabs .rig-shell {
    padding-top: 168px;
  }
}

/* ── Section header ──────────────────────────────────────────────────── */

.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 22px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--soft-line);
}

.section-header h1,
.section-header h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
}

.section-header .section-caption {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0;
  text-transform: none;
}

.section-header .section-meta {
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

section + section,
.rig-section + .rig-section {
  margin-top: 48px;
}

/* ── Stat tile ───────────────────────────────────────────────────────── */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1px;
  background: var(--soft-line);
  border: 1px solid var(--soft-line);
}

.stat-tile {
  position: relative;
  background: var(--paper);
  padding: 16px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-tile .stat-label {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--heading);
}

.stat-tile .stat-value {
  font-size: 17px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  word-break: break-word;
}

.stat-tile .stat-sub {
  font-size: 11px;
  color: var(--muted);
}

/* ── Frame card ──────────────────────────────────────────────────────── */

.frame-card {
  position: relative;
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 20px;
}

.frame-card .frame-card-title {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--heading);
  margin: 0 0 14px;
}

/* ── Data table ──────────────────────────────────────────────────────── */

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.data-table th,
.data-table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--soft-line);
  font-variant-numeric: tabular-nums;
}

.data-table th {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--heading);
  font-weight: 400;
  border-bottom: 1px solid var(--line);
}

.data-table tbody tr {
  transition: background 0.3s var(--ease);
}

.data-table tbody tr:hover {
  background: var(--soft-line);
}

.data-table td.numeric,
.data-table th.numeric {
  text-align: right;
}

/* ── Form controls ───────────────────────────────────────────────────── */

.form-field {
  display: grid;
  gap: 6px;
  margin-bottom: 14px;
}

.form-field label {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--heading);
}

.form-input,
.form-select {
  width: 100%;
  border: 1px solid var(--soft-line);
  background-color: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  padding: 10px 12px;
  outline: none;
  transition: border-color 0.35s var(--ease);
}

/* Native <select> popups (and the calendar/spinner UI on date/number
   inputs) are OS-rendered and do NOT inherit page CSS — they only pick up
   the palette via `color-scheme` above plus their own explicit
   background-color/color, which is why these are set even though
   `.form-select` already looks correct closed. `option`/`optgroup` need
   the same pair explicitly: some engines (Chromium) otherwise render
   options with a UA-default white background regardless of the select's
   own background, which is the exact "pale text on white, in dark mode"
   bug this fixes. */
.form-select option,
.form-select optgroup {
  background-color: var(--paper);
  color: var(--ink);
}

.form-input::placeholder {
  color: var(--muted);
}

.form-input:focus,
.form-select:focus {
  border-color: var(--line);
}

.form-hint {
  font-size: 11px;
  color: var(--muted);
}

.frame-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--soft-line);
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 12px;
  padding: 11px 18px;
  cursor: pointer;
  transition:
    border-color 0.45s var(--ease),
    transform 0.45s var(--ease),
    opacity 0.35s ease;
}

.frame-button::before,
.frame-button::after {
  content: "";
  position: absolute;
  inset: -1px;
  pointer-events: none;
  background:
    linear-gradient(var(--line), var(--line)) left top / 18px 1px no-repeat,
    linear-gradient(var(--line), var(--line)) left top / 1px 18px no-repeat,
    linear-gradient(var(--line), var(--line)) right top / 18px 1px no-repeat,
    linear-gradient(var(--line), var(--line)) right top / 1px 18px no-repeat,
    linear-gradient(var(--line), var(--line)) right bottom / 18px 1px no-repeat,
    linear-gradient(var(--line), var(--line)) right bottom / 1px 18px no-repeat,
    linear-gradient(var(--line), var(--line)) left bottom / 18px 1px no-repeat,
    linear-gradient(var(--line), var(--line)) left bottom / 1px 18px no-repeat;
}

.frame-button::after {
  opacity: 0;
  transform: scale(0.965);
  transition:
    opacity 0.45s var(--ease),
    transform 0.45s var(--ease);
}

.frame-button:hover {
  border-color: var(--line);
  transform: translateY(-2px);
}

.frame-button:hover::after {
  opacity: 1;
  transform: scale(1.018);
}

.frame-button:disabled {
  cursor: not-allowed;
  opacity: 0.48;
  transform: none;
}

/* `a.` variant included so link-styled buttons beat `.rig-body a`'s
   color:inherit (0,1,1) — otherwise primary anchors render ink-on-ink. */
.frame-button--primary,
.rig-body a.frame-button--primary {
  background: var(--ink);
  color: var(--paper);
}

.frame-button--primary::before,
.frame-button--primary::after {
  background:
    linear-gradient(var(--ink), var(--ink)) left top / 18px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) left top / 1px 18px no-repeat,
    linear-gradient(var(--ink), var(--ink)) right top / 18px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) right top / 1px 18px no-repeat,
    linear-gradient(var(--ink), var(--ink)) right bottom / 18px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) right bottom / 1px 18px no-repeat,
    linear-gradient(var(--ink), var(--ink)) left bottom / 18px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) left bottom / 1px 18px no-repeat;
}

.frame-button--small {
  padding: 7px 12px;
  font-size: 10px;
  letter-spacing: 0.14em;
}

/* ── Status chip ─────────────────────────────────────────────────────── */

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border: 1px solid var(--soft-line);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.status-chip::before {
  content: "";
  width: 6px;
  height: 6px;
  background: currentColor;
  flex-shrink: 0;
}

.status-chip--active { color: var(--status-active); border-color: currentColor; }
.status-chip--inactive { color: var(--status-inactive); }
.status-chip--listed { color: var(--status-listed); border-color: currentColor; }
.status-chip--lease-pending { color: var(--status-lease); border-color: currentColor; }
.status-chip--epoch-locked { color: var(--status-epoch-locked); border-color: currentColor; }

/* ── Progress bar (hairline track, flat fill) ───────────────────────── */

.progress-bar {
  position: relative;
  height: 3px;
  background: var(--soft-line);
  overflow: hidden;
}

.progress-bar .progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--progress, 0%);
  background: var(--ink);
  transition: width 0.6s var(--ease);
}

.progress-bar--yellow .progress-fill {
  background: var(--yellow);
}

/* ── Rig card ────────────────────────────────────────────────────────── */
/* The NFT representation. Clean frame, corner ticks, and a subtle
   tier-colored glow that travels clockwise around the full border ring
   as the only color/motion element. Set the tier via a class:
   .rig-card--tier-1 .. .rig-card--tier-5 (higher tiers may reuse
   --tier-5). Inactive rigs get .rig-card--inactive, which dims the glow
   and expects an INACTIVE status chip.

   Glow mechanic: a registered <angle> custom property (--rig-glow-angle)
   drives a conic-gradient on ::before. ::before is masked down to the
   border ring only (content-box excluded from border-box via
   mask-composite), so every animation frame repaints a ~2px ring, never
   the card body — no full-card blur/filter, no box-shadow or
   background-position animation. Corner ticks are real DOM nodes that
   paint after this pseudo-element, so they stay crisp on top of the ring.
   prefers-reduced-motion freezes the angle and swaps in a flat static
   ring in the tier color (no conic-gradient, no motion). */

@property --rig-glow-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.rig-card {
  position: relative;
  border: 1px solid var(--line);
  background: var(--panel);
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.rig-card::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 2px;
  background: conic-gradient(
    from var(--rig-glow-angle),
    transparent 0deg,
    transparent 8deg,
    color-mix(in srgb, var(--rig-tier-color, var(--tier-1)) 45%, transparent) 42deg,
    var(--rig-tier-color, var(--tier-1)) 60deg,
    color-mix(in srgb, var(--rig-tier-color, var(--tier-1)) 45%, transparent) 78deg,
    transparent 116deg,
    transparent 360deg
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-clip: content-box, border-box;
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0.92;
  animation: rig-glow-spin 5s linear infinite;
  /* `--rig-glow-angle` is what's actually driving the change, but
     `will-change` accepting a custom-property ident is inconsistently
     implemented; `background` is the concrete property that repaints
     each frame as the angle advances, and is the widely-supported hint.
     Scoped to this pseudo-element only, not the card or its children. */
  will-change: background;
  contain: paint;
  pointer-events: none;
}

@keyframes rig-glow-spin {
  to {
    --rig-glow-angle: 360deg;
  }
}

.rig-card--tier-1 { --rig-tier-color: var(--tier-1); }
.rig-card--tier-2 { --rig-tier-color: var(--tier-2); }
.rig-card--tier-3 { --rig-tier-color: var(--tier-3); }
.rig-card--tier-4 { --rig-tier-color: var(--tier-4); }
.rig-card--tier-5 { --rig-tier-color: var(--tier-5); }

/* Tier-1's "white glow" is a pale, low-chroma color by design, which on
   the light-mode paper (#f4f3ee) needs a little extra definition to read
   as a border rather than disappearing — a static, faint outer shadow
   (not part of the animated ring, so no per-frame cost) rather than
   darkening the glow color itself. Not needed against the near-black
   dark-mode paper, where the pale tier-1 value already glows clearly. */
.rig-card--tier-1 {
  box-shadow: 0 0 0 1px rgba(9, 9, 9, 0.07);
}

html[data-theme="dark"] .rig-card--tier-1 {
  box-shadow: none;
}

.rig-card--inactive::before {
  opacity: 0.36;
}

.rig-card--inactive {
  opacity: 0.82;
}

.rig-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.rig-card-id {
  font-size: 15px;
  color: var(--ink);
  letter-spacing: 0.02em;
}

.rig-card-tier {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--rig-tier-color, var(--muted));
}

.rig-card-status {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.rig-card-specs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
  padding-top: 10px;
  border-top: 1px solid var(--soft-line);
}

.rig-card-spec .spec-label {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--heading);
  margin-bottom: 3px;
}

.rig-card-spec .spec-value {
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}

/* ── Utility ─────────────────────────────────────────────────────────── */

.rig-muted { color: var(--muted); }
.rig-mono-nums { font-variant-numeric: tabular-nums; }
.rig-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Mobile breakpoint ───────────────────────────────────────────────── */

@media (max-width: 620px) {
  .rig-shell {
    padding: 132px 18px 56px;
  }

  .rig-body.rig-chrome-tabs .rig-shell {
    padding-top: 168px;
  }

  /* Tab bar collapses to a 3-row × 2-column grid, still centered
     (left: 50%; transform: translateX(-50%), and top: 226px, both
     inherited from the 708px breakpoint above) — dropped well below the
     brand/dropdown/back-link column, past the open .site-menu dropdown's
     full height, so an open dropdown never overlaps the grid even at
     narrow widths where their columns would otherwise intersect
     horizontally. */

  .section-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .stat-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .rig-card-specs {
    grid-template-columns: 1fr;
  }

  .data-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

/* ── Reduced motion ──────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .site-tabbar a,
  .site-nav-back,
  .theme-toggle::before,
  .frame-button,
  .frame-button::after,
  .data-table tbody tr,
  .progress-bar .progress-fill,
  .form-input,
  .form-select {
    transition: none !important;
  }

  /* Freeze the traveling glow; fall back to a flat static ring in the
     tier color, still masked to the border only (no motion, no
     conic-gradient recompute). */
  .rig-card::before {
    animation: none !important;
    background: var(--rig-tier-color, var(--tier-1));
    opacity: 0.85;
  }

  .rig-card--inactive::before {
    opacity: 0.32;
  }
}

/* ── X profile link (self-reported trust badge + link controls) ─────── */

.x-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--heading);
  text-decoration: none;
  border: 1px solid var(--soft-line);
  padding: 1px 6px 2px;
  white-space: nowrap;
  vertical-align: middle;
}

.x-badge:hover {
  border-color: var(--line);
  box-shadow: inset 0 -2px 0 0 var(--ink);
}

.x-link-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.x-link-row .form-input {
  flex: 1;
  min-width: 0;
}
