/* --------------------------------------------------------------------------
   The signed-in skin -- v2, dark "instrument" system (see tokens.css's own
   top comment). Structural continuity with the v1 file this replaces:
   same class names, same component shapes (.card, .pill, .mod, .tabbar,
   .credit-card ...), so no JS that builds markup via el() needed to
   change just because the skin did. Only the VALUES moved -- light greys
   to deep indigo, Bootstrap blue to viridis teal, and every hardcoded
   light-mode text colour (pill/callout/alert text was literally
   `color: #0f5132` etc, tuned for a pale tinted background) rewritten for
   a dark tinted background instead. --orange is gone: DHARA moved to
   amber, and generic UI never reached for a product colour to begin with
   (DESIGN.md's "amber/astro are product identity, never a general
   accent") -- structural chrome (topbar, avatar, focus rings) now reads
   var(--primary) throughout, same principle as before, new value.
   -------------------------------------------------------------------------- */

/* ==========================================================================
   Sitewide mouse-reactive background (js/fx.js) -- 2026-08-26, your
   instruction to carry the sign-in page's curl-noise canvas onto every
   signed-in page too. js/flow.js's own SVG-line motif was removed
   entirely the same day (your own follow-up instruction) -- this canvas
   is the whole background now, not a layer added on top of that one.
   js/parallax.js's tile-only scroll-speed layer is untouched.

   z-index: -1, not 0 -- a viewport-pinned `position: fixed` layer sitting
   behind literally every other static-positioned element on the page
   needs no position:relative-on-every-sibling discipline the way an
   in-flow decorative layer would (a negative z-index sits in the tier
   BELOW all static content by definition, so it never needs any other
   element's own position touched to stay behind them). Still paints above
   body's own CSS background (child boxes always paint after their
   parent's own background, regardless of the child's z-index sign), so
   the existing radial-gradient wash on body.app remains visible through
   it, not replaced by it.
   ========================================================================== */
#fx-bg {
  position: fixed; inset: 0; z-index: -1;
  width: 100%; height: 100%;
  pointer-events: none;
  opacity: .55;   /* lower than the entry page's .9 -- this sits behind opaque cards/tables most of the page, only the margins around them need to read */
}
@media (prefers-reduced-motion: reduce) { #fx-bg { display: none; } }

body.app {
  background:
    radial-gradient(1100px 560px at 88% -12%, color-mix(in srgb, var(--teal) 10%, transparent), transparent 60%),
    radial-gradient(900px 480px at 4% 4%,  color-mix(in srgb, var(--astro) 7%, transparent), transparent 55%),
    var(--page);
  background-attachment: fixed;
  min-height: 100vh;
  display: flex; flex-direction: column;
}

/* ==========================================================================
   Header
   ========================================================================== */

.topbar {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--void) 86%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--border);
  transition: box-shadow var(--dur-2) ease;
}
.topbar.stuck { box-shadow: var(--shadow-2); }
.topbar-in {
  max-width: 1180px; margin: 0 auto;
  padding: 10px var(--sp-5);
  display: flex; align-items: center; gap: var(--sp-4);
}
/* Contact us + the account menu, grouped tighter than the topbar's own
   gap so they read as one cluster -- "near profile information" means
   visually paired, not just another item in the row. Takes over the
   right-push .who used to do on its own (it's nested in here now). */
.account-group { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.topbar .logo { height: 30px; width: auto; }

/* Cloud-credits header widget -- links to credits.html. Amber, not the
   page's own --accent: credits are a platform-level thing, the same
   balance regardless of which product's dashboard you're standing on.
   Un-boxed 2026-08-27 (your instruction: "both credits and storage info
   are inside separate boxes... have them stay without boxes in the
   header") -- no background/border/padding any more, sits directly in
   the header row like the nav links either side of it. Hover swaps to
   the brighter tone instead of a background change, since there's no box
   left for a background to visibly fill. */
.credits-chip {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--warn-text); font-family: var(--font-mono); font-size: var(--t-sm); font-weight: 600;
  transition: color var(--dur-1) ease;
}
.credits-chip:hover { color: var(--amber-bright); text-decoration: none; }
.credits-chip svg { color: var(--amber); flex: none; }

/* Storage widget -- links to storage.html. Teal, not amber: distinct at a
   glance from the credits widget sitting right next to it, and teal reads
   as "platform-level" the same way the credits widget's amber does
   (neither is a product accent -- DESIGN.md's own rule, see shell.js's
   top comment). Un-boxed 2026-08-27, same instruction/reasoning as
   .credits-chip above. */
