/* ClockRadio theme — dark slate + amber (user theme: terminals amber #FFB000 on #0B0F17) */
:root {
  --bg: #0B0F17;
  --panel: #121826;
  --panel-2: #182136;
  --line: #263046;
  --text: #d7dee8;
  --muted: #8b96a8;
  --amber: #FFB000;
  --amber-dim: #b57f00;
  --good: #34d399;
  --bad: #f87171;
  --warn: #fbbf24;
  /* ── `--dvw` = ONE PERCENT OF THE DISPLAY (2026-09-16) ─────────────────────
     Pane type used to be sized in `vw`, which measures the BROWSER WINDOW — so on
     the dev box, authoring Mike's 480x800 cut inside a 1500px window, 6vw is 90px
     instead of the 28.8px the real 480px screen draws. Every consequence of that
     was a lie about the device:
       · the digital clock rendered 54.4px instead of 28.8px, so its line box was
         taller than the pane and the violations overlay reported "clock-digital 9px
         above the top edge" (Mike 2026-09-16: "Digital still claims above-leading
         that it doesn't actually need") — a claim about a font size the device
         never uses;
       · the same oversize produced the amber `clip-vw` marks (`vw` measuring the
         window, not the display) that had to be explained away as benign.
     A layout that names its display renders AS that display, so its type has to be
     measured in that display's units too. When a device pin owns the canvas, js/app.js
     writes `--dvw` = pinWidth/100 on #workspace; everywhere else it stays `1vw`,
     byte-identical to the old behaviour (Mike's own revert of the pane-relative
     sizes, 2026-09-13, is preserved exactly where no display is pinned). */ --dvw: 1vw;
}
* { box-sizing: border-box; }
html { font-size: 16px; } /* pin rem — Chrome & Chromium render identically no matter each profile's default-font-size setting (2026-09-09, Mike) */
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 14px/1.45 system-ui, "Segoe UI", Roboto, sans-serif;
  display: flex; flex-direction: column; overflow: hidden;
}

/* ── top bar ─────────────────────────────── */
#topbar {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .3rem .7rem; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #101624, #0b0f17);
  flex-shrink: 0; flex-wrap: nowrap; /* ONE line always — never a fatter header (2026-09-09, Mike) */
  /* height is FIXED (2026-09-09, Mike: “the pane repositioning is due to
     fitting the headers and footer above the main content”): the bar's
     natural height depended on its tallest child, so the fit cascade hiding
     the brand/links could shorten the bar AFTER boot and shift every pane
     down/up. A pinned height means nothing above the workspace can ever
     move it — the cascade may only hide items horizontally. */
  height: 2.25rem; min-height: 2.25rem;
}
.brand { font-size: 1.02rem; white-space: nowrap; }
.brand b { color: var(--amber); letter-spacing: .02em; }
.tagline { color: var(--muted); font-size: .76rem; margin-left: .45rem; }
/* the chips row FILLS the bar, and the profile chip owns every spare pixel of
   it (Mike 2026-09-13: "the header controls can fill the width — longer user
   names than 'Mike' will need extra space, so put all spare pixels there").
   So a long user name grows into the bar's slack instead of pushing a control
   into the sacrifice cascade.
   Safe for the cascade: flex-GROW only ever spends FREE space, and the overflow
   test in js/app.js `fitTopbar()` (`#topbar` scrollWidth > clientWidth) is
   driven by SHRINK, which is unchanged — each chip still refuses to shrink past
   its own content (`min-width: auto`). `#topbar.measuring` pins every chip back
   to `flex: 0 0 auto !important` during the natural-width read, so the
   duplicate-Creator-Support measurement still sees true intrinsic widths. */
.chips { display: flex; align-items: center; gap: .35rem; flex-wrap: nowrap; min-width: 0; flex: 1 1 auto; }
#profile-chip { flex: 1 1 auto; }
/* header sacrifice cascade — JS hides the lowest-value items until the
   topbar fits on one line; nothing is trimmed or wrapped (2026-09-09) */
.fit-hid { display: none !important; }
/* content-based hide (2026-09-12) — deliberately a SEPARATE class from
   .fit-hid: the width cascade strips .fit-hid off every element on each fit,
   so riding on it would resurrect the element on the next resize. */
.moot { display: none !important; }
/* Creator Support link in the topbar (styled like the old inline pill) */
.ko-fi-top {
  font-variant: small-caps; font-weight: normal; font-size: .78rem; color: #FFB000;
  text-decoration: none; border: 1px solid #263046; border-radius: 999px; padding: .14rem .6rem; white-space: nowrap;
}
.ko-fi-top:hover { border-color: #FFB000; }
/* dev-only chrome: templates/layouts button + the display-size reference
   rectangles — production screens never show them (?dev enables) */
.dev-only { display: none; }
.canvas-display-references { display: none; }
body.dev .dev-only { display: inline-block; }
/* the modal's dev block is a layout container, not an inline control */
body.dev .dev-only.lmod-devblock { display: block; }
/* the save row is a flex ROW (input + button); inline-block would break it */
body.dev .dev-only.lmod-save-row { display: flex; }
body.dev .canvas-display-references { display: block; }
/* no speech API (open-source Chromium): the mic button is pointless */
body.no-voice #btn-mic { display: none !important; }
.chip {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: .14rem .6rem; font-size: .76rem; color: var(--text);
}
.chip-btn {
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; padding: .14rem .6rem; font-size: .76rem; cursor: pointer;
}
.chip-btn:hover { color: var(--amber); border-color: var(--amber-dim); }
.chip-btn.on { border-color: var(--amber-dim); color: var(--amber); background: rgba(255, 176, 0, .1); }
.range-seg { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; line-height: 1; }
.range-seg .range-btn {
  background: transparent; border: 0; border-right: 1px solid var(--line);
  color: var(--muted); font-size: .72rem; padding: .1rem .5rem; cursor: pointer;
}
.range-seg .range-btn:last-child { border-right: 0; }
.range-seg .range-btn:hover { color: var(--amber); }
.range-seg .range-btn.on { color: var(--amber); background: rgba(255, 176, 0, .12); }
#range-chip { padding: .1rem .3rem .1rem .5rem; }

/* ── body: tray + workspace ──────────────── */
.app-body { display: flex; flex: 1; overflow: hidden; position: relative; }
.pane-tray {
  width: 168px; min-width: 168px; background: #0d1320;
  border-right: 1px solid var(--line); padding: .5rem .35rem;
  overflow-y: auto; flex-shrink: 0;
}
.pane-tray-title { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); padding: .15rem .3rem .3rem; }
.pane-tray-item {
  display: flex; align-items: center; gap: .4rem; padding: .26rem .45rem;
  border-radius: 6px; cursor: pointer; color: var(--text); font-size: .82rem;
  border: 1px solid transparent; user-select: none;
}
.pane-tray-item:hover { background: var(--panel-2); }
.pane-tray-item.active { background: var(--panel-2); border-color: var(--line); }
.pane-tray-item .check { width: 1rem; color: var(--amber); }
.workspace { flex: 1; overflow: auto; padding: 3px; } /* uniform 3px frame — GridStack's margin opt is a no-op in this static-column build, so the outer gap IS this padding (09-09: was .5rem/1rem/.55rem/6px → first grid point now sits at (3,3)) */
/* Fixed-cell canvas (2026-09-09, Mike: “the grid should NOT resize with the
   window, it should just get more columns and/or rows”): width is set in JS
   to columns × cell (so a wider window ADDS columns at the same cell size),
   and the min-height keeps the canvas filling the viewport so there is always
   empty grid below the panes to drop more into. */
.grid-stack { min-height: 100%; }
/* ── `?noscroll=1` — NO PAGE SCROLLERS, ON ANY DISPLAY (Mike 2026-09-13) ──────
   "Create no-scrollbar localhost URLs with 480x800 device targets ... that I can
   add bannerless panes (from the tray) to while staying within rectangles that
   subtract out the header and footer."
   The phone tier gets this automatically (see the small-display media query), but
   800x480 and 480x800 are NOT that tier — the gate needs BOTH axes — so they
   would keep a scrollbar, and an authoring session that can scroll can slide the
   canvas out from under its own guide. Applied at load by
   js/app.js urlChromeSwitches() and deliberately NOT remembered: it belongs to
   the link, not to the browser. The Live pane keeps its own scroller — this is
   only the page. */
body.noscroll main.workspace { overflow: hidden; }
body.tray-hidden .pane-tray { display: none; }

/* ── panes (gridstack widgets) ───────────── */
.grid-stack-item { display: flex; flex-direction: column; border-radius: 6px; overflow: hidden; z-index: 1; }
.grid-stack-item-content {
  display: flex; flex-direction: column; height: 100%;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 6px; overflow: hidden;
}
.grid-stack-item:hover .grid-stack-item-content { border-color: var(--amber-dim); }
/* pane header = pill; default hugs content (markets + live stretch full-width
   below); 2026-09-09: tighter gaps + 4px slimmer (padding 0 + hit 24) */
.pane-header {
  display: inline-flex; width: max-content; max-width: calc(100% - .4rem);
  align-self: flex-start; align-items: center; gap: .28rem;
  margin: .14rem 0 .06rem .14rem; padding: 0 .5rem;
  /* The banner is the ONLY grab surface (banner-only movement, 2026-09-12), so
     it must win the press where the resize zones overlap it. GridStack sets its
     own handles to z-index 100 (computed, set by the library — not in our CSS),
     and its NW handle (28x28 at the corner) + N/W strips otherwise cover the
     pill's leading edge, turning a "grab the banner" press into a resize: the
     measured symptom was a pane drag that also shrank the pane by the drag
     delta. 101 keeps the pill above the handles while staying inside this
     item's own stacking context (the item carries the raise() z-index), so it
     can never jump above a neighbouring pane. Resizing stays available on the
     S/E/W edges and the SE/SW corners. */
  position: relative; z-index: 101;
  cursor: grab; user-select: none; flex-shrink: 0;
  background: linear-gradient(180deg, #1a2233, #141b2c);
  border: 1px solid var(--line); border-radius: 999px;
}
/* banner-hosted controls (2026-09-09): news scope select + watchlist symbol
   box — styled to sit inside the slim pill without bloating it */
.pane-header select, .pane-header input[type="text"],
.pane-header input[type="number"], .pane-header input[type="date"] {
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  font-size: .72rem; padding: .06rem .3rem; height: 22px; }
.pane-header .scope-sel { max-width: 8.6em; } /* News scope — 'Regional' must show fully (2026-09-09) */
.pane-header .wl-sym { width: 7.2em; }
/* markets + Live + Watchlist/Portfolio/Links: pill spans the pane like the
   tile borders, controls right (Watchlist/Portfolio/Links joined 2026-09-09) */
#pane-markets-us .pane-header, #pane-markets-global .pane-header, #pane-live .pane-header,
#pane-watchlist .pane-header, #pane-favorites .pane-header, #pane-links .pane-header {
  width: calc(100% - .14rem); max-width: calc(100% - .14rem); }
#pane-markets-us .pane-header .pane-actions,
#pane-markets-global .pane-header .pane-actions { margin-left: auto; }
/* Portfolio add-row and Links '+ new group' ride right, tight against the
   window controls (their pills are full width); 2026-09-09, Mike */
#pane-favorites .pane-header .pane-actions,
#pane-links .pane-header .pane-actions { margin-left: 0; }
#pane-favorites .pane-header .ctl-row { margin: 0 0 0 auto; flex-wrap: nowrap; }
#pane-links .pane-header .cr-add { margin-left: auto; }
#pane-watchlist .pane-header .wl-sym { margin-left: auto; } /* symbol box rides with the window buttons, right side */
#pane-live .pane-header .act-n-wrap { margin-left: auto; }
.pane-header:active { cursor: grabbing; }
.pane-label { font-size: .78rem; font-weight: 600; color: var(--amber); letter-spacing: .02em; flex-shrink: 0; }
.pane-note { flex: 0 1 auto; min-width: 0; text-align: center; font-size: .64rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 12rem; margin: 0 .1rem; }
.pane-note:empty { display: none; }
.pane-actions { display: flex; gap: .05rem; align-items: center; flex-shrink: 0; }
.pane-btn {
  background: transparent; border: none; color: var(--muted); cursor: pointer;
  font-size: .72rem; line-height: 1; padding: .1rem .26rem; border-radius: 999px;
}
.pane-btn:hover { color: var(--amber); background: rgba(255, 176, 0, .12); }
.pane-btn.danger:hover { color: #f85149; background: rgba(248, 81, 73, .12); }
.pane-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: .38rem .55rem .5rem; position: relative; }
.pane-empty { color: var(--muted); font-size: .82rem; padding: .4rem 0; }
.pane-err { color: var(--bad); font-size: .78rem; padding: .3rem 0; }
/* moon + clocks + date: content is fit to the pane — NEVER scrollbars (2026-09-09:
   hard invariant for these panes — oversized content clips, it does not
   scroll. Date joined 2026-09-16: Mike, "On the Date pane, no scroll bars,
   please." — it was reaching a scroller through the window, not the pane: see the
   `#pane-date` sizing block below.) */
#pane-moon .pane-body, #pane-clock-analog .pane-body, #pane-clock-digital .pane-body,
#pane-date .pane-body {
  overflow: hidden !important; scrollbar-width: none; -ms-overflow-style: none; }
#pane-moon .pane-body::-webkit-scrollbar, #pane-clock-analog .pane-body::-webkit-scrollbar,
#pane-clock-digital .pane-body::-webkit-scrollbar, #pane-date .pane-body::-webkit-scrollbar {
  display: none; width: 0; height: 0; }
/* Moon image runs to the pane's LEFT edge; the facts text below keeps its own
   inset (2026-09-09, Mike) */
#pane-moon .pane-body { padding-left: 0; }
#pane-moon .moon-facts { padding-left: .55rem; }
/* analog clock: face anchored top-left (no left border), grows with the pane */
#pane-clock-analog .pane-body { display: flex; flex-direction: column; padding: .3rem 0 0; }
#pane-clock-analog .ctl-row { padding: 0 0 0 8px; margin: 0 0 .1rem; } /* sec/zoom ~8px in (2026-09-09: +2 from 6) */
#pane-clock-analog .pane-fill { flex: 1 1 auto; min-height: 0; justify-content: flex-start; margin-top: -2px; }
#pane-clock-analog .ana-slot { flex: 1 1 auto; min-height: 0; }
/* Pane bodies do NOT move panes any more (banner-only movement, 2026-09-12),
   so a pane body must not advertise a grab. The 2026-09-06 body-drag rule
   (`.pane-body, .pane-body * { cursor: grab }`) was NOT removed along with the
   behaviour it described, so it went on painting a hand over every pane body —
   a move affordance for a gesture that no longer exists. Mike caught it on
   🗺 Metros (2026-09-12): the hand is indistinguishable from the map's own pan
   cursor, so the pane looked like it was claiming the gesture. Panes that
   legitimately own a pointer gesture set their OWN cursor — `.pane-header` for
   the move grab, `.mz-svg` for the map. */
.pane-body { cursor: default; }
.pane-body :is(a, button, .fold-bar) { cursor: pointer; }

/* ── pane internals ──────────────────────── */
.ctl-row { display: flex; gap: .4rem; align-items: center; margin-bottom: .3rem; flex-wrap: wrap; }
.ctl-row select, .ctl-row button, .pane-body select {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--line);
  border-radius: 6px; padding: .14rem .4rem; font-size: .78rem;
}
.ctl-row button { cursor: pointer; }
.ctl-row button.on { border-color: var(--amber-dim); color: var(--amber); }

/* ── CLOCK SIZE: REVERTED TO MIKE'S ORIGINAL (2026-09-13) ────────────────────
   An earlier pass today made these pane-relative (`21cqw`) to stop a pinned
   canvas clipping the clock. Mike: "You changed the digital clock and main
   temperature font sizes, go back, please." Reverted to the original viewport
   clamps. The pane-relative form is not lost knowledge — if the clock ever has
   to fit a slot too narrow for it, CAP it instead of shrinking it:
     .digital-clock { font-size: min(clamp(1.6rem, calc(6 * var(--dvw)), 3.4rem), 21cqw); }
   which is the old size everywhere it fit and shrinks only where it would clip.
   The middle value is `--dvw` rather than `vw` (2026-09-16, see :root): with no
   device pinned it IS 1vw, so this is Mike's revert untouched; with a display
   pinned it is that display's own percent, which is the size the device draws.
   NO cqw IS LEFT IN THIS FILE — the same pass also shrank `.date-line` to
   `clamp(.62rem, 4.3cqw, 1.5rem)` behind a `#pane-date .pane-body` container;
   both are reverted with it, so the container-type declaration went too.

   ⚠️ AND ONE DAY LATER THE PANE-RELATIVE FORM CAME BACK — asked for, not imposed
   (2026-09-16, Mike: "phone portrait & landscape now show Digital quite a bit
   smaller. How about using pane size to determine the font size?"). `--digi-fit`
   (set by panes/clock.js from the pane's own box) now supersedes the clamp, which
   stays only as the fallback for the instant before the first measurement — so a
   canvas-less browser keeps exactly the size it always had. */
.digital-clock { font-variant-numeric: tabular-nums; font-size: var(--digi-fit, clamp(1.6rem, calc(6 * var(--dvw)), 3.4rem)); letter-spacing: .04em; text-align: left; line-height: 1.1; color: var(--amber); }
.digital-sec { color: var(--muted); font-size: .6em; }
.pane-fill { display: flex; flex-direction: column; justify-content: center; }
/* clock face mode: both — analog + digital side by side */
.ana-slot, .digi-slot { width: 100%; }
.pane-fill.clock-both { flex-direction: row; align-items: center; justify-content: space-evenly; gap: .8rem; flex-wrap: wrap; }
.pane-fill.clock-both .ana-slot { width: 46%; min-width: 110px; }
.pane-fill.clock-both .digi-slot { width: auto; flex: 1; min-width: 150px; text-align: center; }
.pane-fill.clock-both .digital-clock { font-size: var(--digi-fit, clamp(1.4rem, calc(3.4 * var(--dvw)), 2.6rem)); }
.date-line { font-size: clamp(1rem, calc(2.6 * var(--dvw)), 1.5rem); color: var(--text); text-align: center; }
.date-sub { color: var(--muted); font-size: .85rem; text-align: center; margin-top: .3rem; }
/* ── THE DATE FITS ITS PANE (2026-09-16, Mike) ────────────────────────────────
   Mike: "On the Date pane, no scroll bars, please."

   It was getting a scrollbar through the WINDOW, not the pane: `.date-line` is sized
   in `vw`, which measures the browser window, so in a small Date pane on a 1500px
   window the line rendered at its full 1.5rem (24px) and the body overflowed —
   measured with the two-line format at a pinned 800x480: 122px of content in a 96px
   body, a 4px overflow being enough to raise a scrollbar. Two things fix it:

     · the body joins the moon/clocks never-scroll rule above, so a pane that is
       momentarily too small CLIPS and does not scroll (the established invariant);
     · the two-line stack is CAPPED by the pane's own box — the pattern recorded above
       the clock note: keep the chosen size everywhere it fits, shrink only where it
       would clip. `58px` is what the rest of the pane needs (the format picker ~23px
       + its margin, the meta line ~19px, the body's own vertical padding), and `2.3`
       is the two line-boxes at `line-height: 1.15`; the `.62rem` floor keeps the calc
       from going negative in a tiny slot. Under 84px of body the week/day-of-year line
       steps aside (it frees the 19px that keeps the DATE itself visible). */
#pane-date .pane-body { container-type: size; }
/* ── COLOUR (2026-09-16, Mike): "put day of week in amber and the date line the same
   cyan used elsewhere" — the app's own split: values are the dim cyan #4d80c3 (share
   prices, position values, the portfolio figure, the Links names — see the "dim cyan
   as the rest of the app" notes below), accents are the terminal amber. The date is a
   value; the day of the week is the accent that labels it. Every format keeps the
   date in cyan, so switching formats does not change the palette's meaning. */
#pane-date .date-line {
  line-height: 1.15; color: #4d80c3;
  /* `--date-fit` is MEASURED by the pane for the box it is in right now, in px — see
     the fit block in panes/date.js. It replaces the `1rem..1.5rem` clamp rather than
     sitting inside it: the old clamp's FLOOR was the binding constraint (2.6vw is
     12.5px on a 480px display, so 1rem won and the date could never use a box bigger
     than 16px of type — the exact "needs a very large bounding box to get useful font
     size" Mike hit). The fit carries its own floor (.62rem) and ceiling (1.5rem), so
     the clamp below is the no-JS fallback: without `--date-fit` the date sizes exactly
     as it always did. */
  font-size: clamp(.62rem, var(--date-fit, calc(2.6 * var(--dvw))), 1.5rem); }
#pane-date .date-l1 { color: var(--amber); }
/* ⚠️ NO rule for `.date-line.stacked` any more (2026-09-16): the fit models one line
   box per drawn line, so the two-line format goes through the SAME search. The old
   `calc((100cqh - 58px) / 2.3)` term was a second, coarser model of the same
   constraint and could only disagree with the first. */
