/* Pratik — NervalFrost shell, the same tokens, frame, panel, cards and buttons
   as MoDoMiNo, Bòlètopoli and FotoLekti, with one thing of its own: the tape.

   The platform's two faces: Playfair Display for anything meant to be LOOKED at
   (the wordmark, money, a person's name), Inter for everything meant to be READ.
   Both from Google Fonts, which the CSP allows; the fallbacks are a serif and
   the system stack, so a phone with no network still reads correctly.

   No inline styles anywhere — the CSP has no 'unsafe-inline' in style-src. Bar
   widths and the frame transform are set through the CSSOM instead. */

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

/* CANON-LOCK [10]: the Palefò palette as RGB triplets, composed into the family gradient.
   Every NervalFrost alias below derives from these; a colour that is none of them is a deviation. */
:root {
  --accent-1-rgb: 95, 165, 250;      /* sky */
  --accent-2-rgb: 49, 86, 142;       /* navy: the reading ink */
  --accent-3-rgb: 26, 42, 62;        /* the tape's ground */
  --accent-purple-rgb: 167, 78, 222; /* the gradient's far end */
  --gradient-primary: linear-gradient(96deg, rgb(var(--accent-1-rgb)) 0%, rgb(var(--accent-purple-rgb)) 104%);
  --btn-shadow: 0 6px 18px rgba(167, 78, 222, 0.32);
  --nf-backdrop: #e3e5fa;
  --nf-frost: #f5f6fb;
  --nf-card: #ffffff;
  --nf-blue: rgb(var(--accent-2-rgb));
  --nf-purple: rgba(86, 44, 195, 0.85);
  --nf-purple-solid: #542CC2;
  --nf-tip-blue: #3f34e6;
  --nf-disc: rgba(84, 44, 194, 0.08);
  --nf-stroke-50: rgba(86, 44, 195, 0.5);
  --nf-frame-stroke: rgba(160, 140, 225, 0.5);
  --nf-hairline-25: rgba(160, 140, 225, 0.25);
  --nf-grad: var(--gradient-primary);
  --breather: 14px;
  --ember: #ff7a45;
  --ember-deep: #e04f1f;
  --hit-green: #2fb47c;
  --green-deep: #1f8a4c;
  --go-hi: #43d49f;           /* Bòlètopoli's play green, top of the gradient */
  --go-lo: #1f9a67;           /* …and its foot; the captions use it too */
  --go-soft-hi: #eefcf5;      /* the side buttons: the same green, washed out */
  --go-soft-lo: #c3f0da;
  --tile-ink: #4a3418;
  --ink-muted: #3a5280;
  /* Pratik's own: the market's two directions. Kept apart from the brand
     violet, because up and down must never be mistaken for a UI accent. */
  --up: #1f8a4c;
  --dn: #d21034;
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

html { font-size: 16px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  font-family: var(--font-body);
  width: 100vw; height: 100vh; height: 100dvh; overflow: hidden;
  display: flex; justify-content: center; align-items: center;
  background: linear-gradient(160deg, #ccd4f4 0%, #e3e5fa 45%, #ece2f6 75%, #f2e4f2 100%);
  color: var(--nf-blue);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* === DEVICE FRAME — 430×932 canvas, scaled by js/frame.js === */
/* CANON-LOCK [1]: 430×932 at ≥480px, edge-to-edge under it; the frame is the positioning context. */
.device-frame { width: 430px; height: 932px; max-width: 430px; max-height: 932px; position: relative; overflow: hidden; background: var(--nf-backdrop); transform-origin: center center; }
@media (max-width: 479px) { .device-frame { width: 100vw; height: 100vh; height: 100dvh; max-width: none; max-height: none; } }
@media (min-width: 480px) {
  body { background: linear-gradient(135deg, #ccd4f4 0%, #e3e5fa 45%, #ece2f6 75%, #f2e4f2 100%); }
  .device-frame { border-radius: 2.8rem; border: 0.7rem solid #0d0d0d; box-shadow: 0 1.8rem 4.5rem rgba(85, 70, 150, 0.35), 0 0.6rem 1.6rem rgba(85, 70, 150, 0.22), inset 0 0 0 1px rgba(255, 255, 255, 0.06); }
}
/* CANON-LOCK [2]: the glow behind all content — z-index 0, inert, a sky-blue radial at the top; the chrome (.dash-layout) sits at z-index 1. */
.bg-wrapper { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.bg-top { position: absolute; left: 50%; top: -18%; width: 140%; height: 62%; transform: translateX(-50%); border-radius: 50%; background: radial-gradient(closest-side, rgba(var(--accent-1-rgb), 0.28) 0%, rgba(var(--accent-1-rgb), 0.10) 55%, transparent 100%); }
.dash-layout { position: relative; z-index: 1; height: 100%; margin: 0 8px; padding: 8px 0 0; display: flex; flex-direction: column; }
.dash-panel { position: relative; flex: 1 1 auto; min-width: 0; min-height: 0; background: linear-gradient(180deg, #fafbfe 0%, #f2f3fb 48%, #e9e5f8 100%); border-radius: 25px; margin-bottom: 8px; overflow: clip; display: flex; flex-direction: column; padding: 18px 16px 16px; }

/* ================================================================= TAPE ===
   The band along the bottom, under the transport bar. One strip, rendered
   twice, translated -50%: the loop has no seam and the whole animation is one
   compositor transform. */
.ticker {
  /* The panel keeps the family's canon 18px/16px padding; the tape bleeds back
     out of it so it sits flush against the bottom edge, and borrows the panel's
     own corner radius so it does not square off the rounded corners. */
  position: relative; flex-shrink: 0;
  margin: 10px -16px -16px; padding: 6px 0;
  border-radius: 0 0 25px 25px;
  overflow: hidden;
  background: linear-gradient(180deg, #101b29 0%, #1a2a3e 100%);
  border-top: 1px solid rgba(160, 140, 225, 0.35);
  mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
  cursor: pointer;
}
.tk-track {
  display: flex; align-items: center; width: max-content;
  animation: tape var(--tk-dur, 30s) linear infinite;
  /* No will-change here. The track is several thousand pixels wide, and an
     animated transform already gets its own compositor layer — asking for one
     explicitly just pins a very large texture in GPU memory for the whole
     session, on phones that have little of it. */
}
@keyframes tape { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(calc(-1 * var(--tk-span, 50%)), 0, 0); } }
.ticker.is-held .tk-track { animation-play-state: paused; }

.tk-item {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 2px 13px;
  font-family: var(--font-body); font-size: 0.78rem; line-height: 1.5;
  color: #dfe6f5; white-space: nowrap;
  border-right: 1px solid rgba(255, 255, 255, 0.07);
}
.tk-ico { font-size: 0.86rem; }
.tk-name { font-weight: 600; letter-spacing: 0.01em; }
.tk-arrow { font-size: 0.72rem; }
.tk-price { font-variant-numeric: tabular-nums; opacity: 0.85; }
.tk-pct { font-weight: 700; font-variant-numeric: tabular-nums; }
.tk-item.up .tk-arrow, .tk-item.up .tk-pct { color: #57e39a; }
.tk-item.dn .tk-arrow, .tk-item.dn .tk-pct { color: #ff7b8f; }
.tk-item.flat .tk-arrow, .tk-item.flat .tk-pct { color: rgba(223, 230, 245, 0.5); }
.tk-item.tk-hot .tk-name { color: #ffd66b; }
.tk-item.tk-hot::after { content: '!'; color: #ffd66b; font-weight: 800; }
.tk-item.tk-hot { animation: tkHot 1.1s ease 2; }
@keyframes tkHot { 0%, 100% { transform: scale(1); filter: none; } 50% { transform: scale(1.09); filter: brightness(1.25); } }
/* 5: hit areas of at least 36px, whatever the glyph's size */
.tk-item { position: relative; }
.tk-item::before { content: ''; position: absolute; inset: -9px 0; }
.tk-flash { animation: tkFlash 1.1s ease; }
@keyframes tkFlash { 0%, 100% { background: transparent; } 30% { background: rgba(255, 214, 107, 0.22); } }

/* =================================================================== HUD === */
.top-bar { position: relative; display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }
/* Bòlètopoli's header (2026-09-23): the icon strip alone on the top row, flush
   under the panel's edge; the day, the town and the purse on a second row. */
.tb-row { position: relative; display: flex; align-items: center; gap: 8px; min-height: 34px; }
.hud-left { display: flex; flex-direction: column; line-height: 1.1; flex: 0 0 auto; }
/* The day and the load side by side (2026-09-23): what day it is and how full the roof is are one glance. */
.hud-day-row { display: flex; align-items: center; gap: 7px; }
.hud-day { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--nf-purple-solid); white-space: nowrap; }
.hud-city { font-family: var(--font-display); font-style: italic; font-size: 1.19rem; line-height: 1.05; color: var(--nf-purple-solid); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb-icons { display: flex; align-items: center; gap: 6px; margin-left: auto; flex: 0 0 auto; }
/* The info row: the town is the one thing that yields, and it ellipsises. The
   purse is a column, the load under the chip the way Bòlètopoli's "lib" sits. */
.tb-row--info { align-items: flex-end; min-height: 0; }
.tb-row--info .hud-left { flex: 1 1 auto; min-width: 0; padding-bottom: 4px; }
.hud-load { font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em; color: var(--ink-muted); padding: 2px 8px; border-radius: 999px; background: var(--nf-disc); font-variant-numeric: tabular-nums; }
.hud-load.full { color: #fff; background: var(--ember-deep); }
/* What you owe, under the purse: Bòlètopoli's debt badge. Only there when there is a debt. */
.hud-dwe { margin-top: 3px; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.03em; color: var(--ember-deep); background: rgba(224, 79, 31, 0.10); padding: 2px 8px; border-radius: 999px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Pwogresyon: a card whose mechanic has not opened yet says the day. */
.lock-note { color: var(--ink-muted); font-size: 0.72rem; }
/* A live figure in a folded card's title (Bòlètopoli's livetit): shown only when the card is closed. */
h3 .fold-live { display: none; margin-left: auto; margin-right: 6px; font-family: var(--font-body); font-style: normal; font-weight: 600; font-size: 0.7rem; letter-spacing: 0; text-transform: none; color: var(--ink-muted); white-space: nowrap; }
.card.is-closed h3 .fold-live { display: inline; }
/* The "?" (ednot): a small round button in the heading, and the note under it. */
.note-btn { position: relative; width: 20px; height: 20px; margin-left: 6px; border-radius: 50%; border: 1px solid var(--nf-stroke-50); background: var(--nf-disc); color: var(--nf-purple-solid); font-size: 0.68rem; font-weight: 800; line-height: 1; cursor: pointer; flex: 0 0 auto; }
.note-btn.is-on { background: var(--nf-purple-solid); color: #fff; border-color: transparent; }
.note-btn::before { content: ''; position: absolute; inset: -9px; }
/* 12: the pause sits in the same round frame as the arrow */
.pause-btn svg { width: 18px; height: 18px; }
.pause-btn[aria-pressed="true"] { background: var(--nf-purple-solid); color: #fff; border-color: transparent; }
.card-note { margin: 0 0 8px; padding: 8px 10px; border-radius: 10px; background: var(--nf-disc); font-size: 0.76rem; line-height: 1.45; color: var(--nf-blue); }
/* The reading face (Paramèt → Ekriti). */
html[data-font="lizib"] { --font-body: 'Atkinson Hyperlegible', 'Inter', system-ui, sans-serif; }
html[data-font="chale"] { --font-body: 'Fraunces', 'Inter', Georgia, serif; }
/* Your name on the front page, with your face beside it. */
.home-non { display: flex; align-items: center; gap: 8px; margin: 10px auto 0; max-width: 300px; }
.home-non span { font-size: 1.4rem; }
.home-non .input { flex: 1 1 auto; }
.chip.face { font-size: 1.15rem; padding: 4px 10px; }
/* The front page's live line: who is around, and the busiest sezon to walk into. */
.home-live { margin: 8px 0 0; text-align: center; font-size: 0.76rem; line-height: 1.6; color: var(--ink-muted); }
.home-live[hidden] { display: none; }
.home-live .chip { padding: 2px 10px; font-size: 0.7rem; margin-left: 4px; vertical-align: middle; }
/* The record against a friend on the sezon roster: "2–1". */
.h2h { font-style: normal; font-size: 0.68rem; font-weight: 700; color: var(--nf-purple-solid); background: var(--nf-disc); padding: 1px 6px; border-radius: 999px; margin-left: 4px; font-variant-numeric: tabular-nums; }
html[data-theme="nwa"] .card-note { color: #b9c3e6; }
.lock-note b { color: var(--nf-purple-solid); }
/* Misyon: three rows, done ones ticked. */
.misyon-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--nf-hairline-25); font-size: 0.82rem; }
.misyon-row:first-of-type { border-top: none; }
.misyon-row .tick { width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.72rem; font-weight: 800; background: var(--nf-disc); color: var(--ink-muted); flex: 0 0 auto; }
.misyon-row.is-done .tick { background: rgba(47, 180, 124, 0.18); color: var(--green-deep); }
.misyon-row.is-done span { color: var(--ink-muted); text-decoration: line-through; }
/* The paper: a dateline and headlines. */
.jounal-date { font-family: var(--font-display); font-style: italic; color: var(--nf-purple-solid); font-size: 0.9rem; margin: 0 0 6px; }
.jounal-row { display: flex; gap: 8px; padding: 5px 0; border-top: 1px solid var(--nf-hairline-25); font-size: 0.82rem; line-height: 1.4; }
.jounal-row:first-of-type { border-top: none; }
.jounal-row i { font-style: normal; flex: 0 0 auto; }
html[data-theme="nwa"] .hud-dwe { background: rgba(255, 106, 61, 0.16); }
html[data-theme="nwa"] .misyon-row.is-done .tick { background: rgba(79, 214, 154, 0.18); color: #6fe0aa; }
/* The purse. The gold tile is the family's, and it is the last thing on the
   row: the eye lands on it and stays. */
.hud-money { position: relative; display: flex; flex-direction: column; align-items: flex-end; flex: 0 0 auto; margin-left: auto; }
.hud-chip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 14px 13px 13px; border-radius: 15px;   /* 20% up (2026-09-22); a third up, then taller (2026-09-23) */
  background: linear-gradient(150deg, #fdf3da 0%, #f5e2b6 62%, #ecd29a 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.75), inset 0 -2px 3px rgba(140,96,40,0.35), 0 2px 8px rgba(60,30,100,0.18);
  font-size: 1.57rem; line-height: 1; color: var(--tile-ink); font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* The unit, and under it what KIND of money this is. Two lines out of one
   pseudo-element because the figure is written with textContent, which would
   wipe any real child put inside the chip. Saying "jwèt" out loud is the point:
   nobody should ever wonder whether these are real goud. */
.hud-chip::after {
  content: 'GOUD\Ajwèt'; white-space: pre; text-align: center; align-self: center;
  line-height: 1.06; font-size: 0.55rem; font-weight: 700; letter-spacing: 0.09em;
  text-indent: 0.09em; color: rgba(74, 52, 24, 0.6);
}
/* In the black or in the red, Bòlètopoli's two chips. */
.hud-chip.pos { background: linear-gradient(150deg, #e3f7e8 0%, #c9efd5 62%, #b4e5c3 100%); color: #1f5e3a; box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 3px rgba(40,110,70,0.25), 0 2px 8px rgba(40,110,70,0.18); }
.hud-chip.pos::after { color: rgba(31, 94, 58, 0.65); }
.hud-chip.neg { background: linear-gradient(150deg, #fde6e6 0%, #f7cdcd 62%, #f0b6b6 100%); color: #7a1f1f; box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 3px rgba(150,40,40,0.25), 0 2px 8px rgba(150,40,40,0.18); }
.hud-chip.neg::after { color: rgba(122, 31, 31, 0.65); }
/* When money moves the chip flashes to 2.5×, grown from its right edge so it
   swells into the HUD rather than off the frame. Same curve as Bòlètopoli. */
.hud-chip { position: relative; z-index: 5; transform-origin: right center; }
.hud-chip.is-bump { animation: cashFlash 1.46s cubic-bezier(0.2, 0.9, 0.3, 1.2); }   /* 0.75s ×1.3 ×1.5 (2026-09-22) */
@keyframes cashFlash { 0% { transform: scale(1); } 35% { transform: scale(2.5) rotate(-1.5deg); } 65% { transform: scale(1.15); } 100% { transform: scale(1); } }

/* The delta, floating off the purse. Bòlètopoli drifts it upward because its
   chip sits below a hero; here the purse is in the top bar, 18px under the
   panel's edge, and `overflow: clip` would eat it, so it drifts down instead. */
.cash-float {
  position: absolute; right: 2px; top: 100%; z-index: 30;
  font-size: 0.92rem; font-weight: 700; white-space: nowrap; pointer-events: none;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(255,255,255,0.9);
  animation: cashFloat 1.1s ease-out forwards;
}
.cash-float.up { color: var(--hit-green); }
.cash-float.down { color: var(--ember-deep); }
@keyframes cashFloat {
  0%   { opacity: 0; transform: translateY(-6px); }
  20%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(22px); }
}
/* The top bar's round controls are one disc — FotoLekti's gear: a raised lavender coin, the same size on both sides of the bar, so the row reads as one piece. */
.sound-btn { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 50%; border: 1px solid var(--nf-frame-stroke); background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); color: var(--nf-purple-solid); box-shadow: 0 3px 10px rgba(60, 30, 100, 0.10); transition: color 0.2s ease, transform 0.2s ease, background 0.2s ease; }
.sound-btn svg { width: 19px; height: 19px; }
.sound-btn:hover { background: var(--nf-disc); }
.sound-btn:active { transform: scale(0.9); }

/* ================================================================= VOICE ===
   The soundwave is the family's canon choreography: it opens only while the
   Kreyòl voice is actually speaking (js/tts.js sets body.speaking around a
   line), so the app visibly *has* a voice rather than just making noise. */
.soundwave { height: 0; opacity: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; gap: 3px; transition: height 300ms ease, opacity 300ms ease; flex-shrink: 0; }
body.speaking .soundwave { height: 24px; opacity: 1; margin-top: 2px; }
.soundwave-bar { width: 4px; height: 6px; border-radius: 2px; background: var(--nf-grad); animation: barBounce var(--bar-speed, 0.6s) ease-in-out infinite alternate; animation-delay: var(--bar-delay, 0s); }
.soundwave-bar:nth-child(3n+1) { --bar-speed: 0.55s; } .soundwave-bar:nth-child(3n+2) { --bar-speed: 0.72s; } .soundwave-bar:nth-child(3n) { --bar-speed: 0.46s; }
.soundwave-bar:nth-child(5n+1) { --bar-delay: 0s; } .soundwave-bar:nth-child(5n+2) { --bar-delay: 0.12s; } .soundwave-bar:nth-child(5n+3) { --bar-delay: 0.06s; } .soundwave-bar:nth-child(5n+4) { --bar-delay: 0.16s; }
@keyframes barBounce { from { height: 5px; } to { height: 20px; } }

/* Each control shows its own state: a slash through the icon when it is off. */
.sound-btn .sound-off, .music-btn .music-off { display: none; }
.music-btn.is-off .music-on { display: none; }
.music-btn.is-off .music-off { display: block; }
.music-btn.is-off { color: rgba(86, 44, 195, 0.45); }

/* The two levels, under the top-bar icons. */
/* CANON-LOCK [12]: frosted-glass chrome — the popover is translucent glass over the wash, with a faint sky border. */
.vol-pop {
  position: absolute; top: 42px; right: 0; z-index: 40; width: 258px;
  padding: 10px 12px; border-radius: 14px;
  background: rgba(255, 255, 255, 0.78); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border: 1px solid rgba(var(--accent-1-rgb), 0.28);
  box-shadow: 0 10px 28px rgba(28, 16, 74, 0.18);
  display: flex; flex-direction: column; gap: 8px;
}
.vol-row { display: flex; align-items: center; gap: 8px; }
.vol-mute { width: 30px; height: 30px; flex: 0 0 auto; }
.vol-mute svg { width: 19px; height: 19px; }
.vol-label { font-size: 0.74rem; color: var(--nf-blue); flex: 0 0 38px; cursor: pointer; }
.vol-num { font-size: 0.7rem; color: var(--ink-muted); flex: 0 0 26px; text-align: right; font-variant-numeric: tabular-nums; }
.vol-range { flex: 1 1 auto; min-width: 0; height: 22px; margin: 0; background: none; -webkit-appearance: none; appearance: none; cursor: pointer; }
.vol-range::-webkit-slider-runnable-track { height: 5px; border-radius: 999px; background: rgba(86, 44, 195, 0.18); }
.vol-range::-moz-range-track { height: 5px; border-radius: 999px; background: rgba(86, 44, 195, 0.18); }
.vol-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 15px; height: 15px; margin-top: -5px; border-radius: 50%; background: var(--nf-purple-solid); border: 2px solid #fff; box-shadow: 0 1px 3px rgba(28, 16, 74, 0.3); }
.vol-range::-moz-range-thumb { width: 15px; height: 15px; border-radius: 50%; background: var(--nf-purple-solid); border: 2px solid #fff; box-shadow: 0 1px 3px rgba(28, 16, 74, 0.3); }
.vol-range:focus-visible { outline: 2px solid var(--nf-purple-solid); outline-offset: 3px; border-radius: 999px; }
.vol-note { margin: 0; font-size: 0.64rem; line-height: 1.4; color: var(--ink-muted); opacity: 0.9; }

.sound-btn .sound-off { display: none; }
.sound-btn.is-muted .sound-on { display: none; }
.sound-btn.is-muted .sound-off { display: block; }
.sound-btn.is-muted { color: rgba(86, 44, 195, 0.45); }
/* The ear, live: the one control that must be unmistakable mid-sentence. */
.mic-tb.live { color: var(--ember-deep); animation: micPulse 1.1s infinite; }
@keyframes micPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(1.12); } }
.chip.mic { border-color: rgba(63,52,230,0.4); background: rgba(63,52,230,0.07); color: var(--nf-tip-blue); }
.mic-row { margin-bottom: 4px; }

/* ================================================================ SCREEN === */
.screen { display: none; flex: 1 1 auto; min-height: 0; flex-direction: column; animation: screenIn 0.28s ease; overflow-y: auto; scrollbar-width: none; padding-top: 2px; }
.screen::-webkit-scrollbar { display: none; }
.screen.is-active { display: flex; }
@keyframes screenIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ================================================================== HOME === */
/* The hero. The picture is 16:9 but the home screen wants something closer to a
   square, so the box crops it and object-position keeps Lisyènn — who is on the
   right of the frame — in shot at every width. */
.home-hero { margin-top: 8px; display: flex; justify-content: center; flex-shrink: 0; }
.home-hero img {
  width: 100%; max-width: 430px; aspect-ratio: 8 / 5;
  height: auto; object-fit: cover; object-position: center 42%;
  border-radius: 22px;
  box-shadow: 0 0.8rem 1.8rem rgba(85,70,150,0.22), 0 0.3rem 0.7rem rgba(86,44,195,0.12);
}
.home-title { margin-top: 16px; text-align: center; flex-shrink: 0; }
/* CANON-LOCK [11]: the wordmark — one word, Playfair italic, the family gradient clipped to the text. */
.wordmark {
  font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 3.1rem; letter-spacing: 0.01em;
  background: var(--gradient-primary); -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Two lines, always: who she is, then what she does. Letting them reflow put
   the break in the middle of "madan sara", which is the one phrase that must
   read as one thing. */
.home-sub { margin-top: 7px; text-align: center; font-size: 0.88rem; font-weight: 600; line-height: 1.45; color: var(--nf-purple-solid); }
.home-sub span { display: block; }
.home-sub span:last-child { font-weight: 500; color: rgba(84, 44, 194, 0.75); }
.mode-cards { margin-top: 20px; display: flex; flex-direction: column; gap: var(--breather); }
.mode-card { position: relative; display: flex; align-items: center; gap: 14px; width: 100%; padding: 14px; background: var(--nf-card); border: 1px solid var(--nf-frame-stroke); border-radius: 18px; text-align: left; color: var(--nf-blue); box-shadow: 0 2px 10px rgba(60,30,100,0.06); transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background-color 0.2s ease; }
.mode-card:hover:not(:disabled) { transform: translateY(-2px); border-color: rgba(109,138,255,0.6); box-shadow: 0 6px 18px rgba(60,30,100,0.12); background: #e4efff; }
.mode-card:active:not(:disabled) { transform: scale(0.98); }
.mode-card.is-off, .mode-card:disabled { opacity: 0.45; cursor: default; }
/* A season already going: it leads, and it says where you left off. */
.mode-card.is-live { border-color: var(--nf-stroke-50); background: linear-gradient(160deg, #fff 0%, #f2ecff 100%); box-shadow: 0 4px 16px rgba(84,44,194,0.16); }
.mode-card.is-live .mode-card__glyph { background: var(--nf-grad); color: #fff; font-size: 1rem; }
.mode-card__glyph { width: 46px; height: 46px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: linear-gradient(160deg, #fff 0%, #ece6fb 100%); border: 1px solid var(--nf-frame-stroke); box-shadow: 0 3px 10px rgba(84, 44, 194, 0.12), inset 0 1px 0 #fff; font-size: 1.35rem; }
.mode-card__body { flex: 1 1 auto; min-width: 0; }
.mode-card__name { display: block; font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 1.06rem; color: var(--nf-purple-solid); }
.mode-card__desc { display: block; margin-top: 3px; font-size: 0.74rem; line-height: 1.4; color: rgba(49,86,142,0.72); }
.mode-card__chev { width: 18px; height: 18px; flex-shrink: 0; color: var(--nf-stroke-50); }
.home-links { margin-top: 18px; display: flex; justify-content: center; gap: 10px; flex-shrink: 0; }
.klasman-link { padding: 8px 18px; border: 1px solid var(--nf-frame-stroke); border-radius: 999px; background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); color: var(--nf-purple-solid); font-size: 0.82rem; font-weight: 700; box-shadow: 0 2px 10px rgba(60,30,100,0.06); display: inline-flex; align-items: center; gap: 6px; }
.klasman-link:hover { background: var(--nf-disc); border-color: var(--nf-stroke-50); }
.home-best { margin-top: auto; padding-top: 14px; text-align: center; font-size: 0.72rem; font-weight: 600; color: rgba(86,44,195,0.55); }

/* ================================================================== CARDS === */
.card { position: relative; margin-top: var(--breather); padding: 15px 14px; background: var(--nf-card); border: 1px solid var(--nf-frame-stroke); border-radius: 18px; box-shadow: 0 2px 10px rgba(60,30,100,0.06); flex-shrink: 0; }
.card:first-child { margin-top: 6px; }
.card h3 { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(49,86,142,0.6); margin-bottom: 8px; display: flex; align-items: baseline; gap: 6px; }
.card h3 i { font-style: normal; font-weight: 400; letter-spacing: 0; text-transform: none; color: rgba(49,86,142,0.45); }
.card :where(p) { font-size: 0.86rem; line-height: 1.5; color: rgba(49,86,142,0.85); }
.muted { color: rgba(49,86,142,0.6); font-size: 0.82rem; }
.kv { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--nf-hairline-25); font-size: 0.85rem; }
.kv:last-child { border-bottom: none; }
.kv b { font-weight: 400; color: var(--nf-blue); font-variant-numeric: tabular-nums; }
.kv i, .kv span i { font-style: normal; font-size: 0.68rem; color: rgba(49,86,142,0.55); }
.good { color: var(--up) !important; } .bad { color: var(--dn) !important; }
.choice { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 0; }
/* A chip is a small raised pill, the same finish as the round controls. `.on` is the chosen one and takes the family gradient like a tab; `.go` is money moving (a buy, a sale, an offer) and keeps the market's green (CANON [13]). */
.chip { padding: 6px 12px; border-radius: 999px; background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); border: 1px solid var(--nf-frame-stroke); box-shadow: 0 2px 6px rgba(60, 30, 100, 0.07); font-size: 0.74rem; font-weight: 700; color: var(--nf-purple-solid); font-variant-numeric: tabular-nums; transition: transform 0.12s ease, background 0.18s ease, box-shadow 0.18s ease; }
.chip:active:not(:disabled) { transform: scale(0.94); }
.chip:disabled { opacity: 0.4; cursor: default; }
.chip.on { background: var(--gradient-primary); color: #fff; border-color: transparent; box-shadow: var(--btn-shadow); }
.chip.go { background: linear-gradient(96deg, #3fd0a0 0%, var(--hit-green) 100%); color: #fff; border-color: transparent; box-shadow: 0 4px 12px rgba(31, 154, 103, 0.28); }
.chip.warn { color: var(--ember-deep); border-color: rgba(224,79,31,0.4); background: rgba(224,79,31,0.08); }
.chip.credit { color: #8a6a00; border-color: rgba(224,160,32,0.5); background: rgba(224,160,32,0.12); }
.chip.known { border-color: var(--nf-tip-blue); }
.hint { margin-top: 10px; padding: 9px 11px; border-radius: 12px; background: var(--nf-disc); border: 1px solid var(--nf-hairline-25); font-size: 0.78rem; line-height: 1.45; color: var(--nf-blue); }
.hint.bad { background: rgba(224,79,31,0.08); border-color: rgba(224,79,31,0.3); }
.set-note { margin: 7px 0 0; font-size: 0.78rem; line-height: 1.45; color: var(--ink-muted); opacity: 0.95; }
.reg-lnk { border: none; background: none; padding: 0; margin: 0; font: inherit; color: var(--nf-purple-solid); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }   /* a link inside the rules ([text](jump:id) in marks) */
.strateji h4[id] { scroll-margin-top: 12px; }
/* Kredi: the people behind the market, as MoDoMiNo lists them under the build stamp. Role muted, name bold: the line reads as one sentence and the eye lands on the name. */
.set-sub { margin: 12px 0 2px; font-size: 0.62rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); text-align: center; }
.set-credits { list-style: none; margin: 0; padding: 0; text-align: center; }
.set-credits li { font-size: 0.74rem; line-height: 1.75; color: var(--nf-blue); }
.set-credits span { opacity: 0.55; font-weight: 500; }
.set-credits b { font-weight: 700; }
.set-credits__own { margin-top: 6px; opacity: 0.8; }
.mt { margin-top: 12px; } .mt-s { margin-top: 8px; }
.grow { flex: 1 1 auto; min-width: 0; }

.btn { width: 100%; margin-top: 10px; padding: 13px 14px; border-radius: 16px; background: var(--nf-grad); box-shadow: 0 6px 18px rgba(167,78,222,0.32); color: #fff; font-size: 0.94rem; font-weight: 700; transition: transform 0.15s ease, filter 0.2s ease; }
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.45; cursor: default; }
.btn.ghost { border: 1px solid var(--nf-frame-stroke); background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); color: var(--nf-purple-solid); box-shadow: none; }
.btn.sm { width: auto; margin-top: 8px; padding: 8px 12px; font-size: 0.78rem; border-radius: 11px; }

/* ── foldable cards: the heading is the toggle ──
   The Mache tab alone lists twenty-odd goods; a trader who deals in grain
   folds the rest away once and it stays folded. The chevron is the only
   affordance, so the heading also reads as a control: heavier, in brand
   violet, with a pointer. */
.fold-h { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; -webkit-user-select: none; font-weight: 800; color: var(--nf-purple-solid) !important; }
.fold-h .chev { margin-left: auto; color: var(--nf-purple-solid); font-size: 0.78rem; line-height: 1; transition: transform 0.18s ease; }
.fold-h .chev::before { content: '▾'; }
.card.is-closed .fold-h .chev::before { content: '▸'; }
.fold-h:focus-visible { outline: 2px solid var(--nf-stroke-50); outline-offset: 3px; border-radius: 6px; }
/* Everything but the heading goes; the card collapses to one line. */
.card.is-closed > :not(.fold-h) { display: none !important; }
.card.is-closed { padding-top: 13px; padding-bottom: 13px; }
.card.is-closed .fold-h { margin-bottom: 0; }

/* ================================================================= MACHE === */
.town-card { background: linear-gradient(160deg, #fff 0%, #f7f4ff 100%); }
.town-name { font-family: var(--font-display); font-style: italic; font-size: 1.6rem; line-height: 1.1; color: var(--nf-purple-solid); }
.town-mood { margin-top: 4px; font-size: 0.78rem; line-height: 1.45; color: rgba(49,86,142,0.72); font-style: italic; }
.fet-band { margin-top: 10px; padding: 8px 11px; border-radius: 12px; font-size: 0.76rem; font-weight: 600; line-height: 1.4; color: #7a4a00; background: linear-gradient(150deg, #fff6d9 0%, #ffe9a8 100%); border: 1px solid rgba(224,160,32,0.4); }
.kat-head { margin: 12px 0 2px; font-size: 0.64rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(49,86,142,0.5); }
.gd-row { flex-wrap: wrap; row-gap: 4px; }
.gd-id { flex: 1 1 140px; min-width: 0; }
.gd-mine { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 999px; background: var(--nf-disc); color: var(--nf-purple-solid); font-size: 0.7rem; font-weight: 700; }
.gd-life { margin-left: 4px; }
.gd-acts { margin: 0; flex: 0 0 auto; align-items: center; }
.gd-price { min-width: 48px; text-align: right; font-weight: 400; font-variant-numeric: tabular-nums; }
/* The row the tape pointed at: a violet wash that fades over 2.5 s, and a bar on its left so the eye lands before the wash is gone. */
.pulse { animation: rowPulse 2.5s ease; }
.pulse td { animation: rowPulseCell 2.5s ease; }
.pulse td:first-child { box-shadow: inset 4px 0 0 var(--nf-purple-solid); }
@keyframes rowPulse { 0%, 100% { background: transparent; } 20% { background: rgba(84,44,194,0.22); } 70% { background: rgba(84,44,194,0.12); } }
@keyframes rowPulseCell { 0%, 100% { background: transparent; } 20% { background: rgba(84,44,194,0.22); } 70% { background: rgba(84,44,194,0.12); } }
html[data-theme="nwa"] .pulse td:first-child { box-shadow: inset 4px 0 0 #cfc4ff; }

/* ── the strip of faces above the market ── */
.pk-strip-card { padding-bottom: 11px; }
/* The people, one under the other (2026-09-23): a vertical list that scrolls
   inside the card past four rows, so a town with many faces never pushes the
   market off the screen, and no name is ever cut off at the right edge. */
.pk-strip { display: flex; flex-direction: column; gap: 6px; max-height: 232px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; padding: 2px 0 2px; -webkit-overflow-scrolling: touch; }
.pk-strip::-webkit-scrollbar { display: none; }
.pk-chip { flex: 0 0 auto; width: 100%; display: flex; align-items: center; gap: 10px; padding: 6px 13px 6px 7px; border-radius: 14px; border: 1px solid var(--nf-hairline-25); background: #fff; white-space: nowrap; text-align: left; transition: transform 0.14s ease, border-color 0.18s ease; }
.pk-chip:active { transform: scale(0.96); }
.pk-chip.is-close { border-color: var(--nf-stroke-50); background: linear-gradient(160deg, #fff 0%, #f4efff 100%); }
.pk-chip-face { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--nf-disc); font-size: 1.05rem; }
.pk-chip-id { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2; }
.pk-chip-id b, .pk-chip-id i { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.pk-chip-id b { font-family: var(--font-body); font-style: normal; font-weight: 600; font-size: 0.9rem; color: var(--nf-purple-solid); }
.pk-chip-id i { font-style: normal; font-size: 0.6rem; color: rgba(49,86,142,0.6); }
/* The reputation, at a glance. Amber rather than the brand violet: it is a
   fact about the person, not a control. */
.pk-stars { color: #e0a020; letter-spacing: 0.06em; font-size: 0.62rem !important; line-height: 1.1; }

/* The three ratings in full, on the person's own card. */
.pk-rates { display: flex; flex-wrap: wrap; gap: 4px 10px; margin: 8px 0 2px; }
.pk-rate { font-size: 0.64rem; color: rgba(49,86,142,0.7); white-space: nowrap; }
.pk-rate b { color: #e0a020; letter-spacing: 0.04em; font-weight: 400; }
/* Nothing on the stall today: the row stays, so you can see they deal in it. */
.pk-row.is-empty { opacity: 0.45; }

/* ── a pratik's offer, on the row where the decision is made ── */
.pk-offer { flex: 1 1 100%; display: flex; align-items: center; gap: 6px; margin-top: 4px; padding: 6px 11px; border-radius: 999px; border: 1px solid rgba(84,44,194,0.22); background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); box-shadow: 0 2px 6px rgba(60, 30, 100, 0.07); font-size: 0.7rem; color: var(--nf-purple-solid); text-align: left; }
.pk-offer b { font-weight: 700; font-variant-numeric: tabular-nums; margin-left: auto; }
.pk-offer:active { transform: scale(0.985); }
.pk-offer.sell { border-color: rgba(47,180,124,0.35); background: rgba(47,180,124,0.09); color: var(--green-deep); }
/* 2: the best trade as the one thing to press — buy the load and open the road. */
.pk-offer.kou { border-color: rgba(84,44,194,0.35); background: linear-gradient(135deg, rgba(84,44,194,0.10) 0%, rgba(167,78,222,0.10) 100%); color: var(--nf-purple-solid); font-weight: 700; padding: 8px 12px; }
.pk-offer.kou b { color: var(--green-deep); }
/* 3: a stepper per row — − n + — and one button that says what it buys and for how much. */
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--nf-stroke-50); border-radius: 999px; background: var(--nf-card); overflow: hidden; }
.stepper .st { width: 30px; height: 28px; border: none; background: transparent; color: var(--nf-purple-solid); font-size: 1.05rem; font-weight: 700; line-height: 1; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.stepper .st:active { background: var(--nf-disc); }
.stepper .st[disabled] { opacity: 0.3; }
.stepper b { min-width: 22px; text-align: center; font-size: 0.86rem; font-variant-numeric: tabular-nums; color: var(--nf-blue); user-select: none; }
.gd-acts .chip.buy { font-variant-numeric: tabular-nums; }
.chip.wa { background: #25d366; color: #fff; border-color: transparent; }
.trip.is-off .trip-body i .bad { color: var(--ember-deep); font-style: normal; }
/* 9: a coin from the row to the purse on every sale. Outside the frame, so it is not scaled twice. */
.coin { position: fixed; z-index: 90; font-size: 22px; pointer-events: none; will-change: transform; filter: drop-shadow(0 2px 3px rgba(0,0,0,0.25)); }
/* 1: the end as a moment — the card is the hero, the number counts up, one next thing to press. */
.over .worth { transition: none; }
.over .end-next { margin-top: 12px; }
.btn.go { background: linear-gradient(135deg, var(--go-hi) 0%, var(--go-lo) 100%); box-shadow: 0 8px 20px rgba(31, 154, 103, 0.35); }
/* 8: the front door — a live strip of today's market, one big green button, the other modes as chips. */
.home-go { margin-top: 12px; padding: 15px 16px; font-size: 1.02rem; display: flex; align-items: center; justify-content: center; gap: 10px; }
.home-go i { font-style: normal; font-weight: 500; font-size: 0.8rem; opacity: 0.9; }
.home-modes { margin-top: 12px; }
/* 6: the road you would take, lit, and the fare at its end; towns tinted by a good's price. */
.map .path { fill: none; stroke: var(--nf-purple-solid); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 2 1.2; animation: pathRun 1.2s linear infinite; }
@keyframes pathRun { to { stroke-dashoffset: -3.2; } }
.map .city.pick { stroke: var(--ember-deep); stroke-width: 1.2; }
.map .fare { font-size: 2.6px; font-weight: 700; fill: var(--nf-purple-solid); paint-order: stroke; stroke: rgba(255,255,255,0.9); stroke-width: 0.9px; pointer-events: none; }
.map .city.p1 { fill: #2fb47c; } .map .city.p2 { fill: #9ad36b; } .map .city.p3 { fill: #f5c518; } .map .city.p4 { fill: #ff9a4d; } .map .city.p5 { fill: #e04f1f; }
/* the usual price, where today's is not known: the same scale, lighter */
.map .city.u1 { fill: #2fb47c; fill-opacity: 0.7; } .map .city.u2 { fill: #9ad36b; fill-opacity: 0.7; } .map .city.u3 { fill: #f5c518; fill-opacity: 0.7; } .map .city.u4 { fill: #ff9a4d; fill-opacity: 0.75; } .map .city.u5 { fill: #e04f1f; fill-opacity: 0.75; }
.map-pick { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding: 8px 10px; border-radius: 12px; background: var(--nf-disc); font-size: 0.8rem; color: var(--nf-blue); }
.map-pick b { color: var(--nf-purple-solid); }
.map-pick .grow { flex: 1 1 auto; }
.legend-good { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 0.74rem; color: var(--ink-muted); }
.pri-tab .lnk { border: none; background: none; color: var(--nf-purple-solid); font-size: 0.8rem; padding: 0 4px; cursor: pointer; }
/* 7: the coach, above the tabs — one sentence, three dots, a way to say "I know". */
.coach { display: flex; align-items: center; gap: 10px; margin-top: 6px; padding: 8px 10px 8px 12px; border-radius: 14px; background: linear-gradient(135deg, rgba(84,44,194,0.12) 0%, rgba(167,78,222,0.12) 100%); border: 1px solid rgba(84,44,194,0.25); font-size: 0.8rem; line-height: 1.35; color: var(--nf-blue); flex-shrink: 0; }
.coach[hidden] { display: none; }
.coach .dots { display: flex; gap: 4px; flex: 0 0 auto; }
.coach .dots i { width: 7px; height: 7px; border-radius: 50%; background: rgba(84,44,194,0.25); }
.coach .dots i.on { background: var(--nf-purple-solid); }
.coach .grow { flex: 1 1 auto; }
.coach .chip { font-size: 0.7rem; padding: 4px 9px; flex: 0 0 auto; }
html[data-theme="nwa"] .coach { color: #c7d0ec; }
html[data-theme="nwa"] .map-pick { color: #c7d0ec; }
html[data-theme="nwa"] .stepper b { color: #c7d0ec; }

/* ── the pratik: a person, not a row ── */
.pratik-card { background: linear-gradient(160deg, #fff 0%, #fbf8ff 100%); }
.pratik-card.is-close { border-color: var(--nf-stroke-50); box-shadow: 0 4px 16px rgba(84,44,194,0.14); }
.pk-head { display: flex; align-items: center; gap: 10px; }
.pk-face { width: 42px; height: 42px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--nf-disc); font-size: 1.4rem; }
.pk-id { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.pk-name { font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 1.04rem; color: var(--nf-purple-solid); }
.pk-lvl { font-style: normal; font-size: 0.68rem; color: rgba(49,86,142,0.6); }
.pk-det { font-size: 0.68rem; font-weight: 700; }
.pk-what { margin-bottom: 4px; }
.pk-row { flex-wrap: wrap; row-gap: 4px; }
.pk-row .choice { margin: 0; }
.bg-bar { height: 5px; border-radius: 999px; background: var(--nf-disc); overflow: hidden; margin: 8px 0 2px; }
.bg-fill { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--nf-grad); transition: width 0.45s ease; }

/* ================================================================== REZO === */
.map { width: 100%; aspect-ratio: 100 / 74; margin-top: 6px; border-radius: 18px; border: 1px solid var(--nf-frame-stroke); box-shadow: 0 2px 10px rgba(60,30,100,0.06); flex-shrink: 0; display: block; background: #eef2fb; }
.map .dom { fill: #e6e3f2; stroke: rgba(86,44,195,0.25); stroke-width: 0.35; }
.map .land { fill: url(#landg); stroke: #b8965a; stroke-width: 0.45; stroke-linejoin: round; }
.map .road { stroke: rgba(84, 44, 194, 0.42); stroke-width: 0.55; stroke-linecap: round; fill: none; }
.map .road.long { stroke-dasharray: 1.4 0.9; stroke-width: 0.45; }   /* three hours or more: it will cost you a day */
.map .sea { stroke: rgba(63, 52, 230, 0.34); stroke-width: 0.4; stroke-dasharray: 0.6 1.1; stroke-linecap: round; fill: none; }
.map .cg { cursor: pointer; }
.map .hit { fill: transparent; }
.map .city { fill: #fff; stroke: var(--nf-purple-solid); stroke-width: 0.7; transition: r 0.2s ease; }
.map .city.known { fill: rgba(63,52,230,0.25); }
.map .city.mine { fill: var(--nf-purple-solid); }
.map .city.here { stroke: var(--nf-tip-blue); stroke-width: 1.3; fill: var(--nf-tip-blue); }
.map .halo { fill: rgba(63,52,230,0.18); stroke: rgba(63,52,230,0.5); stroke-width: 0.4; animation: haloPulse 1.7s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes haloPulse { 0%, 100% { transform: scale(0.85); opacity: 0.9; } 50% { transform: scale(1.3); opacity: 0.3; } }
.map .cname { font-size: 2.5px; fill: var(--nf-blue); pointer-events: none; font-family: var(--font-body); paint-order: stroke; stroke: rgba(255,255,255,0.85); stroke-width: 0.9px; stroke-linejoin: round; }
.map .compass circle { fill: rgba(255,255,255,0.7); stroke: rgba(84,44,194,0.4); stroke-width: 0.3; }
.map .compass path { fill: var(--ember-deep); }
.map .compass text { font-size: 2.4px; fill: rgba(49,86,142,0.7); font-family: var(--font-body); }
.legend { display: flex; gap: 12px; flex-wrap: wrap; margin: 8px 2px 0; font-size: 0.62rem; color: rgba(49,86,142,0.7); }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; vertical-align: middle; }
.legend .i-here { background: var(--nf-tip-blue); } .legend .i-known { background: rgba(63,52,230,0.3); border: 1px solid var(--nf-purple-solid); } .legend .i-mine { background: var(--nf-purple-solid); }
.city-chips { max-height: 118px; overflow-y: auto; scrollbar-width: none; }
.city-chips::-webkit-scrollbar { display: none; }
.deyo-row span i { display: block; font-size: 0.66rem; line-height: 1.35; }

.trip { display: flex; align-items: center; gap: 11px; width: 100%; margin-top: 8px; padding: 11px 12px; border: 1px solid var(--nf-frame-stroke); border-radius: 15px; background: var(--nf-card); text-align: left; color: var(--nf-blue); box-shadow: 0 2px 8px rgba(60,30,100,0.05); transition: transform 0.15s ease, border-color 0.18s ease; }
.trip:hover:not(:disabled) { border-color: var(--nf-stroke-50); transform: translateY(-1px); }
.trip:disabled, .trip.is-off { opacity: 0.4; cursor: default; }
.trip-ico { font-size: 1.5rem; flex-shrink: 0; }
.trip-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.trip-body b { font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 0.98rem; color: var(--nf-purple-solid); }
.trip-body i { font-style: normal; font-size: 0.67rem; color: rgba(49,86,142,0.6); }
.trip-cost { flex: 0 0 auto; font-size: 0.92rem; font-variant-numeric: tabular-nums; }

/* ================================================================== BANK === */
.worth { font-family: var(--font-display); font-size: 2.3rem; line-height: 1.15; color: var(--nf-purple-solid); font-variant-numeric: tabular-nums; }
.worth.bad { color: var(--dn); }
.worth i { font-style: normal; font-family: var(--font-body); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em; color: rgba(49,86,142,0.5); }
.ledger-item { display: flex; align-items: center; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--nf-hairline-25); font-size: 0.76rem; }
.ledger-item:last-child { border-bottom: none; }
.ledger-item .t { font-size: 0.58rem; color: rgba(49,86,142,0.5); flex: 0 0 26px; }
.ledger-item b { font-weight: 400; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ledger-item .bal { font-size: 0.66rem; color: rgba(49,86,142,0.5); flex: 0 0 54px; text-align: right; font-variant-numeric: tabular-nums; }
.ledger-item.chay .bal { font-style: italic; }   /* a goods loss (engine.book): the purse did not move, the roof did */

/* =================================================================== PRI === */
/* The board scrolls inside its card, so the header row and the goods column
   stay put while the prices move: freeze the top row and the first column. */
.pri-wrap { overflow: auto; max-height: min(58dvh, 460px); scrollbar-width: thin; margin: 0 -4px; overscroll-behavior-x: contain; }
/* Only the sideways scroll is kept inside: when the board reaches its end a
   swipe carries on to the screen below it (the people card), instead of the
   page sitting dead under the thumb. Its offsets survive a redraw (render). */
.pri-tab { border-collapse: separate; border-spacing: 0; }
.pri-tab thead th { position: sticky; top: 0; z-index: 3; background: var(--nf-card); box-shadow: inset 0 -1px 0 var(--nf-hairline-25); }
.pri-tab th:first-child, .pri-tab td:first-child { position: sticky; left: 0; z-index: 2; background: var(--nf-card); box-shadow: inset -1px 0 0 var(--nf-hairline-25); }
.pri-tab thead th:first-child { z-index: 4; }
.pri-tab tr.pulse td:first-child { background: rgba(84,44,194,0.14); }
/* The unit beside the name: a price means nothing until you know it is per sak or per mamit. */
.pri-tab .pri-unit { font-size: 0.68rem; color: var(--ink-muted); font-style: italic; white-space: nowrap; }
/* The row's two ends: the dearest known town green, the cheapest red — a background, so it reads beside the text's own colour (dearer or cheaper than here). Night twins in the TÈM block. */
.pri-tab td.hi { background: rgba(31, 168, 102, 0.16); border-radius: 4px; }
.pri-tab td.lo { background: rgba(224, 79, 31, 0.14); border-radius: 4px; }
table.src { width: 100%; border-collapse: collapse; font-size: 0.76rem; }
table.src th { font-weight: 400; font-size: 0.58rem; letter-spacing: 0.05em; text-transform: uppercase; color: rgba(49,86,142,0.6); text-align: right; padding: 3px 5px; white-space: nowrap; }
table.src th i { display: block; font-style: normal; font-size: 0.52rem; opacity: 0.7; letter-spacing: 0; text-transform: none; }
table.src th:first-child, table.src td:first-child { text-align: left; }
table.src .th-sort { all: unset; box-sizing: border-box; display: block; width: 100%; cursor: pointer; text-align: inherit; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; }
table.src .th-sort b { font-weight: 400; font-size: 0.5rem; margin-left: 2px; }
table.src .th-sort.is-on { color: var(--nf-purple-solid); font-weight: 600; }
table.src .pri-mv { font-style: normal; font-size: 0.55rem; margin-right: 3px; color: rgba(49,86,142,0.35); }
table.src .pri-mv.up { color: var(--up); } table.src .pri-mv.dn { color: var(--dn); }
table.src .th-sort:focus-visible { outline: 2px solid var(--nf-stroke-50); outline-offset: 1px; border-radius: 3px; }
table.src td { padding: 5px; border-top: 1px solid var(--nf-hairline-25); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.src.lb td:nth-child(2) { text-align: left; }
table.src.lb tr.is-me td { background: rgba(84,44,194,0.08); }
/* Plus standings: where each player is right now, squeezed between the name and the purse — small, one line, cut with an ellipsis rather than wrapping the row. */
table.src.lb td.vil { text-align: left; font-size: 0.66rem; max-width: 86px; overflow: hidden; text-overflow: ellipsis; opacity: 0.8; padding-left: 2px; padding-right: 2px; }
.lb-card .set-tabs { margin-bottom: 8px; }

/* ================================================================ NOUVÈL === */
.news-lead { font-size: 0.95rem; line-height: 1.5; }
.log-item { padding: 6px 0; border-bottom: 1px solid var(--nf-hairline-25); font-size: 0.79rem; line-height: 1.45; color: rgba(49,86,142,0.85); }
.log-item:last-child { border-bottom: none; }
.log-item .t { font-size: 0.58rem; color: rgba(49,86,142,0.5); margin-right: 6px; }
.log-item.bad { color: var(--dn); } .log-item.good { color: var(--up); }

/* ==================================================================== END === */
.over { text-align: center; padding: 22px 16px; }
.end-emblem { font-size: 2.8rem; }
.over .big { margin-top: 6px; font-family: var(--font-display); font-style: italic; font-size: 1.4rem; color: var(--nf-purple-solid); }
.over .worth { margin-top: 10px; }
.end-stats { margin: 16px 0 10px; display: flex; justify-content: center; gap: 22px; }
.end-stat b { display: block; font-size: 1.35rem; font-weight: 400; color: var(--nf-blue); font-variant-numeric: tabular-nums; }
.end-stat span { font-size: 0.58rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(49,86,142,0.55); }
.kat-preview { margin-top: 12px; min-height: 40px; }
.kat-preview img { display: block; width: 100%; height: auto; border-radius: 14px; border: 1px solid var(--nf-frame-stroke); box-shadow: 0 4px 14px rgba(60,30,100,0.14); }
.wa-btn { margin-top: 12px; display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 12px; border-radius: 16px; background: #25D366; color: #fff; font-size: 0.92rem; font-weight: 700; text-decoration: none; box-shadow: 0 4px 14px rgba(37,211,102,0.35); }
.wa-btn svg { width: 20px; height: 20px; }
.wa-btn:active { transform: scale(0.98); }

/* The town's wider market: people you could get to know. Bòlètopoli's candidate card. */
.cand { padding: 10px 0; border-bottom: 1px solid var(--nf-hairline-25); font-size: 0.85rem; color: var(--nf-blue); }
.cand:last-of-type { border-bottom: none; }
.cand-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.cand-ask { font-size: 0.74rem; color: var(--nf-purple-solid); white-space: nowrap; }
.cand-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; margin-top: 6px; }
.cand-stat { display: flex; flex-direction: column; line-height: 1.25; }
.cand-stat .cand-lbl { font-size: 0.62rem; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(49,86,142,0.7); }
.cand-stat .stars { font-size: 0.92rem; color: #d99a1e; letter-spacing: 0.04em; }
.cand-stat i { font-style: normal; font-size: 0.7rem; color: var(--ink-muted); }
.cand-offers { margin-top: 8px; }
.pk-chip.pk-more { border-style: dashed; background: transparent; }
.pk-chip.pk-more .pk-chip-face { background: var(--nf-disc); color: var(--nf-purple-solid); font-weight: 700; }

/* Text fields — the Plus code, the name on a challenge. 16px so iOS does not zoom in. */
.input { box-sizing: border-box; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--nf-frame-stroke); background: var(--nf-card); color: var(--nf-blue); font: 400 16px var(--font-body); }
.input:focus { outline: 2px solid var(--nf-stroke-50); outline-offset: 1px; }
.row { display: flex; gap: 8px; align-items: center; }
.row .grow { flex: 1 1 auto; min-width: 0; }

/* ── Spreading: the challenge, the streak, the share row ─────────────────── */
/* A friend's score on the front page. Built like a mode card, lit like the
   live one, because it is the most important thing on the screen when it is there. */
.defi-card { display: flex; align-items: center; gap: 12px; width: 100%; margin-bottom: 12px; padding: 13px 14px; border-radius: 18px; text-align: left; color: var(--nf-blue); background: linear-gradient(160deg, #fff7ef 0%, #ffe9d9 100%); border: 1px solid rgba(224,79,31,0.35); box-shadow: 0 4px 16px rgba(224,79,31,0.14); }
.defi-card:active:not(.is-old) { transform: scale(0.98); }
.defi-card.is-old { background: var(--nf-card); border-color: var(--nf-frame-stroke); box-shadow: none; }
.defi-ico { flex: 0 0 auto; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%; background: rgba(224,79,31,0.12); font-size: 1.25rem; }
.defi-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.defi-body b { font-size: 0.9rem; font-weight: 700; color: var(--ember-deep); }
.defi-body i { font-style: normal; font-size: 0.74rem; line-height: 1.35; color: var(--ink-muted); }
.defi-card.is-old .defi-body b { color: var(--nf-blue); }
.defi-go { flex: 0 0 auto; padding: 7px 13px; border-radius: 999px; background: var(--ember-deep); color: #fff; font-size: 0.78rem; font-weight: 700; }
.defi-hint { border-color: rgba(224,79,31,0.3); background: rgba(224,79,31,0.06); }

/* Day one: the radio's tip, and the row it points at. */
.tuyo-hint { border-color: var(--nf-stroke-50); background: linear-gradient(160deg, #fff 0%, #f2ecff 100%); }
.gd-row.is-tuyo { margin: 0 -6px; padding-left: 6px; padding-right: 6px; border-radius: 12px; background: rgba(84,44,194,0.06); box-shadow: inset 0 0 0 1px var(--nf-stroke-50); }
.gd-tag { display: inline-block; margin-left: 5px; padding: 0 6px; border-radius: 999px; font-style: normal; font-size: 0.62rem; font-weight: 700; line-height: 1.6; white-space: nowrap; }
.gd-tag.good { background: rgba(31,138,76,0.1); }
.gd-tag.bad { background: rgba(210,16,52,0.08); }
.gd-tag.tuyo { background: var(--nf-purple-solid); color: #fff; }

.seri-line { margin-top: 6px; font-size: 0.86rem; font-weight: 700; color: var(--ember-deep); }
.share-name { display: block; margin-top: 14px; text-align: left; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-muted); }
.share-name .input { margin-top: 5px; width: 100%; text-transform: none; letter-spacing: 0; }
.share-text { margin: 10px 0 0; padding: 10px 12px; border-radius: 12px; background: var(--nf-frost); border: 1px solid var(--nf-hairline-25); font-family: var(--font-body); font-size: 0.72rem; line-height: 1.5; color: var(--nf-blue); text-align: left; white-space: pre-wrap; word-break: break-word; }
.share-text:empty { display: none; }
button.wa-btn { border: 0; cursor: pointer; font-family: inherit; }
.share-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }
.share-row .btn { padding: 11px 6px; font-size: 0.8rem; }

/* ================================================================== TABS === */
.set-tabs { display: flex; gap: 5px; width: 100%; margin: 8px 0 0; flex-shrink: 0; }
.set-tab { flex: 1; padding: 8px 4px; border: 1px solid var(--nf-frame-stroke); border-radius: 11px; background: transparent; color: var(--nf-blue); font-size: 0.74rem; font-weight: 700; transition: background 0.18s ease, color 0.18s ease; }
/* CANON-LOCK [13]: primary and active controls take the family gradient with the Palefò lift (.btn, active tabs). */
.set-tab.is-on { background: var(--gradient-primary); border-color: transparent; color: #fff; box-shadow: var(--btn-shadow); }
.game-tabs { margin-top: 6px; }
.game-tabs .set-tab { padding: 6px 4px; }
.level-toggle { display: flex; align-items: center; gap: 10px; width: 100%; padding: 12px 14px; background: var(--nf-card); border: 1px solid var(--nf-frame-stroke); border-radius: 14px; font-size: 0.82rem; font-weight: 600; color: var(--nf-blue); text-align: left; }
.level-toggle__box { flex-shrink: 0; width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--nf-stroke-50); background: #fff; transition: background 0.15s ease, border-color 0.15s ease; }
.level-toggle.is-on .level-toggle__box { background: var(--nf-grad); border-color: transparent; box-shadow: inset 0 0 0 3px #fff; }

/* =================================================================== VCR === */
.vcr { display: flex; align-items: flex-end; justify-content: center; gap: 18px; margin: 6px 0 0; padding: 6px 12px 5px; border-radius: 22px; flex-shrink: 0;
  background: linear-gradient(180deg, #f8f6ff 0%, #ebe6fb 100%); border: 1px solid var(--nf-frame-stroke); box-shadow: inset 0 1px 0 #fff, 0 6px 18px rgba(60, 30, 100, 0.10); }
/* Bòlètopoli's transport bar (2026-09-22): round buttons on a tray, the day a big
   green play that pulses once you have done something today. */
.vcr-btn { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 0; border: none; background: none; font-family: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.vcr-ico { display: flex; align-items: center; justify-content: center; border-radius: 50%; line-height: 1; transition: transform 0.12s ease, box-shadow 0.2s ease; }
/* The three side coins are lavender, FotoLekti's trio; the one green thing on the bar is the play button, the day's "go". */
.vcr-side .vcr-ico { width: 50px; height: 50px; font-size: 1.4rem; background: linear-gradient(160deg, #fff 0%, #ece6fb 100%); border: 1px solid var(--nf-frame-stroke); box-shadow: 0 4px 12px rgba(84, 44, 194, 0.16), inset 0 -2px 0 rgba(84, 44, 194, 0.06), inset 0 1px 0 #fff; }
.vcr-play .vcr-ico { width: 72px; height: 72px; background: linear-gradient(135deg, var(--go-hi) 0%, var(--go-lo) 100%); box-shadow: 0 10px 24px rgba(31, 154, 103, 0.42), inset 0 -3px 0 rgba(0, 0, 0, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.vcr-play svg { width: 38px; height: 38px; fill: #fff; margin-left: 5px; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25)); }
.vcr-cap { max-width: 120px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--nf-purple-solid); }
.vcr-play .vcr-cap { font-size: 0.8rem; color: var(--go-lo); }
.vcr-btn:active:not([disabled]) .vcr-ico { transform: scale(0.93); }
.vcr-btn[disabled] { opacity: 0.35; cursor: default; }
.vcr-play.ready .vcr-ico { animation: vcrPulse 1.6s ease-in-out infinite; }
@keyframes vcrPulse { 50% { box-shadow: 0 10px 34px rgba(31, 154, 103, 0.65), 0 0 0 8px rgba(31, 154, 103, 0.12), inset 0 -3px 0 rgba(0, 0, 0, 0.14); } }
/* The version, in the panel's bottom padding, right-aligned under the transport
   bar. Absolutely placed, so the panel's 18px/16px padding stays the canon's. */

/* ================================================================= TOAST === */
.toast { position: absolute; left: 16px; right: 16px; bottom: 156px;   /* above the transport bar and the tape under it */ z-index: 50; padding: 12px 14px; border-radius: 14px; background: var(--nf-purple-solid); color: #fff !important; font-size: 0.85rem; line-height: 1.35; font-weight: 700; text-align: center; overflow-wrap: anywhere; min-height: 44px; display: flex; align-items: center; justify-content: center; box-shadow: 0 8px 22px rgba(60,30,100,0.3); animation: toastIn 0.24s ease; }
.toast.bad { background: var(--ember-deep); }
@keyframes toastIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ================================================================= SHEET ===
   The travel sheet. It rises from the bottom over the panel, because choosing a
   road is a decision you back out of more often than you commit to. */
.sheet { position: absolute; inset: 0; z-index: 60; display: flex; align-items: flex-end; background: rgba(26, 20, 60, 0); transition: background 0.2s ease; }
.sheet.is-open { background: rgba(26, 20, 60, 0.42); }
.sheet-card { width: 100%; max-height: 82%; overflow-y: auto; scrollbar-width: none; padding: 10px 18px 20px; border-radius: 26px 26px 0 0; background: linear-gradient(180deg, #fafbfe 0%, #f2f3fb 100%); box-shadow: 0 -10px 34px rgba(28,16,74,0.28); transform: translateY(100%); transition: transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1); }
.sheet-card::-webkit-scrollbar { display: none; }
.sheet.is-open .sheet-card { transform: none; }
.sheet-grip { width: 42px; height: 4px; margin: 0 auto 10px; border-radius: 999px; background: var(--nf-frame-stroke); }
.sheet-title { font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 1.5rem; color: var(--nf-purple-solid); margin-bottom: 4px; }
/* ============================================================ FONTIPALE ===
   The ladder of loans: four steps, the ones behind you ticked, the one you
   stand on lit. Wraps to two rows on a narrow phone rather than scrolling. */
.fonti-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 4px 0 10px; padding: 0; list-style: none; }
.fonti-steps li { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 8px 4px 7px; border-radius: 12px; border: 1px solid var(--nf-hairline-25); text-align: center; color: var(--ink-muted); }
.fonti-steps b { width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; background: var(--nf-disc); color: var(--nf-purple-solid); font-size: 0.7rem; }
.fonti-steps span { font-size: 0.62rem; font-weight: 700; line-height: 1.2; }
.fonti-steps i { font-style: normal; font-size: 0.62rem; font-variant-numeric: tabular-nums; }
.fonti-steps li.done b { background: var(--hit-green); color: #fff; }
.fonti-steps li.here { border-color: var(--nf-stroke-50); background: rgba(84, 44, 194, 0.06); color: var(--nf-purple-solid); }
.fonti-steps li.here b { background: var(--nf-grad); color: #fff; }

/* ================================================================== ASK === */
/* The question before something that cannot be taken back, in place of the
   browser's confirm(). Centred, above any open sheet (60), below nothing. */
.ask { position: absolute; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(26, 20, 60, 0); transition: background 0.18s ease; }
.ask.is-open { background: rgba(26, 20, 60, 0.5); }
.ask-card { width: 100%; max-width: 350px; max-height: 84%; overflow-y: auto; scrollbar-width: none; padding: 22px 20px 18px; border-radius: 26px; border: 1px solid var(--nf-frame-stroke); background: linear-gradient(180deg, #fff 0%, #f4f2fc 100%); box-shadow: 0 20px 54px rgba(28, 16, 74, 0.36); text-align: center; opacity: 0; transform: translateY(12px) scale(0.94); transition: transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.15), opacity 0.18s ease; }
.ask-card::-webkit-scrollbar { display: none; }
.ask.is-open .ask-card { opacity: 1; transform: none; }
.ask-ico { width: 58px; height: 58px; margin: 0 auto 10px; display: flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 1.75rem; background: rgba(84, 44, 194, 0.09); box-shadow: inset 0 0 0 1px rgba(84, 44, 194, 0.12); }
.ask-card.danger .ask-ico { background: rgba(224, 79, 31, 0.11); box-shadow: inset 0 0 0 1px rgba(224, 79, 31, 0.2); }
.ask-title { font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 1.45rem; line-height: 1.2; color: var(--nf-purple-solid); }
.ask-body { margin-top: 8px; font-size: 0.88rem; line-height: 1.45; color: var(--ink-muted); }
.ask-card { position: relative; outline: none; }
/* Back: a round arrow in the top-left corner — the way out of every question,
   every sheet and every overlay screen, in place of a "Tounen" at the foot. */
.back-circle { flex: 0 0 auto; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 50%; border: 1px solid var(--nf-frame-stroke); background: linear-gradient(160deg, #fff 0%, #f1edfb 100%); color: var(--nf-purple-solid); box-shadow: 0 3px 10px rgba(60, 30, 100, 0.10); transition: transform 0.12s ease, background 0.2s ease; }
.back-circle svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.back-circle:hover { background: var(--nf-disc); }
.back-circle:active { transform: scale(0.92); }
.back-circle:focus-visible, .ask-ok:focus-visible { outline: 2px solid var(--nf-purple-solid); outline-offset: 2px; }
.ask-card > .back-circle { position: absolute; top: 14px; left: 14px; }
.tb-back { width: 36px; height: 36px; }
.tb-back svg { width: 18px; height: 18px; }
.sheet-head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.sheet-head .sheet-title { min-width: 0; margin-bottom: 0; }
/* Strateji, as Bòlètopoli sets it: small heads, short paragraphs, one fold. */
.strateji p { margin: 6px 0; font-size: 0.8rem; line-height: 1.45; color: var(--nf-blue); font-family: var(--font-body); }
.strateji h4 { margin: 12px 0 4px; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--nf-purple-solid); }
.strateji ul, .strateji ol { margin: 4px 0 6px; padding-left: 18px; font-size: 0.78rem; line-height: 1.45; color: var(--nf-blue); font-family: var(--font-body); }
.strateji li { margin: 3px 0; }
.strateji .kv { font-size: 0.76rem; }
html[data-theme="nwa"] .strateji :is(p, ul, ol) { color: #b9c3e6; }
html[data-theme="nwa"] .strateji h4 { color: #cfc4ff; }
/* CANON-LOCK [7]: the Palefò seal band — 44px, the mark centred, above the tape. Hidden for now (2026-09-23). */
.palefo-logo { flex-shrink: 0; height: 44px; margin: 4px -16px -6px; display: flex; align-items: center; justify-content: center; }
.palefo-logo[hidden] { display: none; }
.palefo-logo img { height: 24px; width: auto; opacity: 0.85; }

/* Poz: Bòlètopoli's pause, a ⏸ beside the back arrow and a veil over the table. */
.pause-btn[aria-pressed="true"] { color: var(--nf-purple-solid); }
.pause-overlay { position: absolute; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center; background: rgba(26, 20, 60, 0.45); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.pause-overlay[hidden] { display: none; }
.pause-card { display: flex; flex-direction: column; align-items: center; gap: 10px; min-width: 220px; background: linear-gradient(180deg, #fafbfe 0%, #eee9fa 100%); border-radius: 22px; padding: 26px 34px; box-shadow: 0 18px 44px rgba(26, 20, 60, 0.4); }
.pause-card .btn { margin-top: 4px; }
.pause-title { margin: 0; font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 1.4rem; color: var(--nf-purple-solid); }
.pause-quit { border: none; background: none; color: var(--nf-blue); font-family: inherit; font-size: 0.8rem; text-decoration: underline; cursor: pointer; padding: 6px 10px; }
html[data-theme="nwa"] .pause-card { background: linear-gradient(180deg, #1e2340 0%, #171a30 100%); box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6); }
html[data-theme="nwa"] .pause-quit { color: #b9c3e6; }
.ask-ok { margin-top: 18px; }
.ask-alt { margin-top: 8px; background: transparent; color: var(--nf-purple-solid); border: 1px solid var(--nf-stroke-50); box-shadow: none; }
html[data-theme="nwa"] .ask-alt { color: #cfc4ff; border-color: rgba(200, 182, 255, 0.35); }
.btn.warn { background: linear-gradient(135deg, var(--ember) 0%, var(--ember-deep) 100%); box-shadow: 0 6px 18px rgba(224, 79, 31, 0.32); }
/* Vann tout: the sale, line by line. */
.ask-list { margin: 12px 0 0; padding: 0; list-style: none; text-align: left; border-top: 1px solid var(--nf-frame-stroke); }
.ask-list li { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; align-items: baseline; padding: 8px 2px; border-bottom: 1px solid var(--nf-frame-stroke); font-size: 0.84rem; }
.ask-list li span { min-width: 0; overflow-wrap: anywhere; color: var(--ink-muted); }
.ask-list li i { display: block; margin-top: 1px; font-size: 0.74rem; color: var(--nf-purple-solid); }
/* Vann tout: an × on every line takes that good off the sale; the row stays, struck through, with ↺ to bring it back. */
.vann-list li { grid-template-columns: 1fr auto auto auto; }
.vann-list .rm { width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--nf-stroke-50); background: var(--nf-disc); color: var(--nf-purple-solid); font-size: 0.95rem; line-height: 1; cursor: pointer; align-self: center; }
.vann-list li.is-off span, .vann-list li.is-off b { text-decoration: line-through; opacity: 0.45; }
.vann-list li.is-off .rm { background: var(--nf-purple-solid); color: #fff; border-color: transparent; }
.ask-list b, .ask-sum b { font-variant-numeric: tabular-nums; color: var(--nf-purple-solid); }
.ask-list em { min-width: 58px; font-style: normal; font-size: 0.74rem; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.ask-sum { margin-top: 12px; font-size: 0.9rem; }
.ask-note { margin-top: 4px; font-size: 0.74rem; color: rgba(49, 86, 142, 0.6); }
.ask .up { color: var(--up); font-weight: 700; }
.ask .dn { color: var(--dn); font-weight: 700; }
.sheet-card h3 { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: rgba(49,86,142,0.6); }

/* ─────────────────────────────────────────────────── short phones ── */
@media (max-height: 740px) {
  .home-hero img { aspect-ratio: 16 / 8; border-radius: 18px; }
  .wordmark { font-size: 2.6rem; }
  .mode-cards { margin-top: 14px; gap: 10px; }
  .toast { bottom: 142px; }
}
@media (prefers-reduced-motion: reduce) {
  .tk-track { animation: none; }
  .screen, .toast, .map .halo, .tk-flash, .pulse, .vcr-play.ready .vcr-ico { animation: none; }
  .sheet-card, .ask-card { transition: none; }
}

/* Pa gen rezo (OFFLINE.md): the mark in the icon strip while navigator.onLine is false. */
.tb-offline { font-size: 0.95rem; line-height: 1; padding: 0 4px; filter: grayscale(0.2); }
.home-offline { margin: 6px 0 2px; font-size: 0.78rem; }

/* ================================================================== TÈM ===
   Bòlètopoli's (2026-09-13), brought over whole: klè is the NervalFrost
   daylight; nwa is the same shell at night. The tokens carry most of it — the
   night values are byte-identical to Bòlètopoli's so the family reads as one —
   and the rules below catch the surfaces Pratik paints with a literal light
   colour. The moon/sun in the top bar flips it; Paramèt also offers Otomatik. */
.theme-btn .theme-sun { display: none; }
.theme-btn.is-nwa .theme-moon { display: none; }
.theme-btn.is-nwa .theme-sun { display: block; }

html[data-theme="nwa"] { color-scheme: dark;
  --nf-backdrop: #0e1020; --nf-frost: #161a2c; --nf-card: #1b2036; --nf-blue: #c7d0ec; --nf-purple: rgba(200, 182, 255, 0.92); --nf-purple-solid: #c8b6ff; --nf-tip-blue: #9fb0ff;
  --nf-disc: rgba(200, 182, 255, 0.12); --nf-stroke-50: rgba(200, 182, 255, 0.5); --nf-frame-stroke: rgba(150, 130, 230, 0.42); --nf-hairline-25: rgba(150, 130, 230, 0.22);
  --nf-grad: linear-gradient(96deg, #4f7fe0 0%, #8a5cf0 104%); --ember: #ff8a5c; --ember-deep: #ff6a3d; --hit-green: #4fd69a; --tile-ink: #f3e6c2; --ink-muted: #a3b0d4;
  /* Pratik's own: the market's two directions, lit for a dark ground. */
  --up: #4fd69a; --dn: #ff7b8f; --green-deep: #4fd69a;
  --go-soft-hi: #1f3a2f; --go-soft-lo: #163126; }
html[data-theme="nwa"] body { background: linear-gradient(135deg, #0b0d1c 0%, #141633 45%, #1a1436 75%, #1f1530 100%); }
html[data-theme="nwa"] .dash-panel { background: linear-gradient(180deg, #181c31 0%, #141830 48%, #111427 100%); }
html[data-theme="nwa"] .bg-top { background: radial-gradient(closest-side, rgba(124, 77, 255, 0.22) 0%, rgba(124, 77, 255, 0.08) 55%, transparent 100%); }
html[data-theme="nwa"] .vol-pop { background: rgba(27, 32, 54, 0.82); border-color: rgba(200, 182, 255, 0.28); }
html[data-theme="nwa"] .palefo-logo img { filter: invert(1) hue-rotate(180deg); opacity: 0.7; }
html[data-theme="nwa"] .card, html[data-theme="nwa"] .mode-card { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35); }

/* The words: every muted line Pratik paints in the daylight's blue. */
html[data-theme="nwa"] :is(.card h3, .sheet-card h3, .card :where(p), .muted, .mode-card__desc, .kv i, .kv span i, .town-mood, .kat-head, .pk-chip-id i, .pk-rate,
  .pk-lvl, .legend, .trip-body i, .worth i, .ledger-item .t, .ledger-item .bal, table.src th, .log-item, .log-item .t, .end-stat span, .cand-stat .cand-lbl, .ask-note) { color: var(--ink-muted); }
html[data-theme="nwa"] .card h3 i { color: rgba(163, 176, 212, 0.6); }
html[data-theme="nwa"] :is(.set-credits li, .set-sub) { color: var(--ink-muted); }
html[data-theme="nwa"] .set-credits b { color: var(--nf-blue); }
html[data-theme="nwa"] .pk-rate b { color: var(--nf-blue); }
html[data-theme="nwa"] .sound-btn.is-muted { color: rgba(200, 182, 255, 0.4); }

/* Violet grounds that carried white text: the violet is lavender at night, so the text goes dark. */
html[data-theme="nwa"] :is(.set-tab.is-on, .gd-tag.tuyo) { background: #c8b6ff; color: #1b1440; box-shadow: none; }
html[data-theme="nwa"] .toast { background: #2b2458; color: #ece6ff !important; border: 1px solid rgba(200, 182, 255, 0.3); box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5); }
html[data-theme="nwa"] .toast.bad { background: #4a1a1a; color: #ffb0b0 !important; border-color: #7a2a2a; }

/* Surfaces painted with a literal white. */
html[data-theme="nwa"] :is(.btn.ghost, .klasman-link, .back-circle, .sound-btn, .chip, .pk-offer, .mode-card__glyph, .vcr-side .vcr-ico) { background: rgba(120, 140, 255, 0.14); color: #cdd8ff; border-color: rgba(120, 140, 255, 0.35); box-shadow: none; }
html[data-theme="nwa"] .chip.on { background: #c8b6ff; color: #1b1440; }
html[data-theme="nwa"] .chip.go { background: linear-gradient(96deg, #3fd0a0 0%, #2fb47c 100%); color: #0f2a1e; border-color: transparent; }
html[data-theme="nwa"] .vcr-side .vcr-cap { color: #cdd8ff; }
html[data-theme="nwa"] :is(.town-card, .pratik-card, .pk-chip) { background: var(--nf-card); }
html[data-theme="nwa"] :is(.mode-card.is-live, .pk-chip.is-close, .tuyo-hint) { background: linear-gradient(135deg, #1e2340 0%, #261c4a 100%); }
html[data-theme="nwa"] .mode-card:hover:not(:disabled) { background: #232a4a; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45); }
html[data-theme="nwa"] .pk-chip.pk-more { background: transparent; }
html[data-theme="nwa"] .level-toggle__box { background: var(--nf-card); }
html[data-theme="nwa"] .level-toggle.is-on .level-toggle__box { box-shadow: inset 0 0 0 3px var(--nf-card); }
html[data-theme="nwa"] .vol-range::-webkit-slider-thumb { border-color: #1d1b3a; }
html[data-theme="nwa"] .vol-range::-moz-range-thumb { border-color: #1d1b3a; }
html[data-theme="nwa"] .chip.credit { color: #ffd66b; }
html[data-theme="nwa"] .fet-band { color: #ffe3a0; background: linear-gradient(150deg, #3a2c0c 0%, #4a3810 100%); }
html[data-theme="nwa"] .defi-card { color: var(--nf-blue); background: linear-gradient(160deg, #2e1d18 0%, #3a2218 100%); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); }
html[data-theme="nwa"] .defi-card.is-old { background: var(--nf-card); }
html[data-theme="nwa"] .hud-chip.pos { background: linear-gradient(150deg, #123324 0%, #17442f 62%, #1b5238 100%); color: #9ff0c0; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 -2px 3px rgba(0, 0, 0, 0.35); }
html[data-theme="nwa"] .hud-chip.pos::after { color: rgba(159, 240, 192, 0.7); }
html[data-theme="nwa"] .hud-chip.neg::after { color: rgba(255, 179, 179, 0.7); }
html[data-theme="nwa"] .home-sub span:last-child { color: rgba(200, 182, 255, 0.75); }
html[data-theme="nwa"] .home-best { color: rgba(200, 182, 255, 0.55); }
html[data-theme="nwa"] .hud-chip.neg { background: linear-gradient(150deg, #3a1616 0%, #4a1c1c 62%, #582222 100%); color: #ffb3b3; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 -2px 3px rgba(0, 0, 0, 0.35); }

/* The map: the island in dusk, the towns lit. */
html[data-theme="nwa"] .map { background: #0f1830; }                       /* the sea at night */
html[data-theme="nwa"] .map .dom { fill: #1c2138; stroke: rgba(200, 182, 255, 0.18); }   /* the neighbour, quieter than Haiti */
html[data-theme="nwa"] .map stop:first-child { stop-color: #4d4429; }
html[data-theme="nwa"] .map stop:last-child { stop-color: #3a321d; }
html[data-theme="nwa"] .map .land { stroke: #7a6536; }
html[data-theme="nwa"] .map .city { fill: var(--nf-card); }
html[data-theme="nwa"] .map .cname { stroke: rgba(14, 16, 32, 0.85); }
html[data-theme="nwa"] .map .compass circle { fill: rgba(27, 32, 54, 0.8); }
html[data-theme="nwa"] .map .compass text { fill: var(--ink-muted); }

/* The transport bar, the sheets and the question. */
html[data-theme="nwa"] .vcr { background: linear-gradient(180deg, #1d2140 0%, #141830 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 6px 18px rgba(0, 0, 0, 0.4); }
html[data-theme="nwa"] .vcr-side .vcr-ico { box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4), inset 0 -2px 0 rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.06); }
html[data-theme="nwa"] .vcr-cap { color: #6fe0aa; }
html[data-theme="nwa"] :is(.sheet-card, .ask-card) { background: linear-gradient(180deg, #1e2340 0%, #171a30 100%); box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6); }
html[data-theme="nwa"] .fonti-steps li.here { background: rgba(200, 182, 255, 0.10); }
html[data-theme="nwa"] .fonti-steps li.done b { color: #0f2a1e; }
html[data-theme="nwa"] .ask-ico { background: rgba(200, 182, 255, 0.12); }
html[data-theme="nwa"] .pri-tab td.hi { background: rgba(87, 227, 154, 0.2); }
html[data-theme="nwa"] .pri-tab td.lo { background: rgba(255, 123, 143, 0.2); }