.storage-chip {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--info-text); font-family: var(--font-mono); font-size: var(--t-sm); font-weight: 600;
  transition: color var(--dur-1) ease;
}
.storage-chip:hover { color: var(--teal-bright); text-decoration: none; }
.storage-chip svg { color: var(--teal); flex: none; }
.storage-bar {
  display: inline-block; width: 34px; height: 5px; border-radius: 3px;
  background: color-mix(in srgb, var(--teal) 18%, var(--border-soft));
  overflow: hidden;
}
.storage-fill {
  display: block; height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--teal), var(--teal-bright));
  transition: width var(--dur-3) var(--e-out);
}
@media (max-width: 980px) { .storage-chip .storage-bar { display: none; } }

/* storage.html's own larger summary bar -- same idea as .storage-bar
   above, sized for a page hero instead of a header chip. */
.storage-track {
  width: 100%; height: 10px; border-radius: 5px;
  background: color-mix(in srgb, var(--teal) 14%, var(--border-soft));
  overflow: hidden;
}
.storage-track-fill {
  display: block; height: 100%; border-radius: 5px;
  background: linear-gradient(90deg, var(--teal), var(--teal-bright));
  transition: width var(--dur-4) var(--e-out);
}

.nav { display: flex; gap: 2px; margin-left: var(--sp-5); }
.nav a {
  position: relative;
  padding: 8px 13px; border-radius: var(--r-sm);
  font-family: var(--font-mono);
  color: var(--label); font-size: var(--t-sm); font-weight: 500;
  transition: background var(--dur-1) ease, color var(--dur-1) ease;
}
.nav a:hover { background: var(--border-soft); color: var(--ink); text-decoration: none; }
.nav a.on { color: var(--primary); font-weight: 600; }
.nav a.on::after {
  content: ""; position: absolute; left: 13px; right: 13px; bottom: 2px;
  height: 2px; border-radius: 2px; background: var(--primary);
  animation: nav-underline var(--dur-3) var(--e-out);
}
@keyframes nav-underline { from { transform: scaleX(0); } }


.who { position: relative; }
.who-btn {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 11px 5px 5px;
  border: 1px solid var(--border); border-radius: var(--r-pill);
  background: var(--card); cursor: pointer;
  font-size: var(--t-sm); color: var(--label);
  transition: box-shadow var(--dur-2) var(--e-out), border-color var(--dur-1) ease;
}
.who-btn:hover { border-color: var(--primary); box-shadow: var(--shadow-2); }
.avatar {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center; border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--astro));
  color: #fff; font-weight: 700; font-size: var(--t-sm);
}
.menu {
  position: absolute; right: 0; top: calc(100% + 8px);
  min-width: 230px; padding: 6px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-3);
  animation: pop-in var(--dur-2) var(--e-out);
}
.menu .head { padding: 9px 11px 11px; border-bottom: 1px solid var(--border-soft); margin-bottom: 5px; }
.menu .head b { display: block; font-size: var(--t-sm); }
.menu .head span { font-size: var(--t-xs); color: var(--muted); word-break: break-all; }
.menu button, .menu a {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 11px; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--label); font-size: var(--t-sm);
  text-align: left; cursor: pointer;
}
.menu button:hover, .menu a:hover { background: var(--border-soft); color: var(--ink); text-decoration: none; }

.burger { display: none; margin-left: auto; }
@media (max-width: 820px) {
  .nav {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; gap: 0; margin: 0; padding: var(--sp-3);
    background: var(--card); border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-3);
  }
  .nav:not(.open) { display: none; }
  .nav a.on::after { display: none; }
  .burger { display: inline-flex; }
  .who { margin-left: var(--sp-2); }
  .who-btn .email { display: none; }
}

/* ==========================================================================
   Page shell
   ========================================================================== */

main { flex: 1 0 auto; }
.wrap-page { max-width: 1180px; margin: 0 auto; padding: var(--sp-6) var(--sp-5) var(--sp-8); }

.page-head { position: relative; margin-bottom: var(--sp-5); }
.page-head h1 {
  position: relative; z-index: 1;
  font-family: var(--font-display);
  font-size: var(--t-2xl); font-weight: 600; letter-spacing: -.03em;
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
}
.page-head p { position: relative; z-index: 1; color: var(--muted); margin-top: 6px; }