#pane-date .date-sub { font-size: min(.85rem, calc(var(--date-fit, 1.55rem) * .55)); margin-top: min(.3rem, 1.4cqh); }
#pane-date .ctl-row select { font-size: min(.85rem, 3.6cqw); }
@container (max-height: 84px) { #pane-date .date-sub { display: none; } }

/* ── weather pane — today-only summary ───────────────────── */
/* header row: big temp on the left, then a STACKED pair on its right —
   "feels 76°" over the condition word (2026-09-13, Mike). align-items:center
   (not baseline) so the two-line column is centred against the temp box and the
   row height stays the temp's.
   ⚠️ SIZE + WEIGHT ARE MIKE'S (2026-09-13: "You changed the digital clock and
   main temperature font sizes, go back, please. Also remove bold on both, if
   present."). `.wx-t` is back to its original 2rem and is explicitly NOT bold —
   the original carried `font-weight: 700`; `normal` is stated rather than
   omitted so no ancestor can re-bold it. `align-items: center` (not baseline)
   means the temp box no longer has to cover the pair's height, so the 2.4rem
   that was raised for that reason is gone.
   NO flex-wrap: the pair must stay to the RIGHT of the temp at every width, so
   the column shrinks (min-width:0) and a long condition word wraps inside
   itself instead of the whole pair dropping below the temp. */
.wx-now { display: flex; align-items: center; gap: .5rem; }
.wx-t { font-size: 2rem; font-weight: normal; color: var(--amber); font-variant-numeric: tabular-nums; line-height: 1.05; }
.wx-side { display: flex; flex-direction: column; align-items: flex-start; gap: .05rem; min-width: 0; }
/* the two lines are ONE visual block, so they get explicit tight leading
   (Mike 2026-09-13: "I'd prefer we removed ~2px of leading between feels like
   and Clear"). Measured ink-to-ink from real pixels: the gap was 9.75px at the
   inherited line-height (~1.45 — 18.56px box around 9.75px of glyph for a
   12.8px font, i.e. ~4.4px of leading above AND below each line). line-height
   1.3 shrinks each box by ~1.95px, i.e. ~1px off each side of the shared edge,
   for a ~2px tighter gap. Do NOT set a negative gap instead — that would
   overlap the boxes rather than remove the leading. */
.wx-feels { font-size: .8rem; line-height: 1.3; color: var(--muted); white-space: nowrap; }
.wx-c { font-size: .82rem; line-height: 1.3; color: var(--muted); }
.wx-feels b { color: #4d80c3; font-weight: 600; font-variant-numeric: tabular-nums; }
.wx-line { font-size: .8rem; color: var(--muted); line-height: 1.35; }
.wx-line b { color: #4d80c3; font-weight: 600; font-variant-numeric: tabular-nums; } /* Hi/Lo/feels/% values — dim blue, same as Live genre + Moon dates (2026-09-09, Mike) */
.wx-sep { color: #3a455c; margin: 0 .25rem; }

.moon-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; flex-wrap: nowrap; } /* figure on top, facts ALWAYS underneath; 3px air between figure and text (Mike 2026-09-09) */
/* ⚠️ NO PIXEL FLOOR ON THE FIGURE (Mike 2026-09-13: "Nothing left clipped").
   This was `clamp(110px, 62%, 300px)`, and 110px is a floor the pane cannot always
   honor: in the landscape cut's moon pane (101px wide) the figure alone was the
   overflow — measured `.moon-wrap` 91.9 wide needing 110, i.e. exactly the 9px of
   horizontal clip, plus 110px of height from `aspect-ratio: 1` on a square figure
   (the card wanted 243px in a 192px pane). `min()` kept the same size wherever
   62% was the winner.
   ⚠️ THE 62% IS GONE TOO (2026-09-16, Mike: "There's so much dead space in Moon
   when the image is roughly the width of text below"). A fixed 62% left the other
   38% of every pane as an empty band beside the image. The size now comes from
   layoutMoon as `--moon-fig-px`: the largest square that fits the width AND leaves
   the facts their room, in BOTH arrangements. The `min(62%, 300px)` below is only
   the declaration-time fallback for a pane whose layoutMoon has not run yet, so
   such a pane still renders exactly as it did before. */
.moon-fig { width: var(--moon-fig-px, min(62%, 300px)); height: var(--moon-fig-px, auto); aspect-ratio: 1; flex-shrink: 0; }
.moon-fig img.nasa-moon { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; background: #000; display: block; }
/* ── MOON: TWO ARRANGEMENTS, CHOSEN BY THE PANE'S OWN SHAPE (2026-09-16, Mike) ─
   Mike: "I need Moon that can display text on the right of the image as well as
   below, depending on how the pane is stretched."
   `cols` (the rules above, unchanged) = figure on top, facts underneath.
   `rows` = figure LEFT, facts RIGHT, which is what a wide-but-short pane needs:
   the stacked form cannot fit there at all (measured 2026-09-16 on a 260x140
   pane: the 155px figure + 70px of facts want 231px of height from a 126px box,
   so the image alone was already scrolling/clipping).
   The switch is decided in JS by FIT, not by a bare aspect ratio (panes/moon.js
   layoutMoon) and lands as `.moon-rows` on the pane body — never inferred here,
   so the two arrangements stay unambiguous for the probes.
   ⚠️ `--moon-fig-px` is set by layoutMoon (the exact square that fits both the
   height and the space left of the facts). CSS cannot derive it: a height-driven
   square with a `max-width` cap loses the aspect ratio and paints an ellipse. */
#pane-moon .pane-body.moon-rows .moon-wrap {
  flex-direction: row; align-items: center; gap: 6px; height: 100%; }
/* ⚠️ NO separate `.moon-rows .moon-fig` rule (removed 2026-09-16): it carried a
   `var(--moon-fig-px, 0px)` fallback, which is a figure of ZERO if the variable is
   ever absent — an invisible moon, and the one way this arrangement could fail
   closed. The shared `.moon-fig` rule above now takes the same variable with a
   sane fallback and covers both arrangements. */
#pane-moon .pane-body.moon-rows .moon-facts {
  width: auto; flex: 1 1 auto; min-width: 0; padding-left: 0; }
/* one-round measurement state used by layoutMoon: the facts at their natural
   (unwrapped) width and height — that pair is what decides whether a column
   beside the figure can hold them. `padding-left: 0` so the number is the TEXT's
   width in both arrangements (the stacked form insets the facts; the side-by-side
   one spaces them with the wrap's gap). Never left on. */
#pane-moon .pane-body.moon-measuring .moon-facts {
  width: max-content !important; flex: 0 0 auto !important; padding-left: 0 !important; }
.moon-facts { flex: 0 0 auto; width: 100%; min-width: 0; line-height: 1.2; }
.moon-facts .big { font-size: 1.4rem; line-height: 1.2; color: var(--amber); }
.moon-facts .row { font-size: .8rem; line-height: 1.15; color: var(--muted); margin-top: .06rem; }
.moon-facts .row b { color: var(--muted); font-weight: 600; } /* phase dimmed to the facts tier (2026-09-09, Mike) */
.moon-facts .row b.moon-date { color: #4d80c3; } /* next full/new dates — dim blue, same as Live genre (2026-09-09, Mike) */

.live-wrap { display: flex; flex-direction: column; gap: .35rem; }
.live-group-title { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-top: .12rem; }
.live-grid { display: flex; flex-wrap: wrap; gap: .3rem; }
.live-stack { display: flex; flex-direction: column; gap: .18rem; }
.live-station { display: flex; align-items: center; gap: .3rem; }
.live-btn .lv-call { color: var(--amber); } /* call + frequency — News title amber (2026-09-09) */
.live-btn .lv-desc { color: #4d80c3; } /* format/network — dimmed steel blue, matches .news-src (2026-09-09) */
.live-btn { font-size: .78rem; color: var(--text); background: #131a26; border: 1px solid #263046; border-radius: 6px; padding: .16rem .5rem; text-decoration: none; white-space: nowrap; }
.live-btn:hover { border-color: var(--amber); color: var(--amber); }
.live-btn.on { border-color: var(--amber); color: var(--amber); }
.live-play { width: 2rem; text-align: center; padding: .16rem .15rem; flex-shrink: 0; color: #3fb950; } /* play arrows green, not muted white (2026-09-09, Mike) */
/* Links: names in the same dim cyan as the rest of the app (2026-09-09) */
#pane-links .live-btn { color: #4d80c3; }
#pane-links .live-btn:hover { color: var(--amber); }
.live-scroll { flex: 1 1 auto; overflow: auto; min-height: 0; }

/* ── the LIVE pane: no horizontal scroller, and a 3px gutter (Mike 2026-09-16) ─
   "I want to forego the horiz scroll bar in Live altogether (I thought we did
   that earlier) ... there's almost 1/4" of dead space beyond KSNE 106.5 and the
   vert scroller; I want that gutter reduced to 3px."
   · SIDEWAYS: the old fix was inside `@container canvas (max-width: 720px)`
   (see the block further down), so it only held on a NARROW CANVAS. The 800x480
   tier (canvas 794) and any wide window kept `overflow: auto`, and the ellipsis
   rules were in the same query — so there a narrow Live pane did not elide, it
   overflowed (measured: a 240px Live in a 1324px canvas, 32px of overflow and a
   real horizontal scrollbar). Live must not scroll sideways at ANY canvas width:
   the station name is `nowrap`, so the honest answer is to elide its tail (full
   name and URL stay in the anchor's title/href, so nothing becomes unreachable).
   · 3px IS A LAYOUT CHANGE, NOT A PADDING TWEAK. `.live-station` is a flex row:
   [▶ play][anchor pill][✕]. The ✕ (`.cr-del`, 15px) is pushed to the right edge
   by `margin-left: auto` behind a `.3rem` (4.8px) gap — 19.8px of every row is
   reserved for a control that is INVISIBLE until hover — while the pill
   (`flex: 0 1 auto`) stops where its TEXT does. So the widest station in the
   default lineup (KSNE 106.5 · Adult Contemporary, pill 215.1px) showed a 19.8px
   dead gutter and every shorter row showed more: the gutter was the ✕'s
   reservation plus whatever slack was left over. Now the ✕ rides ON the pill's
   right end (`position: absolute`, reserving no width — it is already invisible
   until hover) and the pill spans the row, so the gutter is 3px for every row
   and STAYS 3px when Mike resizes the pane. The ✕ now rides ON the pill's right
   end (`position: absolute`), so the whole cost of keeping it off the name is the
   pill's own right padding: 1.8rem (28.8px), sized to the ✕'s 15..29px band —
   which is why the ✕ itself drops 15px → 13px (`font-size: .62rem`, below): two px
   off a hover-only control buys the name back.
   ⚠️ THE ROW IS EXACTLY FULL at Mike's 272px width, so every px the ✕'s band
   takes comes from somewhere. Measured budget at that width: row 269px =
   play 32 + gap 3 + pill 234; the pill's ink room = 234 − 4 (left pad) − 28.8
   (right pad) = 201.2, against 199.1px for the longest name in the default lineup
   (KSNE 106.5 · Adult Contemporary) — 2.1px of margin, i.e. the same razor's edge
   the old layout sat on (its ink room was 212 − 16 = 196 with a 199.1px name, so
   the pill's padding was doing the same job the ✕'s reservation did). Nothing that
   fitted before elides now: `pillOverflow` = 0 at 272px and above.
   · The narrow-canvas block below keeps its own copies: those serve the OTHER
   `.live-scroll` panes (finance / favorites / actives / watchlist) and the Links
   pane's `.live-grid` chips, which this block deliberately does not touch. */
#pane-live .live-scroll { overflow-x: hidden; padding-right: 3px; }
#pane-live .live-station { min-width: 0; position: relative; gap: 3px; }
#pane-live .live-station > a.live-btn { flex: 1 1 auto; min-width: 0; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; padding-left: 4px; padding-right: 1.8rem; }
#pane-live .live-grid > .cr-inline { min-width: 0; max-width: 100%; }
#pane-live .live-grid .live-btn { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
#pane-live .live-station .cr-del { margin-left: 0; position: absolute; right: 15px;
  top: 50%; transform: translateY(-50%); z-index: 101; font-size: .62rem; padding: .12rem .16rem; }
/* `right: 15px`, NOT `right: 2px`: GridStack's east resize handle is a 10px band
   at the pane's right edge (measured 752..762 on a 240px pane, z-index 100,
   pointer-events auto the moment the pointer enters the item) and the ✕ is
   invisible-but-hit-testable until hover, so parking it at the very edge put its
   centre UNDER the handle — a click meant to remove a station would have started a
   pane resize (measured: elementFromPoint at the ✕ centre = the handle). 15px puts
   the whole ✕ clear of both the scrollbar band and the handle, while still riding
   the pill's right end. `z-index: 101` covers the CORNER handles instead: `ne`/`se`
   are 29px wide at the pane's top/bottom-right and a row sitting under one was
   measured stealing the click (a 336px-tall pane: the last visible row's ✕ hit
   `ui-resizable-se`). Above GridStack's 100 the ✕ wins that 13x18px square; the
   handle is still grabbable everywhere else along the edge and at both corners. */
/* A station with no direct stream is NOT a play button: the row's ▶ opens the
   station PAGE, so it wears the link colour (2026-09-16, Mike: "change the
   non-playable the KISF arrow from white to dim cyan"). Same cyan as
   `#pane-links .live-btn`, `.lv-desc`, `.news-src`, the Date line and now the
   Analog hands — one meaning, one colour. */
.live-btn.live-open { color: #4d80c3; }
.live-status { font-size: .7rem; color: var(--muted); margin-bottom: .15rem; min-height: 1em; }
.live-status:empty { display: none; margin: 0; }
.vol-row { display: flex; align-items: center; gap: .4rem; margin: 0 0 .18rem; font-size: .72rem; color: var(--muted); }
/* volume slider: EW/PW/SM-style thumb — amber disc with a white ring (2026-09-09) */
.vol-row input[type="range"] {
  flex: 1; min-width: 0; /* ⚠️ `min-width: auto` floors a range input at its ~129px
    intrinsic width, so a narrow Live pane (194px in Mike's portrait cut) could not
    fit [Frequency][vol][slider]: the row needed 239px and the slider's tail was
    clipped. With min-width 0 the track simply gets shorter (2026-09-13). */
  -webkit-appearance: none; appearance: none; background: transparent;
  height: 20px; margin: 0; cursor: pointer; }
.vol-row input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: #334155; border-radius: 3px; }
.vol-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 14px; height: 14px; background: var(--amber);
  border-radius: 50%; border: 2px solid #4d80c3; margin-top: -5px; /* ring — dim cyan (2026-09-09, Mike) */
  box-shadow: 0 0 4px rgba(0, 0, 0, .5); }
.vol-row input[type="range"]::-moz-range-track { height: 4px; background: #334155; border-radius: 3px; }
.vol-row input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px; background: var(--amber);
  border-radius: 50%; border: 2px solid #4d80c3; box-shadow: 0 0 4px rgba(0, 0, 0, .5); }

/* ── finance pane ─────────────────────────────────────────── */
#pane-finance .pane-body { padding-top: .16rem; } /* tighten banner → first fold gap */
#pane-finance .live-scroll > :first-child .fold-bar { margin-top: 0; } /* ~2px tighter: banner → 'Indices · US' */
.up { color: #3fb950; }
.down { color: #f85149; }
.flat { color: var(--muted); }
.fin-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .35rem; margin-bottom: .2rem; }
.fin-tile { background: #131a26; border: 1px solid #263046; border-radius: 6px; padding: .3rem .45rem .24rem; display: flex; flex-direction: column; min-width: 0; }
.fin-tile-head { display: flex; align-items: center; justify-content: space-between; gap: .3rem; }
.fin-name { font-size: .72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fin-del { background: none; border: none; color: var(--muted); cursor: pointer; font-size: .85rem; line-height: 1; padding: 0 .1rem; opacity: 0; transition: opacity .12s; }
.fin-tile:hover .fin-del, .fin-del:focus-visible { opacity: 1; }
.fin-del:hover { color: #f85149; }
.fin-add { margin-left: auto; background: none; border: none; color: var(--muted); cursor: pointer; font-size: .8rem; line-height: 1; padding: .02rem .3rem; border-radius: 999px; opacity: 1; transition: opacity .12s; }
.fold-bar:hover .fin-add, .fin-add:focus-visible { opacity: 1; }
.fin-add:hover { color: var(--amber); }
.fin-price { font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums; margin-top: .06rem; }
.fin-chg { font-size: .72rem; font-variant-numeric: tabular-nums; }
.fin-spark { width: 100%; height: 24px; display: block; margin-top: .2rem; }
.fin-spark-empty { height: 24px; }
.fin-sym { font-size: .6rem; color: var(--muted); margin-top: .05rem; }
.fin-actives { display: flex; flex-direction: column; margin-bottom: .2rem; }
.fin-row { display: grid; grid-template-columns: 54px 1fr 70px 70px 76px; gap: .4rem; font-size: .78rem; padding: .12rem 0; border-bottom: 1px dashed #1c2333; align-items: baseline; }
#pane-actives .fin-row { padding: 0; } /* Most Active: no padding above entries (2026-09-09, Mike) */
#pane-actives .pane-body { padding-top: .25rem; } /* banner → first entry ~2px tighter (2026-09-09, Mike) */
.fin-a-sym { color: var(--amber); font-weight: 600; }
.fin-a-name { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fin-a-price { text-align: right; font-variant-numeric: tabular-nums; color: #4d80c3; } /* share prices — dim cyan (2026-09-09, Mike) */
.fin-a-chg { text-align: right; font-variant-numeric: tabular-nums; }
.fin-a-vol { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ── foldable finance sections ───────────────────────────── */
.fold-bar { display: flex; align-items: center; gap: .3rem; cursor: pointer; user-select: none;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  padding: .14rem 0 .1rem; margin-top: .14rem; border-bottom: 1px dashed #1c2333; }
.fold-bar:hover { color: var(--amber); }
.fold-caret { width: .8rem; color: var(--amber); flex-shrink: 0; }
/* community harvest sections (Live + Links panes) */
.cm-hdr { border-top: 1px dashed #1c2333; margin-top: .3rem; padding-top: .22rem; }
.cm-title { color: var(--amber); font-weight: 600; }
.cm-cat { font-size: .6rem; text-transform: uppercase; letter-spacing: .08em; color: #55617a; margin: .3rem 0 .05rem; }
/* Top-N count control lives in the banner pill (Most Active) */
.act-n-wrap { display: inline-flex; align-items: center; gap: .18rem; color: var(--muted); font-size: .64rem; margin-left: .15rem; }
.act-n { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 999px; font-size: .64rem; padding: .05rem .18rem; cursor: pointer; }
.fin-input { background: #0d1320; border: 1px solid #263046; color: var(--text); border-radius: 6px; padding: .14rem .45rem; font-size: .78rem; width: 9rem; }
.fin-input::placeholder { color: #55617a; }

/* ── My Stocks pane — positions table + watchlist ────────── */
.pos-wrap { min-width: 560px; }
.pos-grid { display: grid; grid-template-columns: 52px minmax(0, 1fr) 56px 52px 96px 68px 104px 18px; gap: .35rem; align-items: center; font-size: .74rem; }
.pos-head { font-size: .62rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: .1rem 0; border-bottom: 1px dashed #1c2333; }
.pos-row { padding: .12rem 0; border-bottom: 1px dashed #1c2333; }
.pos-sym { color: var(--amber); font-weight: 600; font-size: .78rem; font-variant-numeric: tabular-nums; } /* same symbol size as Most Active (2026-09-09, Mike) */
.pos-name { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .7rem; }
.pos-price, .pos-val, .pos-pl { text-align: right; font-variant-numeric: tabular-nums; }
.pos-val { color: #4d80c3; } /* position value — dim cyan (2026-09-09, Mike) */
.pos-pl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pos-sh-cell input, .pos-d-cell input { width: 100%; min-width: 0; }
.fin-sh { width: 4.8rem; }
.fin-d { width: 8.6rem; }
.pos-sym-in { width: 6.6rem; }
.ctl-row .fin-sh, .ctl-row .fin-d, .pane-body .fin-sh, .pane-body .fin-d {
  background: var(--panel-2); color: #4d80c3; border: 1px solid var(--line); /* shares + bought-date text — dim cyan (2026-09-09, Mike) */
  border-radius: 6px; padding: .14rem .4rem; font-size: .78rem;
}
input[type="date"] { color-scheme: dark; }
.pos-total { display: flex; justify-content: flex-end; gap: 1.1rem; font-size: .74rem;
  padding: .3rem 0 .05rem; border-top: 1px solid var(--line); color: var(--muted);
  font-variant-numeric: tabular-nums; }

/* portfolio history chart — full width of the positions list feeding it */
.perf-cap { display: flex; justify-content: flex-end; gap: 1.1rem; font-size: .74rem;
  padding: .25rem 0 .1rem; color: var(--muted); font-variant-numeric: tabular-nums;
  white-space: nowrap; }
/* the portfolio VALUE figure in the chart caption — dim cyan, same as the
   Positions value column (.pos-val): never red/green, the P/L span carries
   that (2026-09-09, Mike) */
.perf-val { color: #4d80c3; }
.perf-svg { display: block; width: 100%; min-width: 560px; height: 132px; }
.perf-line { fill: none; stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.perf-line-cost { stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 4 3; opacity: .85; }
.perf-line-value { stroke: var(--amber); }
.perf-grid { stroke: #2b3550; stroke-width: 1; vector-effect: non-scaling-stroke; opacity: .8; }
.perf-axis { position: relative; width: 100%; height: 1.2em; font-size: .68rem;
  color: var(--muted); padding-top: .12rem; font-variant-numeric: tabular-nums; }
/* Line box must fit INSIDE the axis box: the default line-height (~1.45)
   overflows the 1.2em-high axis by ~2.7px, and .pf-pin's overflow:hidden
   clipped the bottom of the date labels exactly where the Positions bar
   starts (2026-09-09, Mike). Tighter leading = labels fully visible with no
   layout shift anywhere else. */
.perf-axis span { position: absolute; top: 0; white-space: nowrap; line-height: 1.15; }

.news-chips { display: flex; gap: .35rem; flex-wrap: wrap; }
.news-chips button { font-size: .74rem; padding: .12rem .5rem; }
.news-list { list-style: none; margin: .3rem 0 0; padding: 0; }
.news-list li { padding: .2rem 0; border-bottom: 1px dashed var(--line); } /* ~1px less each side ≈ 2px tighter between entries (2026-09-09) */
.news-list li:last-child { border-bottom: none; }
.news-list a { color: var(--amber); text-decoration: none; font-size: .84rem; line-height: 1.3; display: block; }
.news-list a:hover { color: var(--amber); text-decoration: underline; }
.news-src { color: #4d80c3; font-size: .72rem; } /* original source — dimmed steel blue, matches .lv-desc in Live */
.news-meta { color: var(--muted); font-size: .72rem; margin-top: .15rem; }
/* News: tighter banner → first-item gap (2026-09-09, Mike) */
#pane-news .pane-body { padding-top: .18rem; }
#pane-news .news-list { margin-top: 0; }

/* ── footer ──────────────────────────────── */
#foot {
  flex-shrink: 0; border-top: 1px solid var(--line); padding: .14rem .7rem;
  color: var(--muted); font-size: .68rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-height: 1.3rem; /* pinned too — the bottom edge of the content area is as fixed as the top */
}
/* footer dev toggle (2026-09-10, Mike) — the switch for dev chrome: ON shows the
   display-size reference rectangles on the canvas PLUS the device-resolution
   selection; OFF is plain production. Two states only, the chip is amber while
   on (.chip-btn.on). */
#foot { display: flex; align-items: center; gap: .6rem; }
#foot > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.foot-dev { margin-left: auto; display: inline-flex; align-items: center; gap: .45rem; }
.foot-dev .chip-btn { font-size: .68rem; padding: .1rem .55rem; }
.dev-select {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; font-size: .68rem; padding: .1rem .4rem; max-width: 13rem;
}
.dev-select:hover { color: var(--amber); border-color: var(--amber-dim); }

/* ── responsive: small screens stack the tray ── */
@media (max-width: 720px) {
  .app-body { flex-direction: column; }
  .pane-tray { width: 100%; min-width: 0; max-height: 130px; border-right: none; border-bottom: 1px solid var(--line); }
  .pane-tray-items { display: flex; flex-wrap: wrap; }
  #tray-items { display: flex; flex-wrap: wrap; }
  .tagline { display: none; }
}

/* ── on a genuinely SMALL DISPLAY the Panes bar is not offered AT ALL ───────
   Mike 2026-09-13: "in these small displays, the user won't get that at all."
   Below 720px wide the tray stops being a sidebar and stacks, so it starts
   costing VERTICAL space instead of horizontal — and on the 320x480 phone tier
   that is 130px of a 480px screen: 27% of the display, measured
   (`F:/tmp/cr_mike2/chrome320.js`: canvas 282.1px with it, 412.1px without).
   Height is what makes it fatal, so the gate needs BOTH axes: a 700x780 window
   — one Mike actually tests in — keeps its Panes bar, because the tray is
   affordable there; a 320x480 or 480x320 display does not.
   The toggle goes with the panel: a control that cannot do anything is a lie.
   The arrangement is already open and complete on such a display, so nothing
   is lost — panes come back from the saved layout, not from the tray. */
@media (max-width: 720px) and (max-height: 600px) {
  /* ── NO PAGE SCROLLBARS ON A REAL DEVICE (Mike 2026-09-13) ────────────────
     "On a real device we're not going to provide/enable page scroll bars, only
     the Live pane will have a vert scroller." The canvas IS the display, so on
     the display there is nothing legitimate to scroll to: what does not fit is
     CLIPPED. A layout that overflows is a design error the band guides exist to
     prevent, not something the user should have to pan around for.
     The Live pane keeps its own vertical scroller (`.live-scroll`) — that one is
     INSIDE the pane and untouched here.
     DEV KEEPS THE SCROLL, deliberately: the authoring view must be able to reach
     a device box taller/wider than the window (a 1:1 phone pin in a small window)
     and to reach whatever a pane bleed pushed past the edge. Authoring pans; the
     product does not.
     SCOPE: the phone tier only. `800x480`/`480x800` are the FULL chrome tier (the
     small gate needs BOTH ≤720 wide and ≤600 tall), so they still scroll if a
     layout overflows — that is a tier decision for Mike, not an oversight. */
  body:not(.dev) main.workspace { overflow: hidden; }
  .pane-tray { display: none; }
  #btn-tray { display: none; }
  /* ── exactly TWO controls survive in the top bar: the user name and the
     location. Mike 2026-09-13: "at 320 width, there are only two controls: user
     name and location." Everything else here is chrome a finished small-display
     dashboard has no use for.
     This is STATED, not left to the sacrifice cascade: `#profile-chip` sits 4th
     in FIT_ORDER, so the cascade would eat the user name itself once the bar got
     tight, and `#loc-chip` is not in FIT_ORDER at all (it survives by accident,
     not by design). Both are pinned visible; the rest are pinned away. */
  #topbar .brand,
  #topbar .tagline,
  #btn-mic, #btn-layouts, #range-chip, .ko-fi-top { display: none !important; }
  /* PINNED VISIBLE — this was documented but never written, so both chips were
     surviving on luck (the bar happened to be empty enough that the sacrifice
     cascade never fired). With `#btn-min` back in play below, luck is no longer
     enough: the cascade would reach `#profile-chip` (4th) long before it reaches
     the minimal button (last) and eat the user's NAME. */
  #topbar #profile-chip,
  #topbar #loc-chip { display: inline-flex !important; }
  /* `#btn-min` is deliberately NOT in the list above. It is the control whose
     whole job is this screen ("no banner, no pane controls"), and pinning it away
     made minimal mode unreachable on the displays it was designed for — the exact
     symptom Mike hit 2026-09-13 ("I lost the button that removes pane banners and
     within-pane controls"). Left to the normal machinery instead:
       · `.moot` hides it when the dashboard holds panes outside the small set
       · the sacrifice cascade hides it ONLY when the row is genuinely too tight
         (it is last in FIT_ORDER), which is what keeps 320-wide down to two */
  /* IN PRODUCTION it is also `.moot` on the small tier, and that is the point
     (Mike 2026-09-13): "you're showing the layout with pane banners and internal
     controls. Not something we'd ever ship." Minimal chrome is FORCED on a small
     display in production (js/app.js `refreshMinimal`: `small && !DEV`), so a
     toggle for it would be a control with nothing to toggle — the bar is back to
     exactly the two controls (name, location) this display ships with. DEV mode
     (footer switch / ?dev) keeps the button, because the banner is the only DRAG
     surface: a 320x480 cut is arranged in dev mode and ships bannerless. */
  #topbar #btn-min.moot { display: none !important; }
  /* and the footer keeps no buttons — "we wouldn't show ... any of the buttons
     in the footer" (Mike 2026-09-13). The attribution line stays; only controls
     go. This also covers the dev-only footer controls: there is no room for a
     dev switch on a phone canvas, and the ?dev URL still crosses over.
     HIDE THE GROUPS, NOT THEIR CHILDREN (Mike 2026-09-13: "Also no need for undo
     in this mode"). The old rule hid `#foot .chip-btn` and left the undo badge
     behind — `#undo-depth` is a plain span (js/app.js paintUndo writes `1/30`
     into it), so a shipped 320x480 screenshot showed a stranded "1/30" in the
     footer with no button to explain it. Every one of these groups is meaningless
     without its button/slider, so the group is the unit that goes. */
  #foot .foot-dev,
  #foot .foot-undo,
  #foot .foot-savelayout,
  #foot .chip-btn,
  #foot .dev-select { display: none !important; }
}

/* ── PANE BEHAVIOUR FOLLOWS THE CANVAS, NOT THE WINDOW (2026-09-13) ──────────
   These rules are about a PANE being narrow, and a pane's width comes from the
   CANVAS. Keyed to the window they were silently wrong the moment the two differ —
   which is exactly the dev workflow for a small-display cut: a 320x480 device
   pinned inside a 1500x950 window. There the media query did NOT fire, so Live kept
   `overflow: auto` + `white-space: nowrap` and the pinned preview showed a
   horizontal scrollbar with 272px of station rows in a 194px pane: the very defect
   this block fixed for a real small window, still present in every preview of it.
   A small window has a small canvas (the canvas is the window minus its chrome), so
   these fire identically there — nothing is lost by moving them here.
   `container: canvas / inline-size` is safe on the grid: GridStack already makes
   `.grid-stack` `position: relative`, so layout containment cannot move the items'
   containing block, and the width is set by JS, never derived from the children. */
.grid-stack { container: canvas / inline-size; }
@container canvas (max-width: 720px) {
  /* Live: no horizontal scrollbar (Mike 2026-09-13: "In these minimal displays,
     we can forego the horizontal scrollbar in Live"). `.live-scroll` is
     `overflow: auto` and `.live-btn` is `white-space: nowrap`, so a narrow pane
     grows a horizontal scrollbar — measured **78px** of overflow in the 194px-wide
     portrait Live (content 272px). The ▶ play and ✕ delete are separate flex items
     and keep their space; the link shrinks and ellipsizes its tail instead, so no
     control becomes unreachable and only the tail of a long station name is
     clipped (the full name and URL are still in the link's title and href). */
  .live-scroll { overflow-x: hidden; }
  .live-station { min-width: 0; }
  /* BOTH scrollers: the radio rows AND the TV/links chip grid. The chip grid was
     the actual culprit (240px in a 194px box): it is `flex-wrap: wrap`, but a
     single chip is `white-space: nowrap`, so one long station/link name still
     pushed the row past the pane. The ✕ delete rides the chip as a SIBLING of
     the anchor (.cr-inline), so ellipsizing the anchor cannot hide it. */
  .live-station > a.live-btn,
  .live-grid .live-btn { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  /* ⚠️ the TV/links chips are NOT direct children of .live-grid — each is wrapped
     in `<span class="cr-inline">` (linkChip(), panes/live.js), so a `> a.live-btn`
     selector silently matches nothing and the overflow stays. The wrapper needs
     the cap too. */
  .live-grid > .cr-inline { min-width: 0; max-width: 100%; }
}

/* ── the TOP Creator Support link goes when the header is under real pressure
   (2026-09-12, Mike: "On small displays, the top Creator Support link can go
   (we still have the bottom one)"). The footer carries the same link
   (clockradio.html), so nothing is lost — this stops the topbar spending its
   scarcest resource on a duplicate.
   BREAKPOINT IS MEASURED, NOT INHERITED. First attempt used 1331px (the
   canvas-fit "small display" line) and Mike pushed back: "1332px sounds large.
   If you just have had the site controls left after squeezing out ClockRadio
   and the image line, it looks a lot less than that." He was right — measured
   intrinsic widths (Playwright, viewport 2600, nothing hidden):
      bar padding+border      22.40px
      brand block (+tagline) 256.72px   (tagline alone 142.86px)
      bar gap                  9.60px
      chips gap                5.60px
      chips (site controls)  644.63px   -> profile 67.5, loc 207.8, layouts 33.4,
                                          panes 70.0, range 111.0, ko-fi 127.0
      FULL ROW               933.35px
      controls only          667.03px
      controls minus ko-fi   540.03px
   So the row has no pressure at all above ~934px; at 1331 the link was being
   dropped with 366px of slack to spare — and the width cascade below never
   fired at ANY width >=720 (nothing was ever .fit-hid). 933 = the point where
   the complete row stops fitting, i.e. where giving something up is actually
   required rather than premature.
   Two further measurements, so the constant is bracketed rather than lucky:
   the loc chip is a FIXED width (.loc-sel max-width 9.5em + ellipsis, so the
   chosen city never changes the row — verified Home / Phoenix / longest label
   all 933.34), but the city FILTER grows 4.2em -> 7em on focus
   (css 1568), making the row 967.39px while it has the caret. Nothing is
   hidden in that band and nothing overflows: #topbar is flex and `.chips` can
   shrink, so the row COMPRESSES instead of overflowing — that is also why the
   cascade is almost never seen above ~700px and this media query is the only
   thing hiding the link in 700-1332px. 933 is the idle fit line; 967.39 is the
   focused-filter worst case (raise the query to 967 if the duplicate should
   yield first even while the caret is in the city box).
   ── WHERE THE DUPLICATE LINK YIELDS IS NOW MEASURED AT RUNTIME (2026-09-13) ──
   History first, because the numbers still explain the size of the saving. The
   range chip is content-hidden (`.moot`, js/app.js rangeMoot) whenever no
   Indices / Watchlist / Portfolio pane is open, and re-measured 2026-09-13 at
   viewport 2600 it costs **116.60px of the row** (111.00 chip + its 5.60px
   chips-gap): the row is 933.35px with the picker and 816.75px without it
   (22.40 pad + 256.72 brand + 9.60 gap + chips 644.63 / 528.03). That was
   encoded as two constants: <=933px with the picker, <=816px without.
   THE CONSTANTS WERE THE WRONG SHAPE and went stale the same day. `#btn-min`
   (minimal mode, below) is a third CONTENT-dependent item, and it lengthens the
   quote-less row by ~96px — so the static rule was hiding the link with ~96px of
   slack to spare, which is precisely the complaint Mike raised about the
   inherited 1331. There is no fixed list of states to enumerate here, so the line
   is no longer a constant: `js/app.js applyKofiLine()` measures the row's NATURAL
   width (`#topbar.measuring`, one synchronous read with compression off) and
   toggles `body.kofi-yield` whenever the row's contents change or the window
   resizes. The 816px rule below stays as the no-JS floor — the narrowest full row
   this chrome can have — so without JS the bar still sheds the duplicate rather
   than letting it sit in a row that cannot hold it. Below its own line, further
   pressure is still FIT_ORDER (tagline next); and because the row COMPRESSES
   rather than overflows, a few px of font-metric drift costs at most a few px of
   slack either way. ── */
body.kofi-yield .ko-fi-top { display: none; }
@media (max-width: 816px) {
  .ko-fi-top { display: none; }
}
/* the natural-width probe: `flex: 0 0 auto` stops the .chips compression that
   would otherwise make a measured child report less than its content, and the
   link is forced shown so the row is measured WITH it (measuring a row that
   already excludes the link reports a row that fits — self-confirming). Added
   and removed inside one synchronous block, so nothing paints with it applied. */
#topbar.measuring,
#topbar.measuring .chips,
#topbar.measuring .chips > * { flex: 0 0 auto !important; }
#topbar.measuring .ko-fi-top { display: inline-block !important; }

/* ── MINIMAL mode (2026-09-13, Mike) ─────────────────────────────────────────
   "the smallest possible top bar ... leaving JUST user, location, and a button
   that can remove the panes button, pane banners, and controls within (except
   Live's controls) when the layout contains no more than {analog, digital,
   moon, weather, Live}".
   Engaged by `body.minimal`, set in js/app.js `refreshMinimal()` ONLY while
   every open pane is one of those five (so a dashboard with a Markets pane in it
   never gets banner-stripped), and only when the per-browser preference is on.
   Content-based hiding is always its own class — see the `.moot` note above.

   The bar: brand → gone, so the ◷ mark and the word ClockRadio (and the
   tagline) are what "exclude {'ClockRadio', image-id}" means. Mic/layouts/
   Panes/range/Creator Support also go, leaving profile + location + #btn-min.
   !important because two of these get display values from other rules
   (`body.no-voice #btn-mic`, the ko-fi media query above, `#btn-tray.on`).

   ⚠️ DEV KEEPS THE TRAY IN MINIMAL (Mike 2026-09-13): "I'd like to stick with
   the current no banners, no internal controls digital/analog panes for the next
   couple of layouts, but I'll need the tray, so I can see what combos of panes I
   can get to fit." Bannerless is how a small display SHIPS, so authoring in it is
   the only way to judge a fit — and with the tray gone the author cannot add or
   remove a pane to test a combination. Both production rules below are therefore
   scoped `:not(.dev)`; the shipped view still drops the tray and its toggle. */
body.minimal .brand { display: none; }
body.minimal #btn-mic,
body.minimal #btn-layouts,
body.minimal #range-chip,
body.minimal .ko-fi-top { display: none !important; }
body.minimal:not(.dev) #btn-tray { display: none !important; }
/* the Panes bar itself — same rule the tray toggle uses, so the workspace
   widens by the tray's 186px and the canvas simply gains COLUMNS (cell size is
   fixed; no pane moves or rescales) */
body.minimal:not(.dev) .pane-tray { display: none; }
/* banners: label + note + ▁ ✕ pill. `.grid-stack-item` is a flex column of
   header + body, so the body takes the whole box and the pane's content shifts
   up into the reclaimed strip. The pane BOX is untouched — the user's size and
   placement are never auto-changed. (The 2026-09-13 trade — "these panes can
   still be RESIZED but not dragged until minimal mode is exited" — is gone:
   in this mode the pane's CONTENT is the grab surface, so a bannerless pane is
   still arrangeable. See `.pane-body { cursor: grab }` below.) */
/* ── PER-PANE, NOT ALL-OR-NOTHING (2026-09-16, Mike) ──────────────────────────
   Mike: "I need the min/full button in the header applicable to the same panes as
   used in the small display layouts. News cannot do without its local/regional
   selector, so it always has its banner. Likewise for Links."
   The mode now applies to the panes it APPLIES TO, and only those: JS stamps
   `.min-ok` on every pane whose id is in MIN_PANES (one source of truth, in JS), so
   a pane outside that set — News, Links, the market panes, Watchlist, Voice — keeps
   its banner and its in-banner controls no matter what the mode is doing, and the
   mode is still usable in a layout that contains them.
   MEASURED set (the panes the small-display cuts actually use): clock-analog,
   clock-digital, moon, weather, live, metros, actives, date. Every one keeps only
   max/close in its banner, which is what the mode is for; the ONE exception worth
   knowing is Metros, whose ⟲ reset and ⌖ frame buttons live in the banner — wheel
   zoom, dot clicks and dragging the empty map all still work without them. */
body.minimal .grid-stack-item.min-ok .pane-header { display: none; }
/* controls INSIDE the panes. Live is the exception (Mike): its volume +
   station-order line is `.vol-row`, which is NOT in this list and stays. */
body.minimal .ctl-row { display: none; }
/* keep the pin ✕/▁ row out of the way if a pane re-adds one in its body */
body.minimal .pane-actions { display: none; }
/* ── the footer's UNDO control goes in this mode (Mike 2026-09-13: "Also no need
   for undo in this mode"). Undo exists to take back an ARRANGEMENT mistake, and
   minimal chrome is the finished-arrangement view — the same reasoning that drops
   the Panes bar. Scoped to the MODE, not the small tier, so it holds at desktop
   size too (a small display already loses the whole group, css 493). `.foot-undo`
   is hidden as a UNIT because the depth badge is a plain span: hiding the button
   alone leaves "1/30" stranded, which is exactly what Mike saw. */
body.minimal .foot-undo { display: none !important; }
/* ── ALWAYS SOMETHING TO DRAG (2026-09-13, Mike) ──────────────────────────────
   With the banner gone the pill's grab surface is gone too, so in minimal mode
   the pane's CONTENT is the grab surface (js/app.js wireMinimalBodyDrag →
   minBodyDown). The edge strips cannot be used for it: measured with the pointer
   over a pane, GridStack's autohidden handles un-hide at z-index 100 and claim
   the whole top edge (`.ui-resizable-nw` 28x28 corner, `.ui-resizable-n` from
   x=25 to w-25), plus e/w/s — a strip there would fight the resize.
   The cursor is the affordance, and it is honest: this is the one mode where a
   body drag really moves the pane. (2026-09-12 removed `cursor: grab` from pane
   bodies precisely because no such gesture existed any more — this re-instates
   it exactly where the gesture does exist.)
   Controls keep their own cursor so the hand does not advertise a drag over
   Live's slider / select / buttons. */
body.minimal .pane-body { cursor: grab; }
body.minimal .pane-body:active { cursor: grabbing; }
body.minimal .pane-body input,
body.minimal .pane-body select,
body.minimal .pane-body button,
body.minimal .pane-body a { cursor: pointer; }
/* ── the Metros MAP's empty area is the pane's grab surface in this mode
   (2026-09-15): js/app.js mapYieldsToPane hands the press to the pane, so the
   cursor must say PANE, not the map's `.mz-nopan` no-pan `default` — that would
   be the same lie Mike caught on 2026-09-12 ("cursor is a hand over a map that
   would not move"), just mirrored. A press on a DOT still belongs to the map,
   so `.near` keeps its pointer. */
body.minimal .mz-svg.mz-nopan:not(.near) { cursor: grab; }
body.minimal .mz-svg.mz-nopan:not(.near):active { cursor: grabbing; }
/* while a content drag is actually running, don't smear a text selection */
body.pane-dragging, body.pane-dragging * { user-select: none !important; }
/* A native image drag beats a pane drag (it cancels pointer events), so in
   minimal mode images inside a pane are not natively draggable — otherwise the
   moon pane's NASA <img> is the one pane you cannot move. Paired with the
   `dragstart` guard in js/app.js, which the engines that ignore this honour. */
body.minimal .pane-body img { -webkit-user-drag: none; user-drag: none; }

/* ── fixed-cell grid geometry (2026-09-09, Mike: “the grid should NOT
   resize with the window, it should just get more columns and/or rows”) ──
   One column = var(--cellw) PIXELS (set from js/app.js, remembered per
   browser), so a pane's pixel size never depends on the window width and
   widening the window simply provides MORE columns of the same size. These
   rules are count-agnostic on purpose: the previous gs-240-only block
   silently stopped matching the moment the column count changed, which
   collapsed every pane to content width. Columns 0–400.
   (v11 ships 12-column CSS only, hence this table.) */
.grid-stack > .grid-stack-item[gs-w="1"]{width:calc(var(--cellw, 6px)*1)}
.grid-stack > .grid-stack-item[gs-w="2"]{width:calc(var(--cellw, 6px)*2)}
.grid-stack > .grid-stack-item[gs-w="3"]{width:calc(var(--cellw, 6px)*3)}
.grid-stack > .grid-stack-item[gs-w="4"]{width:calc(var(--cellw, 6px)*4)}
.grid-stack > .grid-stack-item[gs-w="5"]{width:calc(var(--cellw, 6px)*5)}
.grid-stack > .grid-stack-item[gs-w="6"]{width:calc(var(--cellw, 6px)*6)}
.grid-stack > .grid-stack-item[gs-w="7"]{width:calc(var(--cellw, 6px)*7)}
.grid-stack > .grid-stack-item[gs-w="8"]{width:calc(var(--cellw, 6px)*8)}
.grid-stack > .grid-stack-item[gs-w="9"]{width:calc(var(--cellw, 6px)*9)}
.grid-stack > .grid-stack-item[gs-w="10"]{width:calc(var(--cellw, 6px)*10)}
.grid-stack > .grid-stack-item[gs-w="11"]{width:calc(var(--cellw, 6px)*11)}
.grid-stack > .grid-stack-item[gs-w="12"]{width:calc(var(--cellw, 6px)*12)}
.grid-stack > .grid-stack-item[gs-w="13"]{width:calc(var(--cellw, 6px)*13)}
.grid-stack > .grid-stack-item[gs-w="14"]{width:calc(var(--cellw, 6px)*14)}
.grid-stack > .grid-stack-item[gs-w="15"]{width:calc(var(--cellw, 6px)*15)}
.grid-stack > .grid-stack-item[gs-w="16"]{width:calc(var(--cellw, 6px)*16)}
.grid-stack > .grid-stack-item[gs-w="17"]{width:calc(var(--cellw, 6px)*17)}
.grid-stack > .grid-stack-item[gs-w="18"]{width:calc(var(--cellw, 6px)*18)}
.grid-stack > .grid-stack-item[gs-w="19"]{width:calc(var(--cellw, 6px)*19)}
.grid-stack > .grid-stack-item[gs-w="20"]{width:calc(var(--cellw, 6px)*20)}
.grid-stack > .grid-stack-item[gs-w="21"]{width:calc(var(--cellw, 6px)*21)}
.grid-stack > .grid-stack-item[gs-w="22"]{width:calc(var(--cellw, 6px)*22)}
.grid-stack > .grid-stack-item[gs-w="23"]{width:calc(var(--cellw, 6px)*23)}
.grid-stack > .grid-stack-item[gs-w="24"]{width:calc(var(--cellw, 6px)*24)}
.grid-stack > .grid-stack-item[gs-w="25"]{width:calc(var(--cellw, 6px)*25)}
.grid-stack > .grid-stack-item[gs-w="26"]{width:calc(var(--cellw, 6px)*26)}
.grid-stack > .grid-stack-item[gs-w="27"]{width:calc(var(--cellw, 6px)*27)}
.grid-stack > .grid-stack-item[gs-w="28"]{width:calc(var(--cellw, 6px)*28)}
.grid-stack > .grid-stack-item[gs-w="29"]{width:calc(var(--cellw, 6px)*29)}
.grid-stack > .grid-stack-item[gs-w="30"]{width:calc(var(--cellw, 6px)*30)}
.grid-stack > .grid-stack-item[gs-w="31"]{width:calc(var(--cellw, 6px)*31)}
.grid-stack > .grid-stack-item[gs-w="32"]{width:calc(var(--cellw, 6px)*32)}
.grid-stack > .grid-stack-item[gs-w="33"]{width:calc(var(--cellw, 6px)*33)}
.grid-stack > .grid-stack-item[gs-w="34"]{width:calc(var(--cellw, 6px)*34)}
.grid-stack > .grid-stack-item[gs-w="35"]{width:calc(var(--cellw, 6px)*35)}
.grid-stack > .grid-stack-item[gs-w="36"]{width:calc(var(--cellw, 6px)*36)}
.grid-stack > .grid-stack-item[gs-w="37"]{width:calc(var(--cellw, 6px)*37)}
.grid-stack > .grid-stack-item[gs-w="38"]{width:calc(var(--cellw, 6px)*38)}
.grid-stack > .grid-stack-item[gs-w="39"]{width:calc(var(--cellw, 6px)*39)}
.grid-stack > .grid-stack-item[gs-w="40"]{width:calc(var(--cellw, 6px)*40)}
.grid-stack > .grid-stack-item[gs-w="41"]{width:calc(var(--cellw, 6px)*41)}
.grid-stack > .grid-stack-item[gs-w="42"]{width:calc(var(--cellw, 6px)*42)}
.grid-stack > .grid-stack-item[gs-w="43"]{width:calc(var(--cellw, 6px)*43)}
.grid-stack > .grid-stack-item[gs-w="44"]{width:calc(var(--cellw, 6px)*44)}
.grid-stack > .grid-stack-item[gs-w="45"]{width:calc(var(--cellw, 6px)*45)}
.grid-stack > .grid-stack-item[gs-w="46"]{width:calc(var(--cellw, 6px)*46)}
.grid-stack > .grid-stack-item[gs-w="47"]{width:calc(var(--cellw, 6px)*47)}
.grid-stack > .grid-stack-item[gs-w="48"]{width:calc(var(--cellw, 6px)*48)}
.grid-stack > .grid-stack-item[gs-w="49"]{width:calc(var(--cellw, 6px)*49)}
.grid-stack > .grid-stack-item[gs-w="50"]{width:calc(var(--cellw, 6px)*50)}
.grid-stack > .grid-stack-item[gs-w="51"]{width:calc(var(--cellw, 6px)*51)}
.grid-stack > .grid-stack-item[gs-w="52"]{width:calc(var(--cellw, 6px)*52)}
.grid-stack > .grid-stack-item[gs-w="53"]{width:calc(var(--cellw, 6px)*53)}
.grid-stack > .grid-stack-item[gs-w="54"]{width:calc(var(--cellw, 6px)*54)}
.grid-stack > .grid-stack-item[gs-w="55"]{width:calc(var(--cellw, 6px)*55)}
.grid-stack > .grid-stack-item[gs-w="56"]{width:calc(var(--cellw, 6px)*56)}
.grid-stack > .grid-stack-item[gs-w="57"]{width:calc(var(--cellw, 6px)*57)}
.grid-stack > .grid-stack-item[gs-w="58"]{width:calc(var(--cellw, 6px)*58)}
.grid-stack > .grid-stack-item[gs-w="59"]{width:calc(var(--cellw, 6px)*59)}
.grid-stack > .grid-stack-item[gs-w="60"]{width:calc(var(--cellw, 6px)*60)}
.grid-stack > .grid-stack-item[gs-w="61"]{width:calc(var(--cellw, 6px)*61)}
.grid-stack > .grid-stack-item[gs-w="62"]{width:calc(var(--cellw, 6px)*62)}
.grid-stack > .grid-stack-item[gs-w="63"]{width:calc(var(--cellw, 6px)*63)}
.grid-stack > .grid-stack-item[gs-w="64"]{width:calc(var(--cellw, 6px)*64)}
.grid-stack > .grid-stack-item[gs-w="65"]{width:calc(var(--cellw, 6px)*65)}
.grid-stack > .grid-stack-item[gs-w="66"]{width:calc(var(--cellw, 6px)*66)}
.grid-stack > .grid-stack-item[gs-w="67"]{width:calc(var(--cellw, 6px)*67)}
.grid-stack > .grid-stack-item[gs-w="68"]{width:calc(var(--cellw, 6px)*68)}
.grid-stack > .grid-stack-item[gs-w="69"]{width:calc(var(--cellw, 6px)*69)}
.grid-stack > .grid-stack-item[gs-w="70"]{width:calc(var(--cellw, 6px)*70)}
.grid-stack > .grid-stack-item[gs-w="71"]{width:calc(var(--cellw, 6px)*71)}
.grid-stack > .grid-stack-item[gs-w="72"]{width:calc(var(--cellw, 6px)*72)}
.grid-stack > .grid-stack-item[gs-w="73"]{width:calc(var(--cellw, 6px)*73)}
.grid-stack > .grid-stack-item[gs-w="74"]{width:calc(var(--cellw, 6px)*74)}
.grid-stack > .grid-stack-item[gs-w="75"]{width:calc(var(--cellw, 6px)*75)}
.grid-stack > .grid-stack-item[gs-w="76"]{width:calc(var(--cellw, 6px)*76)}
.grid-stack > .grid-stack-item[gs-w="77"]{width:calc(var(--cellw, 6px)*77)}
.grid-stack > .grid-stack-item[gs-w="78"]{width:calc(var(--cellw, 6px)*78)}
.grid-stack > .grid-stack-item[gs-w="79"]{width:calc(var(--cellw, 6px)*79)}
.grid-stack > .grid-stack-item[gs-w="80"]{width:calc(var(--cellw, 6px)*80)}
.grid-stack > .grid-stack-item[gs-w="81"]{width:calc(var(--cellw, 6px)*81)}
.grid-stack > .grid-stack-item[gs-w="82"]{width:calc(var(--cellw, 6px)*82)}
.grid-stack > .grid-stack-item[gs-w="83"]{width:calc(var(--cellw, 6px)*83)}
.grid-stack > .grid-stack-item[gs-w="84"]{width:calc(var(--cellw, 6px)*84)}
.grid-stack > .grid-stack-item[gs-w="85"]{width:calc(var(--cellw, 6px)*85)}
.grid-stack > .grid-stack-item[gs-w="86"]{width:calc(var(--cellw, 6px)*86)}
.grid-stack > .grid-stack-item[gs-w="87"]{width:calc(var(--cellw, 6px)*87)}
.grid-stack > .grid-stack-item[gs-w="88"]{width:calc(var(--cellw, 6px)*88)}
.grid-stack > .grid-stack-item[gs-w="89"]{width:calc(var(--cellw, 6px)*89)}
.grid-stack > .grid-stack-item[gs-w="90"]{width:calc(var(--cellw, 6px)*90)}
.grid-stack > .grid-stack-item[gs-w="91"]{width:calc(var(--cellw, 6px)*91)}
.grid-stack > .grid-stack-item[gs-w="92"]{width:calc(var(--cellw, 6px)*92)}
.grid-stack > .grid-stack-item[gs-w="93"]{width:calc(var(--cellw, 6px)*93)}
.grid-stack > .grid-stack-item[gs-w="94"]{width:calc(var(--cellw, 6px)*94)}
.grid-stack > .grid-stack-item[gs-w="95"]{width:calc(var(--cellw, 6px)*95)}
.grid-stack > .grid-stack-item[gs-w="96"]{width:calc(var(--cellw, 6px)*96)}
.grid-stack > .grid-stack-item[gs-w="97"]{width:calc(var(--cellw, 6px)*97)}
.grid-stack > .grid-stack-item[gs-w="98"]{width:calc(var(--cellw, 6px)*98)}
.grid-stack > .grid-stack-item[gs-w="99"]{width:calc(var(--cellw, 6px)*99)}
.grid-stack > .grid-stack-item[gs-w="100"]{width:calc(var(--cellw, 6px)*100)}
.grid-stack > .grid-stack-item[gs-w="101"]{width:calc(var(--cellw, 6px)*101)}
.grid-stack > .grid-stack-item[gs-w="102"]{width:calc(var(--cellw, 6px)*102)}
.grid-stack > .grid-stack-item[gs-w="103"]{width:calc(var(--cellw, 6px)*103)}
.grid-stack > .grid-stack-item[gs-w="104"]{width:calc(var(--cellw, 6px)*104)}
.grid-stack > .grid-stack-item[gs-w="105"]{width:calc(var(--cellw, 6px)*105)}
.grid-stack > .grid-stack-item[gs-w="106"]{width:calc(var(--cellw, 6px)*106)}
.grid-stack > .grid-stack-item[gs-w="107"]{width:calc(var(--cellw, 6px)*107)}
.grid-stack > .grid-stack-item[gs-w="108"]{width:calc(var(--cellw, 6px)*108)}
.grid-stack > .grid-stack-item[gs-w="109"]{width:calc(var(--cellw, 6px)*109)}
.grid-stack > .grid-stack-item[gs-w="110"]{width:calc(var(--cellw, 6px)*110)}
.grid-stack > .grid-stack-item[gs-w="111"]{width:calc(var(--cellw, 6px)*111)}
.grid-stack > .grid-stack-item[gs-w="112"]{width:calc(var(--cellw, 6px)*112)}
.grid-stack > .grid-stack-item[gs-w="113"]{width:calc(var(--cellw, 6px)*113)}
.grid-stack > .grid-stack-item[gs-w="114"]{width:calc(var(--cellw, 6px)*114)}
.grid-stack > .grid-stack-item[gs-w="115"]{width:calc(var(--cellw, 6px)*115)}
.grid-stack > .grid-stack-item[gs-w="116"]{width:calc(var(--cellw, 6px)*116)}
.grid-stack > .grid-stack-item[gs-w="117"]{width:calc(var(--cellw, 6px)*117)}
.grid-stack > .grid-stack-item[gs-w="118"]{width:calc(var(--cellw, 6px)*118)}
.grid-stack > .grid-stack-item[gs-w="119"]{width:calc(var(--cellw, 6px)*119)}
.grid-stack > .grid-stack-item[gs-w="120"]{width:calc(var(--cellw, 6px)*120)}
.grid-stack > .grid-stack-item[gs-w="121"]{width:calc(var(--cellw, 6px)*121)}
.grid-stack > .grid-stack-item[gs-w="122"]{width:calc(var(--cellw, 6px)*122)}
.grid-stack > .grid-stack-item[gs-w="123"]{width:calc(var(--cellw, 6px)*123)}
.grid-stack > .grid-stack-item[gs-w="124"]{width:calc(var(--cellw, 6px)*124)}
.grid-stack > .grid-stack-item[gs-w="125"]{width:calc(var(--cellw, 6px)*125)}
.grid-stack > .grid-stack-item[gs-w="126"]{width:calc(var(--cellw, 6px)*126)}
.grid-stack > .grid-stack-item[gs-w="127"]{width:calc(var(--cellw, 6px)*127)}
.grid-stack > .grid-stack-item[gs-w="128"]{width:calc(var(--cellw, 6px)*128)}
.grid-stack > .grid-stack-item[gs-w="129"]{width:calc(var(--cellw, 6px)*129)}
.grid-stack > .grid-stack-item[gs-w="130"]{width:calc(var(--cellw, 6px)*130)}
.grid-stack > .grid-stack-item[gs-w="131"]{width:calc(var(--cellw, 6px)*131)}
.grid-stack > .grid-stack-item[gs-w="132"]{width:calc(var(--cellw, 6px)*132)}
.grid-stack > .grid-stack-item[gs-w="133"]{width:calc(var(--cellw, 6px)*133)}
.grid-stack > .grid-stack-item[gs-w="134"]{width:calc(var(--cellw, 6px)*134)}
.grid-stack > .grid-stack-item[gs-w="135"]{width:calc(var(--cellw, 6px)*135)}
.grid-stack > .grid-stack-item[gs-w="136"]{width:calc(var(--cellw, 6px)*136)}
.grid-stack > .grid-stack-item[gs-w="137"]{width:calc(var(--cellw, 6px)*137)}
.grid-stack > .grid-stack-item[gs-w="138"]{width:calc(var(--cellw, 6px)*138)}
.grid-stack > .grid-stack-item[gs-w="139"]{width:calc(var(--cellw, 6px)*139)}
.grid-stack > .grid-stack-item[gs-w="140"]{width:calc(var(--cellw, 6px)*140)}
.grid-stack > .grid-stack-item[gs-w="141"]{width:calc(var(--cellw, 6px)*141)}
.grid-stack > .grid-stack-item[gs-w="142"]{width:calc(var(--cellw, 6px)*142)}
.grid-stack > .grid-stack-item[gs-w="143"]{width:calc(var(--cellw, 6px)*143)}
.grid-stack > .grid-stack-item[gs-w="144"]{width:calc(var(--cellw, 6px)*144)}
.grid-stack > .grid-stack-item[gs-w="145"]{width:calc(var(--cellw, 6px)*145)}
.grid-stack > .grid-stack-item[gs-w="146"]{width:calc(var(--cellw, 6px)*146)}
.grid-stack > .grid-stack-item[gs-w="147"]{width:calc(var(--cellw, 6px)*147)}
.grid-stack > .grid-stack-item[gs-w="148"]{width:calc(var(--cellw, 6px)*148)}
.grid-stack > .grid-stack-item[gs-w="149"]{width:calc(var(--cellw, 6px)*149)}
.grid-stack > .grid-stack-item[gs-w="150"]{width:calc(var(--cellw, 6px)*150)}
.grid-stack > .grid-stack-item[gs-w="151"]{width:calc(var(--cellw, 6px)*151)}
.grid-stack > .grid-stack-item[gs-w="152"]{width:calc(var(--cellw, 6px)*152)}
.grid-stack > .grid-stack-item[gs-w="153"]{width:calc(var(--cellw, 6px)*153)}
.grid-stack > .grid-stack-item[gs-w="154"]{width:calc(var(--cellw, 6px)*154)}
.grid-stack > .grid-stack-item[gs-w="155"]{width:calc(var(--cellw, 6px)*155)}
.grid-stack > .grid-stack-item[gs-w="156"]{width:calc(var(--cellw, 6px)*156)}
.grid-stack > .grid-stack-item[gs-w="157"]{width:calc(var(--cellw, 6px)*157)}
.grid-stack > .grid-stack-item[gs-w="158"]{width:calc(var(--cellw, 6px)*158)}
.grid-stack > .grid-stack-item[gs-w="159"]{width:calc(var(--cellw, 6px)*159)}
.grid-stack > .grid-stack-item[gs-w="160"]{width:calc(var(--cellw, 6px)*160)}
.grid-stack > .grid-stack-item[gs-w="161"]{width:calc(var(--cellw, 6px)*161)}
.grid-stack > .grid-stack-item[gs-w="162"]{width:calc(var(--cellw, 6px)*162)}
.grid-stack > .grid-stack-item[gs-w="163"]{width:calc(var(--cellw, 6px)*163)}
.grid-stack > .grid-stack-item[gs-w="164"]{width:calc(var(--cellw, 6px)*164)}
.grid-stack > .grid-stack-item[gs-w="165"]{width:calc(var(--cellw, 6px)*165)}
.grid-stack > .grid-stack-item[gs-w="166"]{width:calc(var(--cellw, 6px)*166)}
.grid-stack > .grid-stack-item[gs-w="167"]{width:calc(var(--cellw, 6px)*167)}
.grid-stack > .grid-stack-item[gs-w="168"]{width:calc(var(--cellw, 6px)*168)}
.grid-stack > .grid-stack-item[gs-w="169"]{width:calc(var(--cellw, 6px)*169)}
.grid-stack > .grid-stack-item[gs-w="170"]{width:calc(var(--cellw, 6px)*170)}
.grid-stack > .grid-stack-item[gs-w="171"]{width:calc(var(--cellw, 6px)*171)}
.grid-stack > .grid-stack-item[gs-w="172"]{width:calc(var(--cellw, 6px)*172)}
.grid-stack > .grid-stack-item[gs-w="173"]{width:calc(var(--cellw, 6px)*173)}
.grid-stack > .grid-stack-item[gs-w="174"]{width:calc(var(--cellw, 6px)*174)}
.grid-stack > .grid-stack-item[gs-w="175"]{width:calc(var(--cellw, 6px)*175)}
.grid-stack > .grid-stack-item[gs-w="176"]{width:calc(var(--cellw, 6px)*176)}
.grid-stack > .grid-stack-item[gs-w="177"]{width:calc(var(--cellw, 6px)*177)}
.grid-stack > .grid-stack-item[gs-w="178"]{width:calc(var(--cellw, 6px)*178)}
.grid-stack > .grid-stack-item[gs-w="179"]{width:calc(var(--cellw, 6px)*179)}
.grid-stack > .grid-stack-item[gs-w="180"]{width:calc(var(--cellw, 6px)*180)}
.grid-stack > .grid-stack-item[gs-w="181"]{width:calc(var(--cellw, 6px)*181)}
.grid-stack > .grid-stack-item[gs-w="182"]{width:calc(var(--cellw, 6px)*182)}
.grid-stack > .grid-stack-item[gs-w="183"]{width:calc(var(--cellw, 6px)*183)}
.grid-stack > .grid-stack-item[gs-w="184"]{width:calc(var(--cellw, 6px)*184)}
.grid-stack > .grid-stack-item[gs-w="185"]{width:calc(var(--cellw, 6px)*185)}
.grid-stack > .grid-stack-item[gs-w="186"]{width:calc(var(--cellw, 6px)*186)}
.grid-stack > .grid-stack-item[gs-w="187"]{width:calc(var(--cellw, 6px)*187)}
.grid-stack > .grid-stack-item[gs-w="188"]{width:calc(var(--cellw, 6px)*188)}
.grid-stack > .grid-stack-item[gs-w="189"]{width:calc(var(--cellw, 6px)*189)}
.grid-stack > .grid-stack-item[gs-w="190"]{width:calc(var(--cellw, 6px)*190)}
.grid-stack > .grid-stack-item[gs-w="191"]{width:calc(var(--cellw, 6px)*191)}
.grid-stack > .grid-stack-item[gs-w="192"]{width:calc(var(--cellw, 6px)*192)}
.grid-stack > .grid-stack-item[gs-w="193"]{width:calc(var(--cellw, 6px)*193)}
.grid-stack > .grid-stack-item[gs-w="194"]{width:calc(var(--cellw, 6px)*194)}
.grid-stack > .grid-stack-item[gs-w="195"]{width:calc(var(--cellw, 6px)*195)}
.grid-stack > .grid-stack-item[gs-w="196"]{width:calc(var(--cellw, 6px)*196)}
.grid-stack > .grid-stack-item[gs-w="197"]{width:calc(var(--cellw, 6px)*197)}
.grid-stack > .grid-stack-item[gs-w="198"]{width:calc(var(--cellw, 6px)*198)}
.grid-stack > .grid-stack-item[gs-w="199"]{width:calc(var(--cellw, 6px)*199)}
.grid-stack > .grid-stack-item[gs-w="200"]{width:calc(var(--cellw, 6px)*200)}
.grid-stack > .grid-stack-item[gs-w="201"]{width:calc(var(--cellw, 6px)*201)}
.grid-stack > .grid-stack-item[gs-w="202"]{width:calc(var(--cellw, 6px)*202)}
.grid-stack > .grid-stack-item[gs-w="203"]{width:calc(var(--cellw, 6px)*203)}
.grid-stack > .grid-stack-item[gs-w="204"]{width:calc(var(--cellw, 6px)*204)}
.grid-stack > .grid-stack-item[gs-w="205"]{width:calc(var(--cellw, 6px)*205)}
.grid-stack > .grid-stack-item[gs-w="206"]{width:calc(var(--cellw, 6px)*206)}
.grid-stack > .grid-stack-item[gs-w="207"]{width:calc(var(--cellw, 6px)*207)}
.grid-stack > .grid-stack-item[gs-w="208"]{width:calc(var(--cellw, 6px)*208)}
.grid-stack > .grid-stack-item[gs-w="209"]{width:calc(var(--cellw, 6px)*209)}
.grid-stack > .grid-stack-item[gs-w="210"]{width:calc(var(--cellw, 6px)*210)}
.grid-stack > .grid-stack-item[gs-w="211"]{width:calc(var(--cellw, 6px)*211)}
.grid-stack > .grid-stack-item[gs-w="212"]{width:calc(var(--cellw, 6px)*212)}
.grid-stack > .grid-stack-item[gs-w="213"]{width:calc(var(--cellw, 6px)*213)}
.grid-stack > .grid-stack-item[gs-w="214"]{width:calc(var(--cellw, 6px)*214)}
.grid-stack > .grid-stack-item[gs-w="215"]{width:calc(var(--cellw, 6px)*215)}
.grid-stack > .grid-stack-item[gs-w="216"]{width:calc(var(--cellw, 6px)*216)}
.grid-stack > .grid-stack-item[gs-w="217"]{width:calc(var(--cellw, 6px)*217)}
.grid-stack > .grid-stack-item[gs-w="218"]{width:calc(var(--cellw, 6px)*218)}
.grid-stack > .grid-stack-item[gs-w="219"]{width:calc(var(--cellw, 6px)*219)}
.grid-stack > .grid-stack-item[gs-w="220"]{width:calc(var(--cellw, 6px)*220)}
.grid-stack > .grid-stack-item[gs-w="221"]{width:calc(var(--cellw, 6px)*221)}
.grid-stack > .grid-stack-item[gs-w="222"]{width:calc(var(--cellw, 6px)*222)}
.grid-stack > .grid-stack-item[gs-w="223"]{width:calc(var(--cellw, 6px)*223)}
.grid-stack > .grid-stack-item[gs-w="224"]{width:calc(var(--cellw, 6px)*224)}
.grid-stack > .grid-stack-item[gs-w="225"]{width:calc(var(--cellw, 6px)*225)}
.grid-stack > .grid-stack-item[gs-w="226"]{width:calc(var(--cellw, 6px)*226)}
.grid-stack > .grid-stack-item[gs-w="227"]{width:calc(var(--cellw, 6px)*227)}
.grid-stack > .grid-stack-item[gs-w="228"]{width:calc(var(--cellw, 6px)*228)}
.grid-stack > .grid-stack-item[gs-w="229"]{width:calc(var(--cellw, 6px)*229)}
.grid-stack > .grid-stack-item[gs-w="230"]{width:calc(var(--cellw, 6px)*230)}
.grid-stack > .grid-stack-item[gs-w="231"]{width:calc(var(--cellw, 6px)*231)}
.grid-stack > .grid-stack-item[gs-w="232"]{width:calc(var(--cellw, 6px)*232)}
.grid-stack > .grid-stack-item[gs-w="233"]{width:calc(var(--cellw, 6px)*233)}
.grid-stack > .grid-stack-item[gs-w="234"]{width:calc(var(--cellw, 6px)*234)}
.grid-stack > .grid-stack-item[gs-w="235"]{width:calc(var(--cellw, 6px)*235)}
.grid-stack > .grid-stack-item[gs-w="236"]{width:calc(var(--cellw, 6px)*236)}
.grid-stack > .grid-stack-item[gs-w="237"]{width:calc(var(--cellw, 6px)*237)}
.grid-stack > .grid-stack-item[gs-w="238"]{width:calc(var(--cellw, 6px)*238)}
.grid-stack > .grid-stack-item[gs-w="239"]{width:calc(var(--cellw, 6px)*239)}
.grid-stack > .grid-stack-item[gs-w="240"]{width:calc(var(--cellw, 6px)*240)}
.grid-stack > .grid-stack-item[gs-w="241"]{width:calc(var(--cellw, 6px)*241)}
.grid-stack > .grid-stack-item[gs-w="242"]{width:calc(var(--cellw, 6px)*242)}
.grid-stack > .grid-stack-item[gs-w="243"]{width:calc(var(--cellw, 6px)*243)}
.grid-stack > .grid-stack-item[gs-w="244"]{width:calc(var(--cellw, 6px)*244)}
.grid-stack > .grid-stack-item[gs-w="245"]{width:calc(var(--cellw, 6px)*245)}
.grid-stack > .grid-stack-item[gs-w="246"]{width:calc(var(--cellw, 6px)*246)}
.grid-stack > .grid-stack-item[gs-w="247"]{width:calc(var(--cellw, 6px)*247)}
.grid-stack > .grid-stack-item[gs-w="248"]{width:calc(var(--cellw, 6px)*248)}
.grid-stack > .grid-stack-item[gs-w="249"]{width:calc(var(--cellw, 6px)*249)}
.grid-stack > .grid-stack-item[gs-w="250"]{width:calc(var(--cellw, 6px)*250)}
.grid-stack > .grid-stack-item[gs-w="251"]{width:calc(var(--cellw, 6px)*251)}
.grid-stack > .grid-stack-item[gs-w="252"]{width:calc(var(--cellw, 6px)*252)}
.grid-stack > .grid-stack-item[gs-w="253"]{width:calc(var(--cellw, 6px)*253)}
.grid-stack > .grid-stack-item[gs-w="254"]{width:calc(var(--cellw, 6px)*254)}
.grid-stack > .grid-stack-item[gs-w="255"]{width:calc(var(--cellw, 6px)*255)}
.grid-stack > .grid-stack-item[gs-w="256"]{width:calc(var(--cellw, 6px)*256)}
.grid-stack > .grid-stack-item[gs-w="257"]{width:calc(var(--cellw, 6px)*257)}
.grid-stack > .grid-stack-item[gs-w="258"]{width:calc(var(--cellw, 6px)*258)}
.grid-stack > .grid-stack-item[gs-w="259"]{width:calc(var(--cellw, 6px)*259)}
.grid-stack > .grid-stack-item[gs-w="260"]{width:calc(var(--cellw, 6px)*260)}
.grid-stack > .grid-stack-item[gs-w="261"]{width:calc(var(--cellw, 6px)*261)}
.grid-stack > .grid-stack-item[gs-w="262"]{width:calc(var(--cellw, 6px)*262)}
.grid-stack > .grid-stack-item[gs-w="263"]{width:calc(var(--cellw, 6px)*263)}
.grid-stack > .grid-stack-item[gs-w="264"]{width:calc(var(--cellw, 6px)*264)}
.grid-stack > .grid-stack-item[gs-w="265"]{width:calc(var(--cellw, 6px)*265)}
.grid-stack > .grid-stack-item[gs-w="266"]{width:calc(var(--cellw, 6px)*266)}
.grid-stack > .grid-stack-item[gs-w="267"]{width:calc(var(--cellw, 6px)*267)}
.grid-stack > .grid-stack-item[gs-w="268"]{width:calc(var(--cellw, 6px)*268)}
.grid-stack > .grid-stack-item[gs-w="269"]{width:calc(var(--cellw, 6px)*269)}
.grid-stack > .grid-stack-item[gs-w="270"]{width:calc(var(--cellw, 6px)*270)}
.grid-stack > .grid-stack-item[gs-w="271"]{width:calc(var(--cellw, 6px)*271)}
.grid-stack > .grid-stack-item[gs-w="272"]{width:calc(var(--cellw, 6px)*272)}
.grid-stack > .grid-stack-item[gs-w="273"]{width:calc(var(--cellw, 6px)*273)}
.grid-stack > .grid-stack-item[gs-w="274"]{width:calc(var(--cellw, 6px)*274)}
.grid-stack > .grid-stack-item[gs-w="275"]{width:calc(var(--cellw, 6px)*275)}
.grid-stack > .grid-stack-item[gs-w="276"]{width:calc(var(--cellw, 6px)*276)}
.grid-stack > .grid-stack-item[gs-w="277"]{width:calc(var(--cellw, 6px)*277)}
.grid-stack > .grid-stack-item[gs-w="278"]{width:calc(var(--cellw, 6px)*278)}
.grid-stack > .grid-stack-item[gs-w="279"]{width:calc(var(--cellw, 6px)*279)}
.grid-stack > .grid-stack-item[gs-w="280"]{width:calc(var(--cellw, 6px)*280)}
.grid-stack > .grid-stack-item[gs-w="281"]{width:calc(var(--cellw, 6px)*281)}
.grid-stack > .grid-stack-item[gs-w="282"]{width:calc(var(--cellw, 6px)*282)}
.grid-stack > .grid-stack-item[gs-w="283"]{width:calc(var(--cellw, 6px)*283)}
.grid-stack > .grid-stack-item[gs-w="284"]{width:calc(var(--cellw, 6px)*284)}
.grid-stack > .grid-stack-item[gs-w="285"]{width:calc(var(--cellw, 6px)*285)}
.grid-stack > .grid-stack-item[gs-w="286"]{width:calc(var(--cellw, 6px)*286)}
.grid-stack > .grid-stack-item[gs-w="287"]{width:calc(var(--cellw, 6px)*287)}
.grid-stack > .grid-stack-item[gs-w="288"]{width:calc(var(--cellw, 6px)*288)}
.grid-stack > .grid-stack-item[gs-w="289"]{width:calc(var(--cellw, 6px)*289)}
.grid-stack > .grid-stack-item[gs-w="290"]{width:calc(var(--cellw, 6px)*290)}
.grid-stack > .grid-stack-item[gs-w="291"]{width:calc(var(--cellw, 6px)*291)}
.grid-stack > .grid-stack-item[gs-w="292"]{width:calc(var(--cellw, 6px)*292)}
.grid-stack > .grid-stack-item[gs-w="293"]{width:calc(var(--cellw, 6px)*293)}
.grid-stack > .grid-stack-item[gs-w="294"]{width:calc(var(--cellw, 6px)*294)}
.grid-stack > .grid-stack-item[gs-w="295"]{width:calc(var(--cellw, 6px)*295)}
.grid-stack > .grid-stack-item[gs-w="296"]{width:calc(var(--cellw, 6px)*296)}
.grid-stack > .grid-stack-item[gs-w="297"]{width:calc(var(--cellw, 6px)*297)}
.grid-stack > .grid-stack-item[gs-w="298"]{width:calc(var(--cellw, 6px)*298)}
.grid-stack > .grid-stack-item[gs-w="299"]{width:calc(var(--cellw, 6px)*299)}
.grid-stack > .grid-stack-item[gs-w="300"]{width:calc(var(--cellw, 6px)*300)}
.grid-stack > .grid-stack-item[gs-w="301"]{width:calc(var(--cellw, 6px)*301)}
.grid-stack > .grid-stack-item[gs-w="302"]{width:calc(var(--cellw, 6px)*302)}
.grid-stack > .grid-stack-item[gs-w="303"]{width:calc(var(--cellw, 6px)*303)}
.grid-stack > .grid-stack-item[gs-w="304"]{width:calc(var(--cellw, 6px)*304)}
.grid-stack > .grid-stack-item[gs-w="305"]{width:calc(var(--cellw, 6px)*305)}
.grid-stack > .grid-stack-item[gs-w="306"]{width:calc(var(--cellw, 6px)*306)}
.grid-stack > .grid-stack-item[gs-w="307"]{width:calc(var(--cellw, 6px)*307)}
.grid-stack > .grid-stack-item[gs-w="308"]{width:calc(var(--cellw, 6px)*308)}
.grid-stack > .grid-stack-item[gs-w="309"]{width:calc(var(--cellw, 6px)*309)}
.grid-stack > .grid-stack-item[gs-w="310"]{width:calc(var(--cellw, 6px)*310)}
.grid-stack > .grid-stack-item[gs-w="311"]{width:calc(var(--cellw, 6px)*311)}
.grid-stack > .grid-stack-item[gs-w="312"]{width:calc(var(--cellw, 6px)*312)}
.grid-stack > .grid-stack-item[gs-w="313"]{width:calc(var(--cellw, 6px)*313)}
.grid-stack > .grid-stack-item[gs-w="314"]{width:calc(var(--cellw, 6px)*314)}
.grid-stack > .grid-stack-item[gs-w="315"]{width:calc(var(--cellw, 6px)*315)}
.grid-stack > .grid-stack-item[gs-w="316"]{width:calc(var(--cellw, 6px)*316)}
.grid-stack > .grid-stack-item[gs-w="317"]{width:calc(var(--cellw, 6px)*317)}
.grid-stack > .grid-stack-item[gs-w="318"]{width:calc(var(--cellw, 6px)*318)}
.grid-stack > .grid-stack-item[gs-w="319"]{width:calc(var(--cellw, 6px)*319)}
.grid-stack > .grid-stack-item[gs-w="320"]{width:calc(var(--cellw, 6px)*320)}
.grid-stack > .grid-stack-item[gs-w="321"]{width:calc(var(--cellw, 6px)*321)}
.grid-stack > .grid-stack-item[gs-w="322"]{width:calc(var(--cellw, 6px)*322)}
.grid-stack > .grid-stack-item[gs-w="323"]{width:calc(var(--cellw, 6px)*323)}
.grid-stack > .grid-stack-item[gs-w="324"]{width:calc(var(--cellw, 6px)*324)}
.grid-stack > .grid-stack-item[gs-w="325"]{width:calc(var(--cellw, 6px)*325)}
.grid-stack > .grid-stack-item[gs-w="326"]{width:calc(var(--cellw, 6px)*326)}
.grid-stack > .grid-stack-item[gs-w="327"]{width:calc(var(--cellw, 6px)*327)}
.grid-stack > .grid-stack-item[gs-w="328"]{width:calc(var(--cellw, 6px)*328)}
.grid-stack > .grid-stack-item[gs-w="329"]{width:calc(var(--cellw, 6px)*329)}
.grid-stack > .grid-stack-item[gs-w="330"]{width:calc(var(--cellw, 6px)*330)}
.grid-stack > .grid-stack-item[gs-w="331"]{width:calc(var(--cellw, 6px)*331)}
.grid-stack > .grid-stack-item[gs-w="332"]{width:calc(var(--cellw, 6px)*332)}
.grid-stack > .grid-stack-item[gs-w="333"]{width:calc(var(--cellw, 6px)*333)}
.grid-stack > .grid-stack-item[gs-w="334"]{width:calc(var(--cellw, 6px)*334)}
.grid-stack > .grid-stack-item[gs-w="335"]{width:calc(var(--cellw, 6px)*335)}
.grid-stack > .grid-stack-item[gs-w="336"]{width:calc(var(--cellw, 6px)*336)}
.grid-stack > .grid-stack-item[gs-w="337"]{width:calc(var(--cellw, 6px)*337)}
.grid-stack > .grid-stack-item[gs-w="338"]{width:calc(var(--cellw, 6px)*338)}
.grid-stack > .grid-stack-item[gs-w="339"]{width:calc(var(--cellw, 6px)*339)}
.grid-stack > .grid-stack-item[gs-w="340"]{width:calc(var(--cellw, 6px)*340)}
.grid-stack > .grid-stack-item[gs-w="341"]{width:calc(var(--cellw, 6px)*341)}
.grid-stack > .grid-stack-item[gs-w="342"]{width:calc(var(--cellw, 6px)*342)}
.grid-stack > .grid-stack-item[gs-w="343"]{width:calc(var(--cellw, 6px)*343)}
.grid-stack > .grid-stack-item[gs-w="344"]{width:calc(var(--cellw, 6px)*344)}
.grid-stack > .grid-stack-item[gs-w="345"]{width:calc(var(--cellw, 6px)*345)}
.grid-stack > .grid-stack-item[gs-w="346"]{width:calc(var(--cellw, 6px)*346)}
.grid-stack > .grid-stack-item[gs-w="347"]{width:calc(var(--cellw, 6px)*347)}
.grid-stack > .grid-stack-item[gs-w="348"]{width:calc(var(--cellw, 6px)*348)}
.grid-stack > .grid-stack-item[gs-w="349"]{width:calc(var(--cellw, 6px)*349)}
.grid-stack > .grid-stack-item[gs-w="350"]{width:calc(var(--cellw, 6px)*350)}
.grid-stack > .grid-stack-item[gs-w="351"]{width:calc(var(--cellw, 6px)*351)}
.grid-stack > .grid-stack-item[gs-w="352"]{width:calc(var(--cellw, 6px)*352)}
.grid-stack > .grid-stack-item[gs-w="353"]{width:calc(var(--cellw, 6px)*353)}
.grid-stack > .grid-stack-item[gs-w="354"]{width:calc(var(--cellw, 6px)*354)}
.grid-stack > .grid-stack-item[gs-w="355"]{width:calc(var(--cellw, 6px)*355)}
.grid-stack > .grid-stack-item[gs-w="356"]{width:calc(var(--cellw, 6px)*356)}
.grid-stack > .grid-stack-item[gs-w="357"]{width:calc(var(--cellw, 6px)*357)}
.grid-stack > .grid-stack-item[gs-w="358"]{width:calc(var(--cellw, 6px)*358)}
.grid-stack > .grid-stack-item[gs-w="359"]{width:calc(var(--cellw, 6px)*359)}
.grid-stack > .grid-stack-item[gs-w="360"]{width:calc(var(--cellw, 6px)*360)}
.grid-stack > .grid-stack-item[gs-w="361"]{width:calc(var(--cellw, 6px)*361)}
.grid-stack > .grid-stack-item[gs-w="362"]{width:calc(var(--cellw, 6px)*362)}
.grid-stack > .grid-stack-item[gs-w="363"]{width:calc(var(--cellw, 6px)*363)}
.grid-stack > .grid-stack-item[gs-w="364"]{width:calc(var(--cellw, 6px)*364)}
.grid-stack > .grid-stack-item[gs-w="365"]{width:calc(var(--cellw, 6px)*365)}
.grid-stack > .grid-stack-item[gs-w="366"]{width:calc(var(--cellw, 6px)*366)}
.grid-stack > .grid-stack-item[gs-w="367"]{width:calc(var(--cellw, 6px)*367)}
.grid-stack > .grid-stack-item[gs-w="368"]{width:calc(var(--cellw, 6px)*368)}
.grid-stack > .grid-stack-item[gs-w="369"]{width:calc(var(--cellw, 6px)*369)}
.grid-stack > .grid-stack-item[gs-w="370"]{width:calc(var(--cellw, 6px)*370)}
.grid-stack > .grid-stack-item[gs-w="371"]{width:calc(var(--cellw, 6px)*371)}
.grid-stack > .grid-stack-item[gs-w="372"]{width:calc(var(--cellw, 6px)*372)}
.grid-stack > .grid-stack-item[gs-w="373"]{width:calc(var(--cellw, 6px)*373)}
.grid-stack > .grid-stack-item[gs-w="374"]{width:calc(var(--cellw, 6px)*374)}
.grid-stack > .grid-stack-item[gs-w="375"]{width:calc(var(--cellw, 6px)*375)}
.grid-stack > .grid-stack-item[gs-w="376"]{width:calc(var(--cellw, 6px)*376)}
.grid-stack > .grid-stack-item[gs-w="377"]{width:calc(var(--cellw, 6px)*377)}
.grid-stack > .grid-stack-item[gs-w="378"]{width:calc(var(--cellw, 6px)*378)}
.grid-stack > .grid-stack-item[gs-w="379"]{width:calc(var(--cellw, 6px)*379)}
.grid-stack > .grid-stack-item[gs-w="380"]{width:calc(var(--cellw, 6px)*380)}
.grid-stack > .grid-stack-item[gs-w="381"]{width:calc(var(--cellw, 6px)*381)}
.grid-stack > .grid-stack-item[gs-w="382"]{width:calc(var(--cellw, 6px)*382)}
.grid-stack > .grid-stack-item[gs-w="383"]{width:calc(var(--cellw, 6px)*383)}
.grid-stack > .grid-stack-item[gs-w="384"]{width:calc(var(--cellw, 6px)*384)}
.grid-stack > .grid-stack-item[gs-w="385"]{width:calc(var(--cellw, 6px)*385)}
.grid-stack > .grid-stack-item[gs-w="386"]{width:calc(var(--cellw, 6px)*386)}
.grid-stack > .grid-stack-item[gs-w="387"]{width:calc(var(--cellw, 6px)*387)}
.grid-stack > .grid-stack-item[gs-w="388"]{width:calc(var(--cellw, 6px)*388)}
.grid-stack > .grid-stack-item[gs-w="389"]{width:calc(var(--cellw, 6px)*389)}
.grid-stack > .grid-stack-item[gs-w="390"]{width:calc(var(--cellw, 6px)*390)}
.grid-stack > .grid-stack-item[gs-w="391"]{width:calc(var(--cellw, 6px)*391)}
.grid-stack > .grid-stack-item[gs-w="392"]{width:calc(var(--cellw, 6px)*392)}
.grid-stack > .grid-stack-item[gs-w="393"]{width:calc(var(--cellw, 6px)*393)}
.grid-stack > .grid-stack-item[gs-w="394"]{width:calc(var(--cellw, 6px)*394)}
.grid-stack > .grid-stack-item[gs-w="395"]{width:calc(var(--cellw, 6px)*395)}
.grid-stack > .grid-stack-item[gs-w="396"]{width:calc(var(--cellw, 6px)*396)}
.grid-stack > .grid-stack-item[gs-w="397"]{width:calc(var(--cellw, 6px)*397)}
.grid-stack > .grid-stack-item[gs-w="398"]{width:calc(var(--cellw, 6px)*398)}
.grid-stack > .grid-stack-item[gs-w="399"]{width:calc(var(--cellw, 6px)*399)}
.grid-stack > .grid-stack-item[gs-w="400"]{width:calc(var(--cellw, 6px)*400)}
.grid-stack > .grid-stack-item[gs-x="0"]{left:0}
.grid-stack > .grid-stack-item[gs-x="1"]{left:calc(var(--cellw, 6px)*1)}
.grid-stack > .grid-stack-item[gs-x="2"]{left:calc(var(--cellw, 6px)*2)}
.grid-stack > .grid-stack-item[gs-x="3"]{left:calc(var(--cellw, 6px)*3)}
.grid-stack > .grid-stack-item[gs-x="4"]{left:calc(var(--cellw, 6px)*4)}
.grid-stack > .grid-stack-item[gs-x="5"]{left:calc(var(--cellw, 6px)*5)}
.grid-stack > .grid-stack-item[gs-x="6"]{left:calc(var(--cellw, 6px)*6)}
.grid-stack > .grid-stack-item[gs-x="7"]{left:calc(var(--cellw, 6px)*7)}
.grid-stack > .grid-stack-item[gs-x="8"]{left:calc(var(--cellw, 6px)*8)}
.grid-stack > .grid-stack-item[gs-x="9"]{left:calc(var(--cellw, 6px)*9)}
.grid-stack > .grid-stack-item[gs-x="10"]{left:calc(var(--cellw, 6px)*10)}
.grid-stack > .grid-stack-item[gs-x="11"]{left:calc(var(--cellw, 6px)*11)}
.grid-stack > .grid-stack-item[gs-x="12"]{left:calc(var(--cellw, 6px)*12)}
.grid-stack > .grid-stack-item[gs-x="13"]{left:calc(var(--cellw, 6px)*13)}
.grid-stack > .grid-stack-item[gs-x="14"]{left:calc(var(--cellw, 6px)*14)}
.grid-stack > .grid-stack-item[gs-x="15"]{left:calc(var(--cellw, 6px)*15)}
.grid-stack > .grid-stack-item[gs-x="16"]{left:calc(var(--cellw, 6px)*16)}
.grid-stack > .grid-stack-item[gs-x="17"]{left:calc(var(--cellw, 6px)*17)}
.grid-stack > .grid-stack-item[gs-x="18"]{left:calc(var(--cellw, 6px)*18)}
.grid-stack > .grid-stack-item[gs-x="19"]{left:calc(var(--cellw, 6px)*19)}
.grid-stack > .grid-stack-item[gs-x="20"]{left:calc(var(--cellw, 6px)*20)}
.grid-stack > .grid-stack-item[gs-x="21"]{left:calc(var(--cellw, 6px)*21)}
.grid-stack > .grid-stack-item[gs-x="22"]{left:calc(var(--cellw, 6px)*22)}
.grid-stack > .grid-stack-item[gs-x="23"]{left:calc(var(--cellw, 6px)*23)}
.grid-stack > .grid-stack-item[gs-x="24"]{left:calc(var(--cellw, 6px)*24)}
.grid-stack > .grid-stack-item[gs-x="25"]{left:calc(var(--cellw, 6px)*25)}
.grid-stack > .grid-stack-item[gs-x="26"]{left:calc(var(--cellw, 6px)*26)}
.grid-stack > .grid-stack-item[gs-x="27"]{left:calc(var(--cellw, 6px)*27)}
.grid-stack > .grid-stack-item[gs-x="28"]{left:calc(var(--cellw, 6px)*28)}
.grid-stack > .grid-stack-item[gs-x="29"]{left:calc(var(--cellw, 6px)*29)}
.grid-stack > .grid-stack-item[gs-x="30"]{left:calc(var(--cellw, 6px)*30)}
.grid-stack > .grid-stack-item[gs-x="31"]{left:calc(var(--cellw, 6px)*31)}
.grid-stack > .grid-stack-item[gs-x="32"]{left:calc(var(--cellw, 6px)*32)}
.grid-stack > .grid-stack-item[gs-x="33"]{left:calc(var(--cellw, 6px)*33)}
.grid-stack > .grid-stack-item[gs-x="34"]{left:calc(var(--cellw, 6px)*34)}
.grid-stack > .grid-stack-item[gs-x="35"]{left:calc(var(--cellw, 6px)*35)}
.grid-stack > .grid-stack-item[gs-x="36"]{left:calc(var(--cellw, 6px)*36)}
.grid-stack > .grid-stack-item[gs-x="37"]{left:calc(var(--cellw, 6px)*37)}
.grid-stack > .grid-stack-item[gs-x="38"]{left:calc(var(--cellw, 6px)*38)}
.grid-stack > .grid-stack-item[gs-x="39"]{left:calc(var(--cellw, 6px)*39)}
.grid-stack > .grid-stack-item[gs-x="40"]{left:calc(var(--cellw, 6px)*40)}
.grid-stack > .grid-stack-item[gs-x="41"]{left:calc(var(--cellw, 6px)*41)}
.grid-stack > .grid-stack-item[gs-x="42"]{left:calc(var(--cellw, 6px)*42)}
.grid-stack > .grid-stack-item[gs-x="43"]{left:calc(var(--cellw, 6px)*43)}
.grid-stack > .grid-stack-item[gs-x="44"]{left:calc(var(--cellw, 6px)*44)}
.grid-stack > .grid-stack-item[gs-x="45"]{left:calc(var(--cellw, 6px)*45)}
.grid-stack > .grid-stack-item[gs-x="46"]{left:calc(var(--cellw, 6px)*46)}
.grid-stack > .grid-stack-item[gs-x="47"]{left:calc(var(--cellw, 6px)*47)}
.grid-stack > .grid-stack-item[gs-x="48"]{left:calc(var(--cellw, 6px)*48)}
.grid-stack > .grid-stack-item[gs-x="49"]{left:calc(var(--cellw, 6px)*49)}
.grid-stack > .grid-stack-item[gs-x="50"]{left:calc(var(--cellw, 6px)*50)}
.grid-stack > .grid-stack-item[gs-x="51"]{left:calc(var(--cellw, 6px)*51)}
.grid-stack > .grid-stack-item[gs-x="52"]{left:calc(var(--cellw, 6px)*52)}
.grid-stack > .grid-stack-item[gs-x="53"]{left:calc(var(--cellw, 6px)*53)}
.grid-stack > .grid-stack-item[gs-x="54"]{left:calc(var(--cellw, 6px)*54)}
.grid-stack > .grid-stack-item[gs-x="55"]{left:calc(var(--cellw, 6px)*55)}
.grid-stack > .grid-stack-item[gs-x="56"]{left:calc(var(--cellw, 6px)*56)}
.grid-stack > .grid-stack-item[gs-x="57"]{left:calc(var(--cellw, 6px)*57)}
.grid-stack > .grid-stack-item[gs-x="58"]{left:calc(var(--cellw, 6px)*58)}
.grid-stack > .grid-stack-item[gs-x="59"]{left:calc(var(--cellw, 6px)*59)}
.grid-stack > .grid-stack-item[gs-x="60"]{left:calc(var(--cellw, 6px)*60)}
.grid-stack > .grid-stack-item[gs-x="61"]{left:calc(var(--cellw, 6px)*61)}
.grid-stack > .grid-stack-item[gs-x="62"]{left:calc(var(--cellw, 6px)*62)}
.grid-stack > .grid-stack-item[gs-x="63"]{left:calc(var(--cellw, 6px)*63)}
.grid-stack > .grid-stack-item[gs-x="64"]{left:calc(var(--cellw, 6px)*64)}
.grid-stack > .grid-stack-item[gs-x="65"]{left:calc(var(--cellw, 6px)*65)}
.grid-stack > .grid-stack-item[gs-x="66"]{left:calc(var(--cellw, 6px)*66)}
.grid-stack > .grid-stack-item[gs-x="67"]{left:calc(var(--cellw, 6px)*67)}
.grid-stack > .grid-stack-item[gs-x="68"]{left:calc(var(--cellw, 6px)*68)}
.grid-stack > .grid-stack-item[gs-x="69"]{left:calc(var(--cellw, 6px)*69)}
.grid-stack > .grid-stack-item[gs-x="70"]{left:calc(var(--cellw, 6px)*70)}
.grid-stack > .grid-stack-item[gs-x="71"]{left:calc(var(--cellw, 6px)*71)}
.grid-stack > .grid-stack-item[gs-x="72"]{left:calc(var(--cellw, 6px)*72)}
.grid-stack > .grid-stack-item[gs-x="73"]{left:calc(var(--cellw, 6px)*73)}
.grid-stack > .grid-stack-item[gs-x="74"]{left:calc(var(--cellw, 6px)*74)}
.grid-stack > .grid-stack-item[gs-x="75"]{left:calc(var(--cellw, 6px)*75)}
.grid-stack > .grid-stack-item[gs-x="76"]{left:calc(var(--cellw, 6px)*76)}
.grid-stack > .grid-stack-item[gs-x="77"]{left:calc(var(--cellw, 6px)*77)}
.grid-stack > .grid-stack-item[gs-x="78"]{left:calc(var(--cellw, 6px)*78)}
.grid-stack > .grid-stack-item[gs-x="79"]{left:calc(var(--cellw, 6px)*79)}
.grid-stack > .grid-stack-item[gs-x="80"]{left:calc(var(--cellw, 6px)*80)}
.grid-stack > .grid-stack-item[gs-x="81"]{left:calc(var(--cellw, 6px)*81)}
.grid-stack > .grid-stack-item[gs-x="82"]{left:calc(var(--cellw, 6px)*82)}
.grid-stack > .grid-stack-item[gs-x="83"]{left:calc(var(--cellw, 6px)*83)}
.grid-stack > .grid-stack-item[gs-x="84"]{left:calc(var(--cellw, 6px)*84)}
.grid-stack > .grid-stack-item[gs-x="85"]{left:calc(var(--cellw, 6px)*85)}
.grid-stack > .grid-stack-item[gs-x="86"]{left:calc(var(--cellw, 6px)*86)}
.grid-stack > .grid-stack-item[gs-x="87"]{left:calc(var(--cellw, 6px)*87)}
.grid-stack > .grid-stack-item[gs-x="88"]{left:calc(var(--cellw, 6px)*88)}
.grid-stack > .grid-stack-item[gs-x="89"]{left:calc(var(--cellw, 6px)*89)}
.grid-stack > .grid-stack-item[gs-x="90"]{left:calc(var(--cellw, 6px)*90)}
.grid-stack > .grid-stack-item[gs-x="91"]{left:calc(var(--cellw, 6px)*91)}
.grid-stack > .grid-stack-item[gs-x="92"]{left:calc(var(--cellw, 6px)*92)}
.grid-stack > .grid-stack-item[gs-x="93"]{left:calc(var(--cellw, 6px)*93)}
.grid-stack > .grid-stack-item[gs-x="94"]{left:calc(var(--cellw, 6px)*94)}
.grid-stack > .grid-stack-item[gs-x="95"]{left:calc(var(--cellw, 6px)*95)}
.grid-stack > .grid-stack-item[gs-x="96"]{left:calc(var(--cellw, 6px)*96)}
.grid-stack > .grid-stack-item[gs-x="97"]{left:calc(var(--cellw, 6px)*97)}
.grid-stack > .grid-stack-item[gs-x="98"]{left:calc(var(--cellw, 6px)*98)}
.grid-stack > .grid-stack-item[gs-x="99"]{left:calc(var(--cellw, 6px)*99)}
.grid-stack > .grid-stack-item[gs-x="100"]{left:calc(var(--cellw, 6px)*100)}
.grid-stack > .grid-stack-item[gs-x="101"]{left:calc(var(--cellw, 6px)*101)}
.grid-stack > .grid-stack-item[gs-x="102"]{left:calc(var(--cellw, 6px)*102)}
.grid-stack > .grid-stack-item[gs-x="103"]{left:calc(var(--cellw, 6px)*103)}
.grid-stack > .grid-stack-item[gs-x="104"]{left:calc(var(--cellw, 6px)*104)}
.grid-stack > .grid-stack-item[gs-x="105"]{left:calc(var(--cellw, 6px)*105)}
.grid-stack > .grid-stack-item[gs-x="106"]{left:calc(var(--cellw, 6px)*106)}
.grid-stack > .grid-stack-item[gs-x="107"]{left:calc(var(--cellw, 6px)*107)}
.grid-stack > .grid-stack-item[gs-x="108"]{left:calc(var(--cellw, 6px)*108)}
.grid-stack > .grid-stack-item[gs-x="109"]{left:calc(var(--cellw, 6px)*109)}
.grid-stack > .grid-stack-item[gs-x="110"]{left:calc(var(--cellw, 6px)*110)}
.grid-stack > .grid-stack-item[gs-x="111"]{left:calc(var(--cellw, 6px)*111)}
.grid-stack > .grid-stack-item[gs-x="112"]{left:calc(var(--cellw, 6px)*112)}
.grid-stack > .grid-stack-item[gs-x="113"]{left:calc(var(--cellw, 6px)*113)}
.grid-stack > .grid-stack-item[gs-x="114"]{left:calc(var(--cellw, 6px)*114)}
.grid-stack > .grid-stack-item[gs-x="115"]{left:calc(var(--cellw, 6px)*115)}
.grid-stack > .grid-stack-item[gs-x="116"]{left:calc(var(--cellw, 6px)*116)}
.grid-stack > .grid-stack-item[gs-x="117"]{left:calc(var(--cellw, 6px)*117)}
.grid-stack > .grid-stack-item[gs-x="118"]{left:calc(var(--cellw, 6px)*118)}
.grid-stack > .grid-stack-item[gs-x="119"]{left:calc(var(--cellw, 6px)*119)}
.grid-stack > .grid-stack-item[gs-x="120"]{left:calc(var(--cellw, 6px)*120)}
.grid-stack > .grid-stack-item[gs-x="121"]{left:calc(var(--cellw, 6px)*121)}
.grid-stack > .grid-stack-item[gs-x="122"]{left:calc(var(--cellw, 6px)*122)}
.grid-stack > .grid-stack-item[gs-x="123"]{left:calc(var(--cellw, 6px)*123)}
.grid-stack > .grid-stack-item[gs-x="124"]{left:calc(var(--cellw, 6px)*124)}
.grid-stack > .grid-stack-item[gs-x="125"]{left:calc(var(--cellw, 6px)*125)}
.grid-stack > .grid-stack-item[gs-x="126"]{left:calc(var(--cellw, 6px)*126)}
.grid-stack > .grid-stack-item[gs-x="127"]{left:calc(var(--cellw, 6px)*127)}
.grid-stack > .grid-stack-item[gs-x="128"]{left:calc(var(--cellw, 6px)*128)}
.grid-stack > .grid-stack-item[gs-x="129"]{left:calc(var(--cellw, 6px)*129)}
.grid-stack > .grid-stack-item[gs-x="130"]{left:calc(var(--cellw, 6px)*130)}
.grid-stack > .grid-stack-item[gs-x="131"]{left:calc(var(--cellw, 6px)*131)}
.grid-stack > .grid-stack-item[gs-x="132"]{left:calc(var(--cellw, 6px)*132)}
.grid-stack > .grid-stack-item[gs-x="133"]{left:calc(var(--cellw, 6px)*133)}
.grid-stack > .grid-stack-item[gs-x="134"]{left:calc(var(--cellw, 6px)*134)}
.grid-stack > .grid-stack-item[gs-x="135"]{left:calc(var(--cellw, 6px)*135)}
.grid-stack > .grid-stack-item[gs-x="136"]{left:calc(var(--cellw, 6px)*136)}
.grid-stack > .grid-stack-item[gs-x="137"]{left:calc(var(--cellw, 6px)*137)}
.grid-stack > .grid-stack-item[gs-x="138"]{left:calc(var(--cellw, 6px)*138)}
.grid-stack > .grid-stack-item[gs-x="139"]{left:calc(var(--cellw, 6px)*139)}
.grid-stack > .grid-stack-item[gs-x="140"]{left:calc(var(--cellw, 6px)*140)}
.grid-stack > .grid-stack-item[gs-x="141"]{left:calc(var(--cellw, 6px)*141)}
.grid-stack > .grid-stack-item[gs-x="142"]{left:calc(var(--cellw, 6px)*142)}
.grid-stack > .grid-stack-item[gs-x="143"]{left:calc(var(--cellw, 6px)*143)}
.grid-stack > .grid-stack-item[gs-x="144"]{left:calc(var(--cellw, 6px)*144)}
.grid-stack > .grid-stack-item[gs-x="145"]{left:calc(var(--cellw, 6px)*145)}
.grid-stack > .grid-stack-item[gs-x="146"]{left:calc(var(--cellw, 6px)*146)}
.grid-stack > .grid-stack-item[gs-x="147"]{left:calc(var(--cellw, 6px)*147)}
.grid-stack > .grid-stack-item[gs-x="148"]{left:calc(var(--cellw, 6px)*148)}
.grid-stack > .grid-stack-item[gs-x="149"]{left:calc(var(--cellw, 6px)*149)}
.grid-stack > .grid-stack-item[gs-x="150"]{left:calc(var(--cellw, 6px)*150)}
.grid-stack > .grid-stack-item[gs-x="151"]{left:calc(var(--cellw, 6px)*151)}
.grid-stack > .grid-stack-item[gs-x="152"]{left:calc(var(--cellw, 6px)*152)}
.grid-stack > .grid-stack-item[gs-x="153"]{left:calc(var(--cellw, 6px)*153)}
.grid-stack > .grid-stack-item[gs-x="154"]{left:calc(var(--cellw, 6px)*154)}
.grid-stack > .grid-stack-item[gs-x="155"]{left:calc(var(--cellw, 6px)*155)}
.grid-stack > .grid-stack-item[gs-x="156"]{left:calc(var(--cellw, 6px)*156)}
.grid-stack > .grid-stack-item[gs-x="157"]{left:calc(var(--cellw, 6px)*157)}
.grid-stack > .grid-stack-item[gs-x="158"]{left:calc(var(--cellw, 6px)*158)}
.grid-stack > .grid-stack-item[gs-x="159"]{left:calc(var(--cellw, 6px)*159)}
.grid-stack > .grid-stack-item[gs-x="160"]{left:calc(var(--cellw, 6px)*160)}
.grid-stack > .grid-stack-item[gs-x="161"]{left:calc(var(--cellw, 6px)*161)}
.grid-stack > .grid-stack-item[gs-x="162"]{left:calc(var(--cellw, 6px)*162)}
.grid-stack > .grid-stack-item[gs-x="163"]{left:calc(var(--cellw, 6px)*163)}
.grid-stack > .grid-stack-item[gs-x="164"]{left:calc(var(--cellw, 6px)*164)}
.grid-stack > .grid-stack-item[gs-x="165"]{left:calc(var(--cellw, 6px)*165)}
.grid-stack > .grid-stack-item[gs-x="166"]{left:calc(var(--cellw, 6px)*166)}
.grid-stack > .grid-stack-item[gs-x="167"]{left:calc(var(--cellw, 6px)*167)}
.grid-stack > .grid-stack-item[gs-x="168"]{left:calc(var(--cellw, 6px)*168)}
.grid-stack > .grid-stack-item[gs-x="169"]{left:calc(var(--cellw, 6px)*169)}
.grid-stack > .grid-stack-item[gs-x="170"]{left:calc(var(--cellw, 6px)*170)}
.grid-stack > .grid-stack-item[gs-x="171"]{left:calc(var(--cellw, 6px)*171)}
.grid-stack > .grid-stack-item[gs-x="172"]{left:calc(var(--cellw, 6px)*172)}
.grid-stack > .grid-stack-item[gs-x="173"]{left:calc(var(--cellw, 6px)*173)}
.grid-stack > .grid-stack-item[gs-x="174"]{left:calc(var(--cellw, 6px)*174)}
.grid-stack > .grid-stack-item[gs-x="175"]{left:calc(var(--cellw, 6px)*175)}
.grid-stack > .grid-stack-item[gs-x="176"]{left:calc(var(--cellw, 6px)*176)}
.grid-stack > .grid-stack-item[gs-x="177"]{left:calc(var(--cellw, 6px)*177)}
.grid-stack > .grid-stack-item[gs-x="178"]{left:calc(var(--cellw, 6px)*178)}
.grid-stack > .grid-stack-item[gs-x="179"]{left:calc(var(--cellw, 6px)*179)}
.grid-stack > .grid-stack-item[gs-x="180"]{left:calc(var(--cellw, 6px)*180)}
.grid-stack > .grid-stack-item[gs-x="181"]{left:calc(var(--cellw, 6px)*181)}
.grid-stack > .grid-stack-item[gs-x="182"]{left:calc(var(--cellw, 6px)*182)}
.grid-stack > .grid-stack-item[gs-x="183"]{left:calc(var(--cellw, 6px)*183)}
.grid-stack > .grid-stack-item[gs-x="184"]{left:calc(var(--cellw, 6px)*184)}
.grid-stack > .grid-stack-item[gs-x="185"]{left:calc(var(--cellw, 6px)*185)}
.grid-stack > .grid-stack-item[gs-x="186"]{left:calc(var(--cellw, 6px)*186)}
.grid-stack > .grid-stack-item[gs-x="187"]{left:calc(var(--cellw, 6px)*187)}
.grid-stack > .grid-stack-item[gs-x="188"]{left:calc(var(--cellw, 6px)*188)}
.grid-stack > .grid-stack-item[gs-x="189"]{left:calc(var(--cellw, 6px)*189)}
.grid-stack > .grid-stack-item[gs-x="190"]{left:calc(var(--cellw, 6px)*190)}
.grid-stack > .grid-stack-item[gs-x="191"]{left:calc(var(--cellw, 6px)*191)}
.grid-stack > .grid-stack-item[gs-x="192"]{left:calc(var(--cellw, 6px)*192)}
.grid-stack > .grid-stack-item[gs-x="193"]{left:calc(var(--cellw, 6px)*193)}
.grid-stack > .grid-stack-item[gs-x="194"]{left:calc(var(--cellw, 6px)*194)}
.grid-stack > .grid-stack-item[gs-x="195"]{left:calc(var(--cellw, 6px)*195)}
.grid-stack > .grid-stack-item[gs-x="196"]{left:calc(var(--cellw, 6px)*196)}
.grid-stack > .grid-stack-item[gs-x="197"]{left:calc(var(--cellw, 6px)*197)}
.grid-stack > .grid-stack-item[gs-x="198"]{left:calc(var(--cellw, 6px)*198)}
.grid-stack > .grid-stack-item[gs-x="199"]{left:calc(var(--cellw, 6px)*199)}
.grid-stack > .grid-stack-item[gs-x="200"]{left:calc(var(--cellw, 6px)*200)}
.grid-stack > .grid-stack-item[gs-x="201"]{left:calc(var(--cellw, 6px)*201)}
.grid-stack > .grid-stack-item[gs-x="202"]{left:calc(var(--cellw, 6px)*202)}
.grid-stack > .grid-stack-item[gs-x="203"]{left:calc(var(--cellw, 6px)*203)}
.grid-stack > .grid-stack-item[gs-x="204"]{left:calc(var(--cellw, 6px)*204)}
.grid-stack > .grid-stack-item[gs-x="205"]{left:calc(var(--cellw, 6px)*205)}
.grid-stack > .grid-stack-item[gs-x="206"]{left:calc(var(--cellw, 6px)*206)}
.grid-stack > .grid-stack-item[gs-x="207"]{left:calc(var(--cellw, 6px)*207)}
.grid-stack > .grid-stack-item[gs-x="208"]{left:calc(var(--cellw, 6px)*208)}
.grid-stack > .grid-stack-item[gs-x="209"]{left:calc(var(--cellw, 6px)*209)}
.grid-stack > .grid-stack-item[gs-x="210"]{left:calc(var(--cellw, 6px)*210)}
.grid-stack > .grid-stack-item[gs-x="211"]{left:calc(var(--cellw, 6px)*211)}
.grid-stack > .grid-stack-item[gs-x="212"]{left:calc(var(--cellw, 6px)*212)}
.grid-stack > .grid-stack-item[gs-x="213"]{left:calc(var(--cellw, 6px)*213)}
.grid-stack > .grid-stack-item[gs-x="214"]{left:calc(var(--cellw, 6px)*214)}
.grid-stack > .grid-stack-item[gs-x="215"]{left:calc(var(--cellw, 6px)*215)}
.grid-stack > .grid-stack-item[gs-x="216"]{left:calc(var(--cellw, 6px)*216)}
.grid-stack > .grid-stack-item[gs-x="217"]{left:calc(var(--cellw, 6px)*217)}
.grid-stack > .grid-stack-item[gs-x="218"]{left:calc(var(--cellw, 6px)*218)}
.grid-stack > .grid-stack-item[gs-x="219"]{left:calc(var(--cellw, 6px)*219)}
.grid-stack > .grid-stack-item[gs-x="220"]{left:calc(var(--cellw, 6px)*220)}
.grid-stack > .grid-stack-item[gs-x="221"]{left:calc(var(--cellw, 6px)*221)}
.grid-stack > .grid-stack-item[gs-x="222"]{left:calc(var(--cellw, 6px)*222)}
.grid-stack > .grid-stack-item[gs-x="223"]{left:calc(var(--cellw, 6px)*223)}
.grid-stack > .grid-stack-item[gs-x="224"]{left:calc(var(--cellw, 6px)*224)}
.grid-stack > .grid-stack-item[gs-x="225"]{left:calc(var(--cellw, 6px)*225)}
.grid-stack > .grid-stack-item[gs-x="226"]{left:calc(var(--cellw, 6px)*226)}
.grid-stack > .grid-stack-item[gs-x="227"]{left:calc(var(--cellw, 6px)*227)}
.grid-stack > .grid-stack-item[gs-x="228"]{left:calc(var(--cellw, 6px)*228)}
.grid-stack > .grid-stack-item[gs-x="229"]{left:calc(var(--cellw, 6px)*229)}
.grid-stack > .grid-stack-item[gs-x="230"]{left:calc(var(--cellw, 6px)*230)}
.grid-stack > .grid-stack-item[gs-x="231"]{left:calc(var(--cellw, 6px)*231)}
.grid-stack > .grid-stack-item[gs-x="232"]{left:calc(var(--cellw, 6px)*232)}
.grid-stack > .grid-stack-item[gs-x="233"]{left:calc(var(--cellw, 6px)*233)}
.grid-stack > .grid-stack-item[gs-x="234"]{left:calc(var(--cellw, 6px)*234)}
.grid-stack > .grid-stack-item[gs-x="235"]{left:calc(var(--cellw, 6px)*235)}
.grid-stack > .grid-stack-item[gs-x="236"]{left:calc(var(--cellw, 6px)*236)}
.grid-stack > .grid-stack-item[gs-x="237"]{left:calc(var(--cellw, 6px)*237)}
.grid-stack > .grid-stack-item[gs-x="238"]{left:calc(var(--cellw, 6px)*238)}
.grid-stack > .grid-stack-item[gs-x="239"]{left:calc(var(--cellw, 6px)*239)}
.grid-stack > .grid-stack-item[gs-x="240"]{left:calc(var(--cellw, 6px)*240)}
.grid-stack > .grid-stack-item[gs-x="241"]{left:calc(var(--cellw, 6px)*241)}
.grid-stack > .grid-stack-item[gs-x="242"]{left:calc(var(--cellw, 6px)*242)}
.grid-stack > .grid-stack-item[gs-x="243"]{left:calc(var(--cellw, 6px)*243)}
.grid-stack > .grid-stack-item[gs-x="244"]{left:calc(var(--cellw, 6px)*244)}
.grid-stack > .grid-stack-item[gs-x="245"]{left:calc(var(--cellw, 6px)*245)}
.grid-stack > .grid-stack-item[gs-x="246"]{left:calc(var(--cellw, 6px)*246)}
.grid-stack > .grid-stack-item[gs-x="247"]{left:calc(var(--cellw, 6px)*247)}
.grid-stack > .grid-stack-item[gs-x="248"]{left:calc(var(--cellw, 6px)*248)}
.grid-stack > .grid-stack-item[gs-x="249"]{left:calc(var(--cellw, 6px)*249)}
.grid-stack > .grid-stack-item[gs-x="250"]{left:calc(var(--cellw, 6px)*250)}
.grid-stack > .grid-stack-item[gs-x="251"]{left:calc(var(--cellw, 6px)*251)}
.grid-stack > .grid-stack-item[gs-x="252"]{left:calc(var(--cellw, 6px)*252)}
.grid-stack > .grid-stack-item[gs-x="253"]{left:calc(var(--cellw, 6px)*253)}
.grid-stack > .grid-stack-item[gs-x="254"]{left:calc(var(--cellw, 6px)*254)}
.grid-stack > .grid-stack-item[gs-x="255"]{left:calc(var(--cellw, 6px)*255)}
.grid-stack > .grid-stack-item[gs-x="256"]{left:calc(var(--cellw, 6px)*256)}
.grid-stack > .grid-stack-item[gs-x="257"]{left:calc(var(--cellw, 6px)*257)}
.grid-stack > .grid-stack-item[gs-x="258"]{left:calc(var(--cellw, 6px)*258)}
.grid-stack > .grid-stack-item[gs-x="259"]{left:calc(var(--cellw, 6px)*259)}
.grid-stack > .grid-stack-item[gs-x="260"]{left:calc(var(--cellw, 6px)*260)}
.grid-stack > .grid-stack-item[gs-x="261"]{left:calc(var(--cellw, 6px)*261)}
.grid-stack > .grid-stack-item[gs-x="262"]{left:calc(var(--cellw, 6px)*262)}
.grid-stack > .grid-stack-item[gs-x="263"]{left:calc(var(--cellw, 6px)*263)}
.grid-stack > .grid-stack-item[gs-x="264"]{left:calc(var(--cellw, 6px)*264)}
.grid-stack > .grid-stack-item[gs-x="265"]{left:calc(var(--cellw, 6px)*265)}
.grid-stack > .grid-stack-item[gs-x="266"]{left:calc(var(--cellw, 6px)*266)}
.grid-stack > .grid-stack-item[gs-x="267"]{left:calc(var(--cellw, 6px)*267)}
.grid-stack > .grid-stack-item[gs-x="268"]{left:calc(var(--cellw, 6px)*268)}
.grid-stack > .grid-stack-item[gs-x="269"]{left:calc(var(--cellw, 6px)*269)}
.grid-stack > .grid-stack-item[gs-x="270"]{left:calc(var(--cellw, 6px)*270)}
.grid-stack > .grid-stack-item[gs-x="271"]{left:calc(var(--cellw, 6px)*271)}
.grid-stack > .grid-stack-item[gs-x="272"]{left:calc(var(--cellw, 6px)*272)}
.grid-stack > .grid-stack-item[gs-x="273"]{left:calc(var(--cellw, 6px)*273)}
.grid-stack > .grid-stack-item[gs-x="274"]{left:calc(var(--cellw, 6px)*274)}
.grid-stack > .grid-stack-item[gs-x="275"]{left:calc(var(--cellw, 6px)*275)}
.grid-stack > .grid-stack-item[gs-x="276"]{left:calc(var(--cellw, 6px)*276)}
.grid-stack > .grid-stack-item[gs-x="277"]{left:calc(var(--cellw, 6px)*277)}
.grid-stack > .grid-stack-item[gs-x="278"]{left:calc(var(--cellw, 6px)*278)}
.grid-stack > .grid-stack-item[gs-x="279"]{left:calc(var(--cellw, 6px)*279)}
.grid-stack > .grid-stack-item[gs-x="280"]{left:calc(var(--cellw, 6px)*280)}
.grid-stack > .grid-stack-item[gs-x="281"]{left:calc(var(--cellw, 6px)*281)}
.grid-stack > .grid-stack-item[gs-x="282"]{left:calc(var(--cellw, 6px)*282)}
.grid-stack > .grid-stack-item[gs-x="283"]{left:calc(var(--cellw, 6px)*283)}
.grid-stack > .grid-stack-item[gs-x="284"]{left:calc(var(--cellw, 6px)*284)}
.grid-stack > .grid-stack-item[gs-x="285"]{left:calc(var(--cellw, 6px)*285)}
.grid-stack > .grid-stack-item[gs-x="286"]{left:calc(var(--cellw, 6px)*286)}
.grid-stack > .grid-stack-item[gs-x="287"]{left:calc(var(--cellw, 6px)*287)}
.grid-stack > .grid-stack-item[gs-x="288"]{left:calc(var(--cellw, 6px)*288)}
.grid-stack > .grid-stack-item[gs-x="289"]{left:calc(var(--cellw, 6px)*289)}
.grid-stack > .grid-stack-item[gs-x="290"]{left:calc(var(--cellw, 6px)*290)}
.grid-stack > .grid-stack-item[gs-x="291"]{left:calc(var(--cellw, 6px)*291)}
.grid-stack > .grid-stack-item[gs-x="292"]{left:calc(var(--cellw, 6px)*292)}
.grid-stack > .grid-stack-item[gs-x="293"]{left:calc(var(--cellw, 6px)*293)}
.grid-stack > .grid-stack-item[gs-x="294"]{left:calc(var(--cellw, 6px)*294)}
.grid-stack > .grid-stack-item[gs-x="295"]{left:calc(var(--cellw, 6px)*295)}
.grid-stack > .grid-stack-item[gs-x="296"]{left:calc(var(--cellw, 6px)*296)}
.grid-stack > .grid-stack-item[gs-x="297"]{left:calc(var(--cellw, 6px)*297)}
.grid-stack > .grid-stack-item[gs-x="298"]{left:calc(var(--cellw, 6px)*298)}
.grid-stack > .grid-stack-item[gs-x="299"]{left:calc(var(--cellw, 6px)*299)}
.grid-stack > .grid-stack-item[gs-x="300"]{left:calc(var(--cellw, 6px)*300)}
.grid-stack > .grid-stack-item[gs-x="301"]{left:calc(var(--cellw, 6px)*301)}
.grid-stack > .grid-stack-item[gs-x="302"]{left:calc(var(--cellw, 6px)*302)}
.grid-stack > .grid-stack-item[gs-x="303"]{left:calc(var(--cellw, 6px)*303)}
.grid-stack > .grid-stack-item[gs-x="304"]{left:calc(var(--cellw, 6px)*304)}
.grid-stack > .grid-stack-item[gs-x="305"]{left:calc(var(--cellw, 6px)*305)}
.grid-stack > .grid-stack-item[gs-x="306"]{left:calc(var(--cellw, 6px)*306)}
.grid-stack > .grid-stack-item[gs-x="307"]{left:calc(var(--cellw, 6px)*307)}
.grid-stack > .grid-stack-item[gs-x="308"]{left:calc(var(--cellw, 6px)*308)}
.grid-stack > .grid-stack-item[gs-x="309"]{left:calc(var(--cellw, 6px)*309)}
.grid-stack > .grid-stack-item[gs-x="310"]{left:calc(var(--cellw, 6px)*310)}
.grid-stack > .grid-stack-item[gs-x="311"]{left:calc(var(--cellw, 6px)*311)}
.grid-stack > .grid-stack-item[gs-x="312"]{left:calc(var(--cellw, 6px)*312)}
.grid-stack > .grid-stack-item[gs-x="313"]{left:calc(var(--cellw, 6px)*313)}
.grid-stack > .grid-stack-item[gs-x="314"]{left:calc(var(--cellw, 6px)*314)}
.grid-stack > .grid-stack-item[gs-x="315"]{left:calc(var(--cellw, 6px)*315)}
.grid-stack > .grid-stack-item[gs-x="316"]{left:calc(var(--cellw, 6px)*316)}
.grid-stack > .grid-stack-item[gs-x="317"]{left:calc(var(--cellw, 6px)*317)}
.grid-stack > .grid-stack-item[gs-x="318"]{left:calc(var(--cellw, 6px)*318)}
.grid-stack > .grid-stack-item[gs-x="319"]{left:calc(var(--cellw, 6px)*319)}
.grid-stack > .grid-stack-item[gs-x="320"]{left:calc(var(--cellw, 6px)*320)}
.grid-stack > .grid-stack-item[gs-x="321"]{left:calc(var(--cellw, 6px)*321)}
.grid-stack > .grid-stack-item[gs-x="322"]{left:calc(var(--cellw, 6px)*322)}
.grid-stack > .grid-stack-item[gs-x="323"]{left:calc(var(--cellw, 6px)*323)}
.grid-stack > .grid-stack-item[gs-x="324"]{left:calc(var(--cellw, 6px)*324)}
.grid-stack > .grid-stack-item[gs-x="325"]{left:calc(var(--cellw, 6px)*325)}
.grid-stack > .grid-stack-item[gs-x="326"]{left:calc(var(--cellw, 6px)*326)}
.grid-stack > .grid-stack-item[gs-x="327"]{left:calc(var(--cellw, 6px)*327)}
.grid-stack > .grid-stack-item[gs-x="328"]{left:calc(var(--cellw, 6px)*328)}
.grid-stack > .grid-stack-item[gs-x="329"]{left:calc(var(--cellw, 6px)*329)}
.grid-stack > .grid-stack-item[gs-x="330"]{left:calc(var(--cellw, 6px)*330)}
.grid-stack > .grid-stack-item[gs-x="331"]{left:calc(var(--cellw, 6px)*331)}
.grid-stack > .grid-stack-item[gs-x="332"]{left:calc(var(--cellw, 6px)*332)}
.grid-stack > .grid-stack-item[gs-x="333"]{left:calc(var(--cellw, 6px)*333)}
.grid-stack > .grid-stack-item[gs-x="334"]{left:calc(var(--cellw, 6px)*334)}
.grid-stack > .grid-stack-item[gs-x="335"]{left:calc(var(--cellw, 6px)*335)}
.grid-stack > .grid-stack-item[gs-x="336"]{left:calc(var(--cellw, 6px)*336)}
.grid-stack > .grid-stack-item[gs-x="337"]{left:calc(var(--cellw, 6px)*337)}
.grid-stack > .grid-stack-item[gs-x="338"]{left:calc(var(--cellw, 6px)*338)}
.grid-stack > .grid-stack-item[gs-x="339"]{left:calc(var(--cellw, 6px)*339)}
.grid-stack > .grid-stack-item[gs-x="340"]{left:calc(var(--cellw, 6px)*340)}
.grid-stack > .grid-stack-item[gs-x="341"]{left:calc(var(--cellw, 6px)*341)}
.grid-stack > .grid-stack-item[gs-x="342"]{left:calc(var(--cellw, 6px)*342)}
.grid-stack > .grid-stack-item[gs-x="343"]{left:calc(var(--cellw, 6px)*343)}
.grid-stack > .grid-stack-item[gs-x="344"]{left:calc(var(--cellw, 6px)*344)}
.grid-stack > .grid-stack-item[gs-x="345"]{left:calc(var(--cellw, 6px)*345)}
.grid-stack > .grid-stack-item[gs-x="346"]{left:calc(var(--cellw, 6px)*346)}
.grid-stack > .grid-stack-item[gs-x="347"]{left:calc(var(--cellw, 6px)*347)}
.grid-stack > .grid-stack-item[gs-x="348"]{left:calc(var(--cellw, 6px)*348)}
.grid-stack > .grid-stack-item[gs-x="349"]{left:calc(var(--cellw, 6px)*349)}
.grid-stack > .grid-stack-item[gs-x="350"]{left:calc(var(--cellw, 6px)*350)}
.grid-stack > .grid-stack-item[gs-x="351"]{left:calc(var(--cellw, 6px)*351)}
.grid-stack > .grid-stack-item[gs-x="352"]{left:calc(var(--cellw, 6px)*352)}
.grid-stack > .grid-stack-item[gs-x="353"]{left:calc(var(--cellw, 6px)*353)}
.grid-stack > .grid-stack-item[gs-x="354"]{left:calc(var(--cellw, 6px)*354)}
.grid-stack > .grid-stack-item[gs-x="355"]{left:calc(var(--cellw, 6px)*355)}
.grid-stack > .grid-stack-item[gs-x="356"]{left:calc(var(--cellw, 6px)*356)}
.grid-stack > .grid-stack-item[gs-x="357"]{left:calc(var(--cellw, 6px)*357)}
.grid-stack > .grid-stack-item[gs-x="358"]{left:calc(var(--cellw, 6px)*358)}
.grid-stack > .grid-stack-item[gs-x="359"]{left:calc(var(--cellw, 6px)*359)}
.grid-stack > .grid-stack-item[gs-x="360"]{left:calc(var(--cellw, 6px)*360)}
.grid-stack > .grid-stack-item[gs-x="361"]{left:calc(var(--cellw, 6px)*361)}
.grid-stack > .grid-stack-item[gs-x="362"]{left:calc(var(--cellw, 6px)*362)}
.grid-stack > .grid-stack-item[gs-x="363"]{left:calc(var(--cellw, 6px)*363)}
.grid-stack > .grid-stack-item[gs-x="364"]{left:calc(var(--cellw, 6px)*364)}
.grid-stack > .grid-stack-item[gs-x="365"]{left:calc(var(--cellw, 6px)*365)}
.grid-stack > .grid-stack-item[gs-x="366"]{left:calc(var(--cellw, 6px)*366)}
.grid-stack > .grid-stack-item[gs-x="367"]{left:calc(var(--cellw, 6px)*367)}
.grid-stack > .grid-stack-item[gs-x="368"]{left:calc(var(--cellw, 6px)*368)}
.grid-stack > .grid-stack-item[gs-x="369"]{left:calc(var(--cellw, 6px)*369)}
.grid-stack > .grid-stack-item[gs-x="370"]{left:calc(var(--cellw, 6px)*370)}
.grid-stack > .grid-stack-item[gs-x="371"]{left:calc(var(--cellw, 6px)*371)}
.grid-stack > .grid-stack-item[gs-x="372"]{left:calc(var(--cellw, 6px)*372)}
.grid-stack > .grid-stack-item[gs-x="373"]{left:calc(var(--cellw, 6px)*373)}
.grid-stack > .grid-stack-item[gs-x="374"]{left:calc(var(--cellw, 6px)*374)}
.grid-stack > .grid-stack-item[gs-x="375"]{left:calc(var(--cellw, 6px)*375)}
.grid-stack > .grid-stack-item[gs-x="376"]{left:calc(var(--cellw, 6px)*376)}
.grid-stack > .grid-stack-item[gs-x="377"]{left:calc(var(--cellw, 6px)*377)}
.grid-stack > .grid-stack-item[gs-x="378"]{left:calc(var(--cellw, 6px)*378)}
.grid-stack > .grid-stack-item[gs-x="379"]{left:calc(var(--cellw, 6px)*379)}
.grid-stack > .grid-stack-item[gs-x="380"]{left:calc(var(--cellw, 6px)*380)}
.grid-stack > .grid-stack-item[gs-x="381"]{left:calc(var(--cellw, 6px)*381)}
.grid-stack > .grid-stack-item[gs-x="382"]{left:calc(var(--cellw, 6px)*382)}
.grid-stack > .grid-stack-item[gs-x="383"]{left:calc(var(--cellw, 6px)*383)}
.grid-stack > .grid-stack-item[gs-x="384"]{left:calc(var(--cellw, 6px)*384)}
.grid-stack > .grid-stack-item[gs-x="385"]{left:calc(var(--cellw, 6px)*385)}
.grid-stack > .grid-stack-item[gs-x="386"]{left:calc(var(--cellw, 6px)*386)}
.grid-stack > .grid-stack-item[gs-x="387"]{left:calc(var(--cellw, 6px)*387)}
.grid-stack > .grid-stack-item[gs-x="388"]{left:calc(var(--cellw, 6px)*388)}
.grid-stack > .grid-stack-item[gs-x="389"]{left:calc(var(--cellw, 6px)*389)}
.grid-stack > .grid-stack-item[gs-x="390"]{left:calc(var(--cellw, 6px)*390)}
.grid-stack > .grid-stack-item[gs-x="391"]{left:calc(var(--cellw, 6px)*391)}
.grid-stack > .grid-stack-item[gs-x="392"]{left:calc(var(--cellw, 6px)*392)}
.grid-stack > .grid-stack-item[gs-x="393"]{left:calc(var(--cellw, 6px)*393)}
.grid-stack > .grid-stack-item[gs-x="394"]{left:calc(var(--cellw, 6px)*394)}
.grid-stack > .grid-stack-item[gs-x="395"]{left:calc(var(--cellw, 6px)*395)}
.grid-stack > .grid-stack-item[gs-x="396"]{left:calc(var(--cellw, 6px)*396)}
.grid-stack > .grid-stack-item[gs-x="397"]{left:calc(var(--cellw, 6px)*397)}
.grid-stack > .grid-stack-item[gs-x="398"]{left:calc(var(--cellw, 6px)*398)}
.grid-stack > .grid-stack-item[gs-x="399"]{left:calc(var(--cellw, 6px)*399)}
.grid-stack > .grid-stack-item[gs-x="400"]{left:calc(var(--cellw, 6px)*400)}

/* ── markets pane scrollbars (vert + horiz, always visible) ─── */
#pane-finance .live-scroll { overflow: scroll; scrollbar-width: thin; scrollbar-color: #39445f transparent; }
#pane-finance .live-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
#pane-finance .live-scroll::-webkit-scrollbar-track { background: rgba(11, 15, 23, .55); border-radius: 6px; }
#pane-finance .live-scroll::-webkit-scrollbar-thumb { background: #2b3550; border-radius: 6px; border: 2px solid var(--panel); }
#pane-finance .live-scroll::-webkit-scrollbar-thumb:hover { background: var(--amber-dim); }
#pane-finance .live-scroll::-webkit-scrollbar-corner { background: transparent; }
/* keep fold sections a readable width — a narrow Markets pane scrolls
   horizontally instead of crushing the tiles */
#pane-finance .fold-sec { min-width: 620px; }

/* the same thin, theme-matched scrollbars on other pane scroll areas (auto) */
.pane-body, .live-scroll { scrollbar-width: thin; scrollbar-color: #39445f transparent; }
.pane-body::-webkit-scrollbar, .live-scroll::-webkit-scrollbar { width: 10px; height: 10px; }
.pane-body::-webkit-scrollbar-thumb, .live-scroll::-webkit-scrollbar-thumb { background: #2b3550; border-radius: 6px; border: 2px solid var(--panel); }
.pane-body::-webkit-scrollbar-thumb:hover, .live-scroll::-webkit-scrollbar-thumb:hover { background: var(--amber-dim); }
.pane-body::-webkit-scrollbar-track, .live-scroll::-webkit-scrollbar-track { background: transparent; }
.pane-body::-webkit-scrollbar-corner, .live-scroll::-webkit-scrollbar-corner { background: transparent; }

/* ── user-editable content panes (links + live) ──────────────── */
.cr-hdr { display: flex; align-items: center; gap: .3rem; margin-top: .12rem; }
.cr-hdr .live-group-title { flex: 1; margin: 0; }
.cr-hdr .cr-add, .pane-foot .cr-add { flex-shrink: 0; line-height: 1.1; font-size: .8rem; }
.link-row { display: flex; align-items: center; gap: .22rem; }
.link-row .live-btn { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.live-station .cr-del { margin-left: auto; }
.cr-del { background: transparent; border: none; color: var(--muted); cursor: pointer;
  font-size: .66rem; padding: .14rem .2rem; opacity: 0; transition: opacity .12s; flex-shrink: 0; }
.link-row:hover .cr-del, .live-station:hover .cr-del { opacity: 1; }
.cr-del:hover { color: #ff7a6e; }
.cr-form { display: flex; flex-wrap: wrap; gap: .25rem; align-items: center; margin: .2rem 0 .35rem; }
.cr-form input, .cr-form select { background: #0d1420; border: 1px solid var(--line);
  color: var(--text); border-radius: 6px; padding: .18rem .4rem; font-size: .76rem; }
.cr-form input { min-width: 0; }
.cr-form input:focus, .cr-form select:focus { outline: none; border-color: var(--amber-dim); }
.cr-form .fname { flex: 0 1 7rem; }
.cr-form .furl { flex: 2 1 11rem; }
.cr-form .fgrp { flex: 0 1 8rem; }
.cr-form .fstream { flex: 1 1 12rem; }
.cr-actions { display: flex; gap: .25rem; }
.cr-actions .chip-btn { font-size: .72rem; padding: .16rem .5rem; }
.pane-foot { display: flex; align-items: center; gap: .45rem; margin-top: .2rem; flex-wrap: wrap; }
.pane-foot .pane-empty { margin: 0; }
.cr-inline { display: inline-flex; align-items: center; gap: .18rem; }
.cr-inline:hover .cr-del { opacity: 1; }

/* ── in-dashboard viewer (links open here instead of a new tab) ── */
.emb { position: absolute; inset: 0; z-index: 200; display: flex;
  flex-direction: column; background: var(--bg); }
.emb.hidden { display: none; }
.emb-bar { display: flex; align-items: center; gap: .5rem; flex-shrink: 0;
  padding: .28rem .55rem; border-bottom: 1px solid var(--line); background: #101624; font-size: .78rem; }
.emb-title { color: var(--amber); font-weight: 600; white-space: nowrap;
  max-width: 26%; overflow: hidden; text-overflow: ellipsis; }
.emb-url { color: var(--muted); flex: 1; min-width: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.emb-btn { background: transparent; border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; padding: .1rem .55rem; cursor: pointer; font-size: .76rem; line-height: 1.25; flex-shrink: 0; }
.emb-btn:hover { color: var(--amber); border-color: var(--amber-dim); }
.emb-frame { flex: 1; width: 100%; min-height: 0; border: 0; background: #fff; }

/* ── suggestions widget (fleet pattern; ClockRadio amber) ── */
.suggest-btn { position: fixed; right: 1rem; bottom: 1.4rem; z-index: 1501; width: 44px; height: 44px;
  border-radius: 50%; border: 1px solid var(--line); background: var(--panel-2); font-size: 1.15rem;
  cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,.4); line-height: 1; }
.suggest-btn:hover { border-color: var(--amber); transform: scale(1.1); }
.suggest-overlay { display: none; position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,.6);
  align-items: center; justify-content: center; }
.suggest-overlay.active { display: flex; }
.suggest-popup { background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  padding: 1.2rem; width: min(420px, 92vw); position: relative; box-shadow: 0 10px 40px rgba(0,0,0,.5); }
.suggest-close { position: absolute; top: .5rem; right: .7rem; background: none; border: none;
  color: var(--muted); font-size: 1.2rem; cursor: pointer; line-height: 1; }
.suggest-close:hover { color: var(--text); }
.suggest-title { font-size: 1rem; font-weight: 700; margin-bottom: .25rem; color: var(--text); }
.suggest-sub { font-size: .75rem; color: var(--muted); margin-bottom: 1rem; }
.suggest-textarea { width: 100%; min-height: 90px; background: #0d1420; border: 1px solid var(--line);
  color: var(--text); border-radius: 6px; padding: .5rem; font: inherit; resize: vertical; }
.suggest-textarea:focus { outline: none; border-color: var(--amber); }
.suggest-submit { margin-top: .6rem; border: none; border-radius: 6px; padding: .45rem 1rem;
  font-weight: 600; font-size: .85rem; cursor: pointer;
  background: linear-gradient(to right, var(--amber), #d97706); color: #0B0F17; }
.suggest-submit:hover { opacity: .9; }
.suggest-thanks { display: none; text-align: center; padding: 2rem 0; color: var(--amber); font-size: .9rem; }
/* 📍 location chip select (Task A 2026-09-08) — blends into the chips row */
.loc-sel { background: transparent; border: none; color: inherit; font: inherit;
  cursor: pointer; max-width: 9.5em; text-overflow: ellipsis; padding: 0 .15rem; }
.loc-sel:focus { outline: none; }
.loc-sel option { background: #0d1420; color: var(--text); }
/* 📈 Markets symbol-search dock (2026-09-08) — ＋ now opens a search field */
.fin-dock { display: none; padding: .35rem .45rem .45rem; border-bottom: 1px solid var(--line); background: var(--panel-2); }
.fin-dock.open { display: block; }
.fin-dock .fd-title { color: var(--muted); font-size: .64rem; margin-bottom: .28rem; }
.fin-dock input { width: 100%; box-sizing: border-box; background: var(--panel-1); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px; padding: .24rem .4rem; font-size: .72rem; }
.fin-dock input:focus { outline: none; border-color: var(--amber); }
.fin-res { margin-top: .3rem; max-height: 140px; overflow: auto; }
.fin-res .fr { display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text); font-size: .7rem; padding: .24rem .3rem; border-radius: 6px; cursor: pointer; }
.fin-res .fr:hover, .fin-res .fr:focus-visible { background: rgba(255, 176, 0, .08); color: var(--amber); }
.fin-res .fr .fr-sym { color: var(--muted); font-size: .62rem; }
/* dock result states (2026-09-09): exact-index quick-map row + already-in-group */
.fin-res .fr.fr-idx { box-shadow: inset 2px 0 0 rgba(255, 176, 0, .6); }
.fin-res .fr.fr-have { color: var(--muted); }
.fin-res .fr.fr-have:hover, .fin-res .fr.fr-have:focus-visible { background: rgba(255, 176, 0, .05); color: var(--muted); }
.fin-res .fr.fr-have .fr-sym { color: #3fb950; }
.fin-res .empty { color: var(--muted); font-size: .66rem; padding: .2rem .3rem; }
/* 📻 Live pane banner order select + mic state (2026-09-08) */
.live-sort { max-width: 6.4em; }
.live-mic.on { border-color: var(--amber); color: var(--amber); background: rgba(255, 176, 0, .12); }
.live-mic.on::after { content: ''; display: inline-block; width: .4rem; height: .4rem; margin-left: .18rem;
  border-radius: 50%; background: #f87171; animation: cr-blink 1.2s ease-in-out infinite; vertical-align: .05rem; }
@keyframes cr-blink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
/* Markets split (2026-09-08): US and Global are separate panes now; each may
   sit as a narrow 1-2-tile column (the old combined pane's 620px fold-sec
   minimum is NOT applied to the split pane ids). */
#pane-markets-us .pane-body, #pane-markets-global .pane-body { padding: .06rem 0 .5rem; } /* no left/right air: charts run to the pane edges (Mike 2026-09-09) */
#pane-markets-us .live-scroll > :first-child .fold-bar,
#pane-markets-global .live-scroll > :first-child .fold-bar { margin-top: 0; } /* banner → 'Indices' ~3px tighter (2026-09-09, Mike) */
#pane-markets-us .fold-sec, #pane-markets-global .fold-sec { min-width: 0; }
/* Watchlist tile borders / Live controls / Portfolio rows / Links chips run
   flush to the pane's left+right edges like the Markets panes — inter-element
   gaps untouched (2026-09-09, Mike) */
#pane-watchlist .pane-body, #pane-live .pane-body { padding: .38rem 0 .5rem; }
#pane-favorites .pane-body, #pane-links .pane-body { padding: .12rem 0 .5rem; } /* 2px more out under the banner (2026-09-09, Mike) */
/* Portfolio: history chart pinned at the top — keeps its space (flex:0 0
   auto); the Positions list below lives in .live-scroll and gets its own
   vertical scrollbar when rows overflow (2026-09-09, Mike) */
#pane-favorites .pf-pin { flex: 0 0 auto; overflow: hidden; }
/* Portfolio: a couple more px of air above the Positions bar so the chart's
   date row never crowds it (2026-09-09, Mike — after the leading fix the
   labels cleared the clip edge but still read tight). */
#pane-favorites .live-scroll > :first-child .fold-bar { margin-top: .34rem; }
/* Live: volume control → first group (~2px tighter per pass) */
#pane-live .vol-row { margin-bottom: 0; }
#pane-live .live-scroll > :first-child.cr-hdr { margin-top: .06rem; }
/* 🎙 Voice monitor pane (2026-09-08) — signal meter + heard + action */
.voice-state { font-size: .68rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.voice-state.on { color: var(--amber); }
.voice-meter { height: .5rem; background: #0d1420; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; flex-shrink: 0; }
.voice-meter-fill { width: 0; height: 100%; background: #39445f; border-radius: 999px; transition: width .06s linear; }
.voice-meter-fill.live { background: linear-gradient(to right, #3fb950, var(--amber)); }
.voice-cap { font-size: .56rem; letter-spacing: .1em; color: var(--muted); text-transform: uppercase; }
.voice-heard { font-size: .74rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: .9rem; }
.voice-action { font-size: .72rem; color: var(--amber); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: .9rem; }
.voice-actrow { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }
.voice-copy { background: none; border: none; color: var(--muted); cursor: pointer; font-size: .68rem;
  padding: .05rem .35rem; border-radius: 4px; line-height: 1; }
.voice-copy:hover { color: var(--amber); background: rgba(255, 176, 0, .08); }
.voice-hist { overflow-y: scroll; font-size: .62rem; color: var(--muted);
  flex: 1 1 3rem; min-height: 2.2rem; max-height: 40%;
  border-top: 1px dashed #1c2333; padding-top: .18rem;
  scrollbar-width: thin; scrollbar-color: #39445f transparent;
  user-select: text; cursor: text; }
.voice-hist::-webkit-scrollbar { width: 8px; }
.voice-hist::-webkit-scrollbar-thumb { background: #39445f; border-radius: 4px; }
.voice-hist::-webkit-scrollbar-track { background: transparent; }
.voice-hist.no-scroll { scrollbar-width: none; }
.voice-hist.no-scroll::-webkit-scrollbar { width: 0; }
.voice-row { white-space: normal; overflow-wrap: anywhere; padding: .06rem 0;
  user-select: text; cursor: text; }
/* whole-page voice (2026-09-08): brief amber ring on the pane voice just
   opened / brought to front ("show news" etc) */
.pane-ping { animation: cr-ping 1.5s ease-out 2; border-radius: 10px; }
@keyframes cr-ping {
  0% { box-shadow: 0 0 0 0 rgba(255, 176, 0, .5); }
  100% { box-shadow: 0 0 0 16px rgba(255, 176, 0, 0); }
}
/* ── header control hit targets (2026-09-08, Mike) ─────────────
   The pill banner is deliberately thin, which made the — ▢ ✕ window
   controls (and the restore-size ▢) hard to hit. Instead of sizing them
   relative to the banner (font/line-height), each button now gets a FIXED
   pixel hit box — tune ONE number (--pane-btn-hit), not banner-relative
   units. */
:root { --pane-btn-hit: 26px; } /* banner 2px shorter top & bottom — 30→26 (2026-09-09, Mike); title font/centering untouched */
.pane-actions .pane-btn { min-width: var(--pane-btn-hit); min-height: var(--pane-btn-hit);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 .2rem; font-size: .86rem; }
.pane-actions .pane-btn + .pane-btn { margin-left: -.3rem; } /* ✕ pulls under the toggle's right pad: glyph gap shrinks (~22→~12px), boxes only overlap on hover */
/* markets: just-added tile confirmation (2026-09-08) — brief amber pulse */
.fin-tile.fin-new { animation: cr-finnew 1.1s ease-out 2; }
@keyframes cr-finnew {
  0% { background: rgba(255, 176, 0, .35); box-shadow: 0 0 0 1px rgba(255, 176, 0, .55); }
  100% { background: #131a26; box-shadow: 0 0 0 1px transparent; }
}
/* 🎙 Voice pane visualizers (2026-09-08) */
.voice-wave, .voice-spec, .voice-specg { display: block; width: 100%; border: 1px solid var(--line);
  border-radius: 4px; background: #0a1018; flex-shrink: 0; }
.voice-specg { margin-top: .05rem; }
/* display-resolution reference layer — all native-size outlines share the
   workspace's active zoom transform; they are behind panes and inert */
#workspace { position: relative; }
.canvas-display-references { position: fixed; left: 0; top: 0; z-index: 0;
  pointer-events: none; overflow: hidden; width: 0; height: 0; }
.canvas-display-rect { position: absolute; left: 0; top: 0;
  border: 1px solid rgba(126, 146, 190, .16); border-radius: 2px;
  box-sizing: border-box; }
.foot-undo { display: inline-flex; align-items: center; gap: .3rem; margin-left: .35rem; }
.foot-undo .chip-btn:disabled { opacity: .38; cursor: default; }
.foot-savelayout { display: inline-flex; align-items: center; margin-left: .35rem; }
.foot-savelayout .chip-btn.saved { border-color: #FFB000; color: #FFB000; }
.undo-depth { color: var(--muted); font-size: .7rem; min-width: 2.2rem; }
.canvas-display-rect.largest { border-color: rgba(155, 171, 211, .22); }
/* small-screen AUTHORING guides (2026-09-13) — a SEPARATE layer above the panes,
   because the outlines above live at z-index 0 and `.grid-stack-item` is z-index
   1, so a small outline is buried the moment a pane covers it. Clipped to the
   canvas so it can never draw over the header or the footer. 150 clears the
   grid items (1) and GridStack's drag raise (~100) while staying under the
   modals (2100). */
.canvas-screen-guides { position: fixed; left: 0; top: 0; z-index: 150;
  pointer-events: none; overflow: hidden; display: none; }
body.dev .canvas-screen-guides { display: block; }
.screen-guide { position: absolute; left: 0; top: 0; box-sizing: border-box;
  border: 1px dashed rgba(157, 171, 204, .34); border-radius: 3px; }
.screen-guide-band { position: absolute; left: 0; right: 0; top: 0; box-sizing: border-box;
  border: 1px dashed rgba(198, 214, 255, .55); border-radius: 3px; }
.screen-guide-tag { position: absolute; left: 2px; top: 1px; white-space: nowrap;
  color: rgba(206, 218, 240, .78); background: rgba(11, 15, 23, .82);
  padding: 0 .3em; font: 500 11px/1.3 ui-monospace, SFMono-Regular, Consolas, monospace; }
.screen-guide-band .screen-guide-tag { top: auto; bottom: 1px; color: rgba(222, 232, 252, .9); }
.canvas-display-label { position: absolute; color: rgba(157, 171, 204, .30);
  padding: 0 .15em; background: #0b0f17;
  font: 500 12px/1 ui-monospace, SFMono-Regular, Consolas, monospace;
  letter-spacing: .02em; white-space: nowrap; text-shadow: 0 1px 2px #0b0f17,
  1px 0 2px #0b0f17, -1px 0 2px #0b0f17; }
.canvas-display-label-h { left: 50%; bottom: -1px; transform: translate(-50%, 50%); }
.canvas-display-label-v { right: -1px; top: 50%; transform: translate(50%, -50%) rotate(-90deg);
  transform-origin: center center; }
/* ── VIOLATION OVERLAY (2026-09-13, Mike) ─────────────────────────────────────
   "can you add a transparent overlay showing where the violations occur (so I can
   fix them intelligently)?" A THIRD reference layer, ABOVE the panes: the display
   references (z 0) sit behind them and the authoring guides (z 150) are thin dashed
   outlines, but a violation has to be LOUD, so it paints over the pane edge it
   describes. z 155 clears the grid items (1) and GridStack's drag raise (~100)
   while staying under the modals (2100) and the guides' own tags.
   Everything here is TRANSPARENT and inert — the marks are annotations, not UI.
   Red = content lost (under the footer, off the top/left edge, text cut by a
   pane). Amber = off-display or only-window-relative (a deliberate bleed, a `vw`
   font) — see paintViolations() in js/templates.js.

   ── TURNED DOWN + MADE LIVE (2026-09-16, Mike) ───────────────────────────────
   Mike: "make the violations overlay less prominent and dynamic so I can see one
   disappear when I eliminate the violation."
     · QUIETER: every fill is now 5-14% alpha and every border ~.5 (was 10-30% /
       .95), and the tags lost their opaque plates — a layout being fixed is
       mostly panes, not labels. Full detail moved to HOVER (`#viol-tip`), which
       is what the plates were standing in for, and the counts still live in the
       legend.
     · LIVE: the marks follow a drag/resize at a throttled 120ms instead of only
       landing 320ms after the pointer stops (js/app.js paintRefsLive), and a
       violation that DISAPPEARS leaves a green ghost fading out for 1.2s
       (`.viol-cleared-mark`) — the disappearance is what you are watching for,
       so it is the one thing on this layer allowed to move. */
.canvas-violations { position: fixed; left: 0; top: 0; z-index: 155;
  pointer-events: none; overflow: hidden; display: none; }
body.dev .canvas-violations { display: block; }
/* the layer holds three persistent boxes, never rebuilt: the marks, the ghosts of
   marks that just went away, and the legend. Rebuilding the layer would kill the
   ghosts' fade and the legend's flash mid-animation. */
.viol-marks, .viol-cleared { position: absolute; left: 0; top: 0; right: 0; bottom: 0; }
.viol-mark { position: absolute; box-sizing: border-box; border-radius: 2px; }
.viol-under { background: rgba(255, 64, 64, .10); border: 1px solid rgba(255, 96, 96, .50); }
.viol-off { background: rgba(255, 64, 64, .14); border: 1px solid rgba(255, 96, 96, .55); }
.viol-text { background: rgba(255, 64, 64, .07); border: 1px dashed rgba(255, 120, 120, .50); }
/* reachable only by SCROLLING a pane body — amber, and the Live pane never gets
   one (its own scroller is by design: js/templates.js paintViolations) */
.viol-scroll { background: rgba(255, 176, 0, .05); border: 1px dashed rgba(255, 176, 0, .38); }
.viol-vw { background: rgba(255, 176, 0, .07); border: 1px dashed rgba(255, 176, 0, .50); }
.viol-bleed { background: rgba(255, 176, 0, .10); border: 1px solid rgba(255, 176, 0, .45); }
.viol-reserved { background: repeating-linear-gradient(45deg,
  rgba(255, 64, 64, .09) 0 4px, rgba(255, 64, 64, .02) 4px 8px);
  border: none; border-top: 1px solid rgba(255, 96, 96, .45); border-radius: 0; }
.viol-past { background: rgba(255, 176, 0, .05);
  border: none; border-left: 1px solid rgba(255, 176, 0, .30); border-radius: 0; }
/* ── A GUIDE, NOT A VERDICT (2026-09-16, Mike) ───────────────────────────────
   The two reserved strips are the places a pane must not be. Painted in violation
   colours unconditionally they contradicted the legend ("a red band across the
   bottom while also saying 'nothing clipped'"), because red here means CONTENT IS
   GONE. Neutral until a pane is actually in the strip: no red, no amber, just a
   faint dim edge so the footer reserve stays visible while authoring. */
.viol-guide { background: rgba(150, 170, 200, .035);
  border: none; border-top: 1px dashed rgba(150, 170, 200, .20); border-radius: 0; }
.viol-guide.viol-guide-right { border-top: none; border-left: 1px dashed rgba(150, 170, 200, .20); }
/* ── THE CONTENT'S TRUE EXTENTS (2026-09-16, Mike) ────────────────────────────
   "We need a better handle on true content extents": a faint dashed box around what
   is actually DRAWN, so the empty pane around it reads as empty. NOT a violation —
   it is excluded from the count — it is the room a hug would reclaim and the reason
   the resize handles sit further out than the content. Deliberately in the
   display-reference family (dim steel, no fill, unboxed text) so it stays quieter
   than the marks that describe something actually lost. */
.viol-content { border: 1px dashed rgba(126, 146, 190, .34); background: none; border-radius: 0; }
.viol-content .viol-tag { color: rgba(178, 194, 222, .85); }
/* tags: NO PLATE any more — shadows carry the legibility instead (see the header
   block: the plate was what made the layer shout). The pointer detail is
   `#viol-tip`, which the marks' own hints feed. */
.viol-tag { position: absolute; left: 2px; top: -1px; white-space: nowrap;
  color: rgba(255, 214, 214, .85); padding: 0 .2em; border-radius: 2px;
  font: 500 10px/1.35 ui-monospace, SFMono-Regular, Consolas, monospace;
  text-shadow: 0 1px 2px #05080e, 0 0 3px #05080e; }
/* a mark whose own box is only the sliver past the display: the label has to grow
   INWARD (leftward) or it would be clipped away by the layer's own overflow */
.viol-tag-left { left: auto; right: 2px; }
.viol-vw .viol-tag, .viol-bleed .viol-tag, .viol-scroll .viol-tag,
.viol-past .viol-tag { color: rgba(255, 228, 184, .85); }
/* ── THE GHOST OF A VIOLATION YOU JUST ELIMINATED (2026-09-16) ────────────────
   Painted at the OLD mark's box for 1.2s and fading out, so "one disappeared"
   is visible rather than silent. Green: this is the good event on this layer. */
.viol-cleared-mark { position: absolute; box-sizing: border-box; border-radius: 2px;
  border: 1px dashed rgba(120, 220, 130, .95); background: rgba(63, 185, 80, .14);
  animation: viol-clear 1.2s ease-out forwards; }
@keyframes viol-clear { 0% { opacity: 1; } 70% { opacity: .75; } 100% { opacity: 0; } }
.viol-cleared-mark .viol-tag { color: #dff5e0; }
/* hover detail — FIXED and outside the scaled layer on purpose: the marks scale
   with the workspace (a 480x320 pin is scaled down), so a tooltip inside the
   layer would shrink with the mark it describes. */
#viol-tip { position: fixed; z-index: 156; display: none; max-width: 340px;
  pointer-events: none; color: #dfe7f5; background: rgba(9, 13, 20, .95);
  border: 1px solid rgba(255, 120, 120, .45); border-radius: 4px; padding: .3em .45em;
  font: 500 11px/1.4 ui-monospace, SFMono-Regular, Consolas, monospace;
  white-space: normal; }
#viol-tip.amber { border-color: rgba(255, 176, 0, .45); }
#viol-tip.ok { border-color: rgba(120, 220, 130, .45); color: #dff5e0; }
.viol-legend { position: absolute; white-space: nowrap; padding: .05em .4em;
  color: rgba(255, 217, 217, .9); background: rgba(22, 6, 8, .62); border: 1px solid rgba(255, 96, 96, .32);
  border-radius: 3px;
  font: 500 11px/1.45 ui-monospace, SFMono-Regular, Consolas, monospace; }
.viol-legend.ok { color: #cdeccd; background: rgba(8, 20, 10, .62); border-color: rgba(120, 220, 130, .32); }
/* the count CHANGED — the second signal that something was just fixed or broken */
.viol-legend.flash { animation: viol-flash 1.1s ease-out; }
@keyframes viol-flash { 0% { box-shadow: 0 0 0 2px rgba(120, 220, 130, .75); } 100% { box-shadow: 0 0 0 2px rgba(120, 220, 130, 0); } }

.lmod-overlay { position: fixed; inset: 0; z-index: 2100; background: rgba(5, 8, 14, .72);
  display: flex; align-items: center; justify-content: center; }
.lmod-overlay[hidden] { display: none; }
.lmod-popup { background: #0d1420; border: 1px solid var(--line); border-radius: 12px;
  padding: 1.1rem 1.2rem 1.2rem; width: min(560px, 94vw); max-height: 88vh; overflow: auto;
  position: relative; box-shadow: 0 10px 40px rgba(0, 0, 0, .55); }
.lmod-close { position: absolute; top: .5rem; right: .7rem; background: none; border: none;
  color: var(--muted); font-size: 1.25rem; cursor: pointer; line-height: 1; }
.lmod-close:hover { color: var(--text); }
.lmod-title { font-size: 1rem; font-weight: 700; margin-bottom: .15rem; color: var(--text); }
.lmod-sub { font-size: .72rem; color: var(--muted); margin-bottom: .9rem; }
.lmod-sec { font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--amber); margin: .8rem 0 .35rem; }
.lmod-select { width: 100%; background: #0a1018; color: var(--text); border: 1px solid var(--line);
  border-radius: 6px; padding: .3rem .4rem; font-size: .78rem; }
.lmod-sizes { display: flex; flex-wrap: wrap; gap: .45rem .9rem; }
.tpl-size-row { display: flex; align-items: flex-start; gap: .55rem; }
.tpl-cell { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.tpl-rect { border: 1px solid #93a7d6; border-radius: 3px; background: #31405f;
  flex-shrink: 0; padding: 0; box-sizing: content-box;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .45); }
.tpl-cap { font-size: .66rem; color: #cdd9f0; white-space: nowrap; text-align: center; }
.lmod-list { display: flex; flex-direction: column; gap: .3rem; max-height: 30vh; overflow: auto; }
.tpl-item { display: flex; align-items: center; gap: .5rem; background: #101725;
  border: 1px solid var(--line); border-radius: 8px; padding: .3rem .45rem; }
.tpl-item.tpl-exact { border-color: rgba(255, 176, 0, .55); }
.tpl-mini { border: 1px solid #39445f; border-radius: 2px; background: #1a2233; flex-shrink: 0; }
.tpl-meta { flex: 1; min-width: 0; }
.tpl-name { font-size: .78rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tpl-sub { font-size: .62rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tpl-go { flex-shrink: 0; }
.tpl-del { flex-shrink: 0; color: var(--muted); }
.tpl-del:hover { color: #f85149; }
.lmod-save-row { display: flex; gap: .4rem; margin-top: .9rem; }
.lmod-save-row input { flex: 1; background: #0a1018; color: var(--text); border: 1px solid var(--line);
  border-radius: 6px; padding: .3rem .45rem; font-size: .78rem; }
.lmod-msg { font-size: .7rem; color: var(--amber); margin-top: .35rem; min-height: .9rem; }

/* ── account sync modal (2026-09-09) — sign in on the 👤 chip ── */
.auth-modal { position: fixed; inset: 0; background: rgba(0, 0, 0, .55); display: flex;
  align-items: center; justify-content: center; z-index: 900; }
.auth-modal.hidden { display: none; }
.auth-box { background: #0d1420; border: 1px solid #263046; border-radius: 10px;
  padding: 1.1rem 1.2rem; width: min(360px, 92vw); position: relative;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .5); }
.auth-title { font-size: 1rem; font-weight: 700; color: var(--text); margin-bottom: .2rem; }
.auth-sub { font-size: .72rem; color: var(--muted); margin-bottom: .7rem; line-height: 1.35; }
.auth-text { width: 100%; box-sizing: border-box; background: var(--panel-1);
  border: 1px solid var(--line); border-radius: 6px; padding: .3rem .45rem;
  font-size: .8rem; color: var(--text); margin: .22rem 0; }
.auth-text:focus { outline: none; border-color: var(--amber-dim); }
.auth-msg { font-size: .72rem; color: var(--amber); min-height: 1.05em; margin: .2rem 0 .15rem; }
.auth-msg.err { color: #f85149; }
.auth-actions { display: flex; gap: .4rem; margin-top: .3rem; }

/* ── 🗺 Metros pane (2026-09-12) — the catalogue as a clickable map ──────────
   A navigation tool for the database, NOT a mapping app: no tiles, no map
   library, no external calls. Self-hosted CONUS outlines
   (data/geo/us-states.json) + one dot per catalogue metro; click a dot to
   visit that city (CR.setLocation), wheel zoom / drag pan / ⟲ reset / ⌖ here. */
#pane-metros .pane-body { padding: 0; display: flex; }
.mz-svg { flex: 1 1 auto; width: 100%; height: 100%; display: block; cursor: grab;
  touch-action: none; }
.mz-svg.dragging { cursor: grabbing; }
.mz-svg.mz-nopan { cursor: default; }   /* at FULL EXTENT clampView() pins
   view.x/y to 0, so there is genuinely nothing to pan — do not advertise a
   grab the map cannot honour (2026-09-12). Placed BEFORE .near so a dot still
   wins with its click cursor. */
.mz-svg.near { cursor: pointer; }   /* within a dot's click disc: the click
   affordance, not the map's grab cursor — the whole map grabbed look-alike
   was half of why the dots felt unreachable (2026-09-12) */
.mz-state { fill: #131a27; stroke: #2b3550; stroke-width: .8; stroke-linejoin: round;
  vector-effect: non-scaling-stroke; }
.mz-dot { fill: var(--amber); cursor: pointer; }
.mz-dot:hover, .mz-dot-g.hover .mz-dot { fill: var(--text); }

/* Ambiguity cues (2026-09-12): when one press covers more than one metro the
   view zooms in and each candidate gets a ring. Static rings show the whole
   candidate SET; the `.live` ring is recreated every 500 ms so its outline
   replays as a drawn circle around the next candidate in turn — the signal
   that a decisive click is still pending. */
.mz-cand { fill: none; stroke: var(--amber); stroke-width: 1.4; opacity: .38;
  vector-effect: non-scaling-stroke; pointer-events: none; }
.mz-cand.live { opacity: 1; stroke-width: 2; animation: mz-ring-draw .42s ease-out both; }
.mz-dot.cand { fill: var(--text); }
@keyframes mz-ring-draw {
  from { stroke-dashoffset: var(--mz-c, 80); opacity: .25; }
  to   { stroke-dashoffset: 0; opacity: 1; }
}
/* ── the SELECTED metro: amber INTERIOR, cyan ring (2026-09-16, Mike) ─────────
   "On the cyan-amber situation, I'd also like to reverse the sensibility of the
   selected Metro on the Metros map, moving to amber interior surrounded by a cyan
   ring." That is the same swap the Analog face took the same day (amber = what you
   read, cyan = the frame around it): the current metro is amber like every other
   dot's fill, and the ring that says WHICH one is current borrows the value colour.
   History, both directions on one day: the centre was `var(--text)` — the exact
   fill a HOVERED dot and a `.cand` dot take, so "where I am" and "what I am
   pointing at" were the same colour on the same map — then dim cyan inside an amber
   ring (Mike: "change the white center of the selected metro to dim cyan"), and now
   amber inside a cyan ring. `#4d80c3` is the app's own-value colour (Date line,
   Analog marks/second hand, `.lv-desc`, non-playable Live rows). */
.mz-dot.cur { fill: var(--amber); stroke: #4d80c3; stroke-width: 1.6;
  vector-effect: non-scaling-stroke; }
.mz-ctl { display: inline-flex; align-items: center; gap: .15rem; margin-right: .3rem; }
.mz-ctl .mz-btn { background: transparent; border: 1px solid transparent; border-radius: 5px;
  color: var(--muted); font: inherit; font-size: .86rem; line-height: 1; padding: 0 .2rem;
  cursor: pointer; }
.mz-ctl .mz-btn:hover { color: var(--amber); border-color: var(--line); }

/* 🔎 city filter in the 📍 chip (2026-09-12) — the catalogue passed 20 metros
   and a bare nearest-first list stopped being usable. Grows on focus, so the
   topbar stays compact when it is not in use. */
.loc-find { background: transparent; border: none; border-bottom: 1px solid transparent;
  color: inherit; font: inherit; width: 4.2em; padding: 0 .1rem; }
.loc-find::placeholder { color: var(--muted); opacity: .7; }
.loc-find:focus { outline: none; width: 7em; border-bottom-color: var(--amber-dim); }
.loc-find.nomatch { color: var(--muted); border-bottom-color: var(--amber); }
