typebulb 0.11.0 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
2
- <div id="app"></div>
1
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
2
+ <div id="app"></div>
@@ -549,6 +549,11 @@ a.server-port:hover { color: var(--accent); text-decoration: underline; }
549
549
  }
550
550
  .md table { border-collapse: collapse; }
551
551
  .md th, .md td { border: 1px solid var(--border); padding: .3rem .55rem; }
552
+ /* A faint header band breaks the grid's monotony and gives the table a head/body structure — tonal
553
+ (`--panel`, the same neutral the pills use), never a hue, so it reads as structure not opinion and
554
+ follows the host light/dark theme. The header text stays `--fg`: weight + the fill carry it, a tint
555
+ would be the opinionated bit. Left-align headers to sit with the body cells. */
556
+ .md th { background: var(--panel); font-weight: 600; text-align: left; }
552
557
 
553
558
  /* The full-lane breakout geometry, defined ONCE and shared by the two breakouts (the mermaid
554
559
  embed and a spread bulb). `100%` in --lane-ml resolves against each user's own containing block
@@ -566,7 +571,10 @@ a.server-port:hover { color: var(--accent); text-decoration: underline; }
566
571
  mermaid SVG is transparent so a bg backs it, the bulb iframe is opaque so it occludes the stripe. */
567
572
  .md .mermaid {
568
573
  width: var(--lane-w);
569
- margin: .6rem 0;
574
+ /* Vertical gap must be >= the box-shadow spread (1rem below): a smaller gap lets the bg ring
575
+ paint over the half-line of prose above/below — the trap the opaque bulb embed dodges by
576
+ having no shadow, which the transparent mermaid can't. */
577
+ margin: 1rem 0;
570
578
  margin-left: var(--lane-ml);
571
579
  margin-right: auto;
572
580
  position: relative;
@@ -596,15 +604,52 @@ a.server-port:hover { color: var(--accent); text-decoration: underline; }
596
604
  .md .svg-embed { justify-content: center; }
597
605
  .md .svg-embed svg { max-width: 100%; height: auto; }
598
606
 
607
+ /* Markdown tables: chop in-column (the `.embed` rule below) and `safe center` — a table that fits its
608
+ box centres, and one that overflows falls back to left so it scrolls from its first column rather than
609
+ clipping. Centring holds in both modes: a small in-column table sits centred in the prose column, a
610
+ spread one centred in the lane. The scroll lives on the inner `.table-scroll`, not the `.embed`
611
+ wrapper, so a horizontal scrollbar rides above the chop's bottom padding instead of flush against the
612
+ next line (a scrollbar sits at its own container's bottom edge). It's the centred flex child, capped at
613
+ the box so it shrinks-to-fit and scrolls only what overflows; `max-width:100%` + the overflow-induced
614
+ 0 min-width let it shrink below the table's natural width. `spread` widens the wrapper to the lane (the
615
+ mermaid geometry) for a table fitTableEmbeds found too wide for the column. The opaque `.embed`
616
+ padding/z-index still occludes the turn stripe the spread crosses — no box-shadow needed. */
617
+ .md .table-embed { justify-content: safe center; }
618
+ .md .table-embed .table-scroll { overflow-x: auto; max-width: 100%; }
619
+ /* max-content keeps the table at its natural (unwrapped) width so it overflows `.table-scroll` and earns
620
+ a scrollbar, rather than wrapping its cells to fit — the bar is the point, and it now rides inside the
621
+ chop padding. */
622
+ /* Two ceilings work together so a prose-heavy table neither scrolls forever nor squashes to mush:
623
+ - per-column (the cell `max-width` — in an auto-layout table every cell in a column shares one width,
624
+ so a cell cap *is* a column cap): no single column hogs; long text wraps at a readable measure.
625
+ - whole-table (`max-width: var(--lane-w)`): the table never grows past the lane, so when columns don't
626
+ all fit, the browser's auto-layout *shares* the lane among them — wrapping each to its slice rather
627
+ than scrolling. It only scrolls once even longest-word-only columns can't fit the lane (genuinely too
628
+ many columns). `width: max-content` is still the *preferred* width, so a small table stays natural
629
+ and a wide one spreads; the lane cap just bounds the worst case. The floor lever (a per-cell
630
+ `min-width`) — turn squash into scroll past some readable minimum — is deliberately left off until a
631
+ real table needs it. `word-break: normal` resets the global `.md { word-break: break-word }` (which
632
+ behaves like overflow-wrap:anywhere): left inherited, that global lets the lane cap squeeze a column
633
+ below its longest word and snap it mid-character ("status" → "statu·s"). Reset to word-boundary
634
+ wrapping so each column floors at its longest whole word and a too-tight table scrolls instead of
635
+ shattering text; a pathological no-space token (a long URL) then scrolls rather than breaking. */
636
+ .md .table-embed table { margin: 0; width: max-content; max-width: var(--lane-w); }
637
+ .md .table-embed th, .md .table-embed td { max-width: 40ch; word-break: normal; }
638
+ .md .table-embed.spread {
639
+ width: var(--lane-w);
640
+ margin-left: var(--lane-ml);
641
+ margin-right: auto;
642
+ }
643
+
599
644
  /* ````bulb```` embeds: a sandboxed nested app. createBulbFrame owns the iframe (auto-height,
600
645
  borderless). No frame of our own — like the mermaid/svg embeds, it sits in the flow rather
601
646
  than in a box, so it reads as part of the transcript; the rounded clip just tidies the corners
602
- of a bulb that paints its own background. `inline` (default) keeps it in the prose column and
647
+ of a bulb that paints its own background. `fit` (default) keeps it in the prose column and
603
648
  caps its height (below); `spread` adds full-lane breakout + spacing from the shared rule above.
604
649
  position:relative anchors the controls overlay in BOTH modes (spread re-declares it for the
605
650
  z-index lift). .err is the compile-failure fallback; .bulb-err-strip is a runtime-error strip
606
651
  under a live embed (both monospace, muted red). */
607
- /* The stripe-chop, shared by every opaque in-column visual artifact (the inline bulb and a raw
652
+ /* The stripe-chop, shared by every opaque in-column visual artifact (the fit bulb and a raw
608
653
  `svg` — each opts in by carrying `.embed`). An opaque bg over position:relative + z-index:0
609
654
  paints above .bubble::before; a -1rem left extension reaches the stripe in the gutter without a
610
655
  full breakout (padding-left:1rem keeps the content in the prose column, and the box's right edge
@@ -628,7 +673,7 @@ a.server-port:hover { color: var(--accent); text-decoration: underline; }
628
673
  /* Inline (default): cap the embed's height so a tall bulb doesn't run away down the transcript.
629
674
  Past the cap the embed scrolls internally (its own overflow, set by the host↔embed protocol —
630
675
  the iframe element can't scroll its srcdoc from out here). spread removes the cap. */
631
- .md .bulb-embed.inline iframe { max-height: 80dvh; }
676
+ .md .bulb-embed.fit iframe { max-height: 80dvh; }
632
677
  /* The frame host is a layout-less wrapper (domeleon owns the node; we parent the live iframe into
633
678
  it once) — display:contents lifts the iframe to be a flex child of .bulb-embed, so the sizing and
634
679
  spread-breakout rules target it directly, exactly as when it was appended as a direct child. The