.sec-head {
  display: flex; align-items: baseline; gap: var(--sp-3);
  margin: var(--sp-6) 0 var(--sp-4);
}
.sec-head h2 { font-family: var(--font-display); font-size: var(--t-xl); font-weight: 600; letter-spacing: -.02em; }
.sec-head .count {
  padding: 1px 9px; border-radius: var(--r-pill);
  background: var(--border-soft); color: var(--muted);
  font-family: var(--font-mono); font-size: var(--t-xs); font-weight: 700;
}
.sec-head .rule { flex: 1; height: 1px; background: var(--border); }

/* Cloud tab (dashboard.js's cloudHome()) -- "Open Cloud Simulation" and
   "Cloud credits" side by side, 2026-08-27 (your instruction), collapsing
   back to stacked under 980px (same breakpoint .storage-chip's own
   responsive rule already uses) since the credits column has real content
   height (banner + card + recent-jobs table) that gets cramped narrower. */
.cloud-home-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 980px) { .cloud-home-grid { grid-template-columns: 1fr; } }

h1, h2, h3, .card-head h2 { font-family: var(--font-display); }

/* ==========================================================================
   Promotion banner
   ========================================================================== */

.promo {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-5);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--border));
  border-radius: var(--r-md);
  background: linear-gradient(100deg, color-mix(in srgb, var(--primary) 12%, var(--panel)), var(--panel) 60%);
  box-shadow: var(--shadow-1);
  transform: translateY(var(--pz, 0px));   /* js/parallax.js */
}
.promo::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--primary), var(--astro));
}
.promo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 42%, rgba(255,255,255,.06) 50%, transparent 58%);
  transform: translateX(-100%);
  animation: shimmer 6s var(--e-in-out) infinite;
}
.promo .gift {
  flex: none; width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--primary), var(--teal-bright));
  color: #04140f;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--primary) 45%, transparent);
  animation: nudge 4s var(--e-in-out) infinite;
}
@keyframes nudge {
  0%, 88%, 100% { transform: none; }
  92% { transform: rotate(-9deg) scale(1.06); }
  96% { transform: rotate(7deg) scale(1.06); }
}
.promo .txt { flex: 1 1 260px; min-width: 0; }
.promo .txt b { font-size: var(--t-lg); }
.promo .txt p { color: var(--label); font-size: var(--t-sm); }
.promo .act { display: flex; align-items: center; gap: var(--sp-2); position: relative; z-index: 1; }
.promo .code-in {
  width: 158px; height: 38px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--raised); color: var(--ink);
  font-family: var(--mono); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase;
}
.promo .code-in:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 18%, transparent);
}
.promo .dismiss { position: absolute; right: 8px; top: 8px; z-index: 1; }

/* ==========================================================================
   Popover -- ui.js's attachPopover(). Anchored, no backdrop, per
   docs/licencekeypopupwidget.md's own reasoning (§2 of that doc).
   ========================================================================== */

.popover {
  position: fixed; z-index: 140;
  width: 300px; max-width: calc(100vw - 24px);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-md);
  border: 1px solid var(--line-bright);
  background: var(--card);
  box-shadow: var(--shadow-4);
  opacity: 0; transform: scale(.95) translateY(-4px);
  transition: transform var(--dur-2) var(--e-out), opacity var(--dur-2) var(--e-out);
}
.popover.in { opacity: 1; transform: none; }

/* ---- Licence key popover content ---------------------------------------- */
.pop-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.pop-head .lab {
  font-family: var(--font-mono); font-size: var(--t-xs);
  text-transform: uppercase; letter-spacing: .14em; color: var(--muted);
}
.pop-key {
  padding: 12px 14px; margin-bottom: var(--sp-3);
  border-radius: var(--r-sm); background: var(--header); border: 1px solid var(--border);
}
.pop-key .key-val {
  font-size: var(--t-md); font-weight: 700; letter-spacing: .06em;
  word-break: break-all; color: var(--ink);
}
.pop-key .key-val.masked { color: var(--muted); font-weight: 600; }
.pop-act { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.popover .note { font-size: var(--t-xs); color: var(--muted); max-width: 40ch; }

.copied .ico-copy { display: none; }
.ico-check { display: none; }
.copied .ico-check { display: block; animation: pop-in var(--dur-2) var(--e-spring); }

/* ==========================================================================
   Module / kind cards
   ========================================================================== */

/* auto-fit, not a hardcoded column count: DHARA has four modules, TARANG
   has two kinds, and this one grid now serves both. */
.mods { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--sp-4); }

.mod {
  --accent: var(--primary);
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  padding: var(--sp-5) var(--sp-4) var(--sp-4);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  /* js/parallax.js's own scroll offset, composed with the hover lift below
     via calc() rather than overwritten by it -- see that file's own
     comment for why it never sets `transform` directly on an element that
     already has a hover transform of its own. */
  transform: translateY(var(--pz, 0px));
  transition: transform var(--dur-3) var(--e-out),
              box-shadow var(--dur-3) var(--e-out),
              border-color var(--dur-2) ease;
}
.mod::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 2px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 40%, white));
  transform: scaleX(.35); transform-origin: left;
  transition: transform var(--dur-3) var(--e-out);
}
.mod:hover {
  transform: translateY(calc(var(--pz, 0px) - 4px));
  box-shadow: var(--shadow-3);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}
.mod:hover::before { transform: scaleX(1); }
.mod::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(340px 150px at 82% -14%,
              color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%);
  opacity: 0; transition: opacity var(--dur-3) ease;
}
.mod:hover::after { opacity: 1; }

.mod > * { position: relative; z-index: 1; }

.mod .glyph {
  width: 44px; height: 44px; margin-bottom: var(--sp-3);
  display: grid; place-items: center;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--accent) 16%, var(--panel));
  color: var(--accent);
  transition: transform var(--dur-3) var(--e-spring);
}
.mod:hover .glyph { transform: scale(1.08) rotate(-4deg); }
.mod:not(.on) .glyph { background: var(--border-soft); color: var(--disabled); }

.mod h3 { font-size: var(--t-lg); font-weight: 600; letter-spacing: -.01em; }
.mod .blurb {
  font-size: var(--t-sm); color: var(--muted);
  margin: 6px 0 var(--sp-3); min-height: 3.1em;
}
.mod .params { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: var(--sp-4); }
.mod .params span {
  padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--border-soft); color: var(--label);
  font-family: var(--font-mono);
  font-size: 10.5px;
}
.mod .foot { margin-top: auto; }

.expiry { margin-bottom: var(--sp-3); }
.expiry .line { display: flex; justify-content: space-between; font-size: var(--t-xs); margin-bottom: 5px; }
.expiry .track { height: 5px; border-radius: 3px; background: var(--border-soft); overflow: hidden; }
.expiry .fill {
  height: 100%; border-radius: 3px;
  transform-origin: left center;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 55%, white));
  animation: fill-in var(--dur-4) var(--e-out) both;
}
@keyframes fill-in { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.expiry.soon .fill { background: linear-gradient(90deg, var(--warn), #f5d78a); }
.expiry.gone .fill { background: var(--danger); }

.mod.on  { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.mod:not(.on) h3 { color: var(--label); }

/* ==========================================================================
   Info cards (device / account / orders)
   ========================================================================== */

.cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); align-items: start; }
@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } }

.kv { display: grid; grid-template-columns: 148px 1fr; gap: 10px var(--sp-4); }
@media (max-width: 480px) { .kv { grid-template-columns: 1fr; gap: 2px var(--sp-4); } }
.kv dt { color: var(--muted); font-size: var(--t-sm); }
.kv dd { margin: 0; font-size: var(--t-md); word-break: break-word; }

.empty {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: var(--sp-6) var(--sp-4);
  text-align: center; color: var(--muted);
}
.empty .ring {
  width: 56px; height: 56px; display: grid; place-items: center;
  border-radius: 50%; background: var(--border-soft); color: var(--disabled);
}

table.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
table.tbl th {
  text-align: left; font-weight: 600; color: var(--muted); font-size: var(--t-xs);
  font-family: var(--font-mono);
  text-transform: uppercase; letter-spacing: .06em;
  padding: 0 var(--sp-3) 9px; border-bottom: 1px solid var(--border);
}
table.tbl td { padding: 12px var(--sp-3); border-bottom: 1px solid var(--border-soft); }
table.tbl tr:last-child td { border-bottom: 0; }
table.tbl tbody tr { transition: background var(--dur-1) ease; }
table.tbl tbody tr:hover { background: var(--header); }
.tbl-scroll { overflow-x: auto; }

.inline-edit { display: flex; gap: var(--sp-2); align-items: flex-start; }
.inline-edit input {
  flex: 1; min-height: 38px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--raised); color: var(--ink);
}
.inline-edit input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 16%, transparent);
}

.callout {
  display: flex; gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
}
.callout-warn { background: var(--amber-100); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); color: var(--warn-text); }
.callout-info { background: var(--primary-100); border: 1px solid color-mix(in srgb, var(--primary) 45%, transparent); color: var(--info-text); }
.callout-note { background: var(--header); border: 1px solid var(--border); color: var(--label); }
.callout .ico { flex: none; margin-top: 1px; }

/* ==========================================================================
   Purchase / package picker (Licence purchase modal, Cloud credit packages)
   ========================================================================== */

.pick {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 13px var(--sp-4); margin-bottom: 10px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  cursor: pointer;
  transition: border-color var(--dur-1) ease, background var(--dur-1) ease,
              transform var(--dur-2) var(--e-spring);
}
.pick:hover { border-color: color-mix(in srgb, var(--accent, var(--primary)) 55%, var(--border)); background: var(--header); }
.pick:has(input:checked) {
  border-color: var(--accent, var(--primary));
  background: color-mix(in srgb, var(--accent, var(--primary)) 12%, var(--panel));
}
.pick:has(input:disabled) { opacity: .55; cursor: not-allowed; }
.pick input { width: 18px; height: 18px; accent-color: var(--accent, var(--primary)); flex: none; }
.pick .nm { font-weight: 600; }
.pick .amt { margin-left: auto; font-family: var(--mono); font-size: var(--t-sm); }

.total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: var(--sp-4) 0 0; margin-top: var(--sp-3);
  border-top: 1px dashed var(--border);
}
.total b { font-size: var(--t-xl); font-family: var(--mono); }

/* ==========================================================================
   Downloads / support content
   ========================================================================== */

.dl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 760px) { .dl-grid { grid-template-columns: 1fr; } }

.dl {
  display: flex; gap: var(--sp-4); align-items: flex-start;
  padding: var(--sp-5);
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-1);
  transform: translateY(var(--pz, 0px));   /* js/parallax.js, see .mod's own comment */
  transition: transform var(--dur-3) var(--e-out), box-shadow var(--dur-3) var(--e-out);
}
.dl:hover { transform: translateY(calc(var(--pz, 0px) - 3px)); box-shadow: var(--shadow-3); }
.dl .os {
  width: 48px; height: 48px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-md); background: var(--header);
  border: 1px solid var(--border); color: var(--accent, var(--primary));
}
.dl h3 { font-size: var(--t-lg); font-weight: 600; }

/* help.html's Manuals tab: a real playable embed next to each manual link,
   not a redirect-out button (your instruction). Fixed 16:9 box regardless
   of the iframe's own intrinsic size. */
.video-embed {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: var(--r-sm); overflow: hidden;
  background: var(--void); border: 1px solid var(--border);
}
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.steps { counter-reset: s; }
.steps li {
  position: relative; counter-increment: s;
  padding: 0 0 var(--sp-5) var(--sp-6);
  border-left: 2px solid var(--border-soft);
  margin-left: 15px;
}
.steps li:last-child { border-left-color: transparent; padding-bottom: 0; }
.steps li::before {
  content: counter(s);
  font-family: var(--font-mono);
  position: absolute; left: -16px; top: -3px;
  width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 50%; background: var(--card);
  border: 2px solid var(--accent, var(--primary)); color: var(--accent, var(--primary));
  font-size: var(--t-sm); font-weight: 700;
}
.steps li b { display: block; margin-bottom: 3px; }
.steps li p { color: var(--muted); font-size: var(--t-sm); }

.prose { max-width: 74ch; }
.prose h2 { font-size: var(--t-xl); font-weight: 600; margin: var(--sp-6) 0 var(--sp-3); letter-spacing: -.02em; }
.prose h3 { font-size: var(--t-lg); font-weight: 600; margin: var(--sp-5) 0 var(--sp-2); }
.prose p, .prose li { color: var(--label); margin-bottom: var(--sp-3); }
.prose ul { list-style: disc; padding-left: var(--sp-5); }
.prose li { margin-bottom: 6px; }

/* ==========================================================================
   Footer
   ========================================================================== */

.foot {
  flex: none;
  border-top: 1px solid var(--border);
  background: var(--void);
}
.foot-in {
  max-width: 1180px; margin: 0 auto; padding: var(--sp-5);
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  align-items: center; justify-content: space-between;
  color: var(--muted); font-size: var(--t-sm);
}
.foot-in nav { display: flex; flex-wrap: wrap; gap: var(--sp-4); font-family: var(--font-mono); }
.foot-in a { color: var(--muted); }
.foot-in a:hover { color: var(--ink); }

/* ==========================================================================
   Mock-only developer panel. Never rendered when CONFIG.USE_MOCK is false.
   ========================================================================== */

.devbar {
  position: fixed; right: 16px; bottom: 16px; z-index: 90;
  width: 250px;
  border: 1px solid var(--line-bright); border-radius: var(--r-md);
  background: var(--void); color: var(--fog-200);
  box-shadow: var(--shadow-4);
  font-size: var(--t-sm);
  overflow: hidden;
}
.devbar summary {
  padding: 9px 13px; cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px;
  background: var(--raised); font-weight: 600;
}
.devbar summary::-webkit-details-marker { display: none; }
.devbar .body { padding: 11px 13px; display: grid; gap: 7px; }
.devbar button {
  width: 100%; padding: 7px 11px; text-align: left;
  border: 1px solid var(--line-bright); border-radius: var(--r-sm);
  background: var(--raised); color: var(--fog-200); cursor: pointer; font-size: var(--t-xs);
  transition: background var(--dur-1) ease, border-color var(--dur-1) ease;
}
.devbar button:hover { background: var(--line-bright); border-color: var(--fog-600); }
.devbar .hr { height: 1px; background: var(--line-bright); margin: 3px 0; }
.devbar .cap { color: var(--fog-500); font-size: 11px; text-transform: uppercase; letter-spacing: .07em; }
@media (max-width: 560px) { .devbar { display: none; } }

/* ==========================================================================
   Alerts
   ========================================================================== */

.alert {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px; margin-bottom: var(--sp-4);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  animation: pop-in var(--dur-2) var(--e-out);
}
.alert-bad  { background: var(--danger-100);  border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent);  color: var(--danger-text); }
.alert-ok   { background: var(--success-100); border: 1px solid color-mix(in srgb, var(--success) 45%, transparent); color: var(--success-text); }
.alert-info { background: var(--primary-100); border: 1px solid color-mix(in srgb, var(--primary) 45%, transparent); color: var(--info-text); }

/* ==========================================================================
   home.html: four full-width product bands, stacked vertically -- one per
   horizontal area, per your instruction (replaces the earlier tile grid).
   Alternating panel/void background is the "band section" device
   DESIGN.md itself uses (datasheet, trust strip). Image and copy swap
   sides on alternate bands so the page has rhythm rather than four
   identical rows.
   ========================================================================== */

.bands { position: relative; display: flex; flex-direction: column; }
.band {
  position: relative;
  display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: var(--sp-7);
  padding: var(--sp-7) 0;
  border-bottom: 1px solid var(--border);
}
.band:last-child { border-bottom: 0; }
.band:nth-child(even) .band-media { order: 2; }
@media (max-width: 860px) {
  .band { grid-template-columns: 1fr; gap: var(--sp-5); padding: var(--sp-6) 0; }
  .band:nth-child(even) .band-media { order: -1; }
}

.band-media {
  position: relative; overflow: hidden;
  border-radius: var(--r-md);
  border: 1px solid var(--line-bright);
  aspect-ratio: 16 / 11;
  background: var(--void);
  transform: translateY(var(--pz, 0px));   /* js/parallax.js -- only the img child has its own hover transform, so this container's is free */
  transition: border-color var(--dur-2) ease;
}
.band-media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.1s var(--e-out);
}
/* Per VS_BETA_V2_UI_CARRYOVER.md §1.2: .mod's lift+shadow register is for
   icon/glyph tiles -- a shadow lift over a real photo competes with the
   image instead of supporting it. These are photo-backed, so the quieter
   register applies here instead: the image's own slow zoom (already
   existed) plus the frame border tinting toward the product's accent,
   not a lift. */
.band:hover .band-media { border-color: color-mix(in srgb, var(--accent, var(--primary)) 45%, var(--line-bright)); }
.band:hover .band-media img { transform: scale(1.045); }
.band-media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 55%, color-mix(in srgb, var(--void) 75%, transparent));
  pointer-events: none;
}
.band-media .root {
  position: absolute; left: var(--sp-4); bottom: var(--sp-4); z-index: 1;
  font-family: var(--font-mono); font-size: var(--t-xs); letter-spacing: .12em;
  color: var(--fog-100);
}

.band-body .eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: .22em; color: var(--accent, var(--primary)); margin-bottom: var(--sp-3);
}
.band-body .eyebrow .sw { width: 8px; height: 8px; border-radius: 2px; background: var(--accent, var(--primary)); flex: none; }
.band-body h2 {
  font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 600; letter-spacing: -.02em;
  line-height: 1.12; margin-bottom: var(--sp-3);
}
.band-body .tagline { font-size: var(--t-lg); color: var(--fog-200); margin-bottom: var(--sp-3); max-width: 52ch; }
.band-body .equation {
  font-family: var(--font-mono); font-size: var(--t-sm); color: var(--fog-500);
  margin-bottom: var(--sp-4);
}
.band-feats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: var(--sp-5); }
.band-feats span {
  padding: 5px 11px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--panel);
  font-size: var(--t-xs); color: var(--fog-200);
}
.band-body .act { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }

.band.off .band-media { filter: grayscale(.6) brightness(.55); }
.band.off .band-media::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: color-mix(in srgb, var(--void) 45%, transparent);
}

/* ==========================================================================
   Per-product dashboard.html: Licence / Cloud / Support / Downloads tabs.
   --accent is set once per page (amber on dhara/dashboard.html, teal on
   tarang/dashboard.html), the same inline-custom-property convention .mod
   already uses per card.
   ========================================================================== */
.tabbar {
  display: flex; margin-bottom: var(--sp-5);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.tabbar button {
  position: relative;
  padding: 12px 4px; margin-bottom: -1px;
  border: 0; background: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--t-sm); font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .05em;
  white-space: nowrap;
  transition: color var(--dur-1) ease;
}
.tabbar button + button { margin-left: var(--sp-5); }
.tabbar button:hover { color: var(--ink); }
.tabbar button.on { color: var(--ink); }
.tabbar button.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--accent, var(--primary));
  border-radius: 2px 2px 0 0;
}
#content { position: relative; }
.tabpane { display: none; position: relative; }
.tabpane.on { display: block; animation: pane-in var(--dur-3) var(--e-out); }
@keyframes pane-in { from { opacity: 0; transform: translateY(8px); } }

/* ---- Cloud tab: credit balance ------------------------------------------ */
.credit-card {
  display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap;
  padding: var(--sp-5);
  border-radius: var(--r-md);
  background: linear-gradient(120deg,
    color-mix(in srgb, var(--accent, var(--primary)) 12%, var(--card)), var(--card));
  border: 1px solid var(--border);
  transform: translateY(var(--pz, 0px));   /* js/parallax.js */
}
.credit-card .num {
  font-family: var(--mono);
  font-size: var(--t-3xl); font-weight: 700;
  letter-spacing: -0.02em; color: var(--ink);
}
.credit-card .num small { font-family: var(--font); font-size: var(--t-md); font-weight: 600; color: var(--muted); margin-left: 6px; }
.credit-card .lab { color: var(--muted); font-size: var(--t-sm); }
.credit-plus  { color: var(--success-text); }
.credit-minus { color: var(--danger-text); }

/* ---- admin.html ---------------------------------------------------------- */
.admin-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-4); margin-bottom: var(--sp-5); }
@media (max-width: 900px) { .admin-grid { grid-template-columns: repeat(2, 1fr); } }
.admin-stat { padding: var(--sp-4); border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); }
.admin-stat .n { font-size: var(--t-2xl); font-weight: 700; font-family: var(--mono); }
.admin-stat .l { color: var(--muted); font-size: var(--t-sm); margin-top: 2px; }

/* ---- help.html's Contact tab: social links (moved from the retired contact.html) --- */
.social-row { display: flex; gap: var(--sp-2); margin-top: 14px; }
.social-link {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--raised); color: var(--muted);
  transition: background var(--dur-1) ease-out, color var(--dur-1) ease-out,
              transform var(--dur-1) ease-out;
}
a.social-link:hover { background: var(--border-soft); color: var(--ink); }
a.social-link:active { transform: scale(.92); transition-duration: 60ms; }
.social-link.is-off { opacity: .45; cursor: not-allowed; }
