github-actions[bot] commited on
Commit
ba81ab3
·
1 Parent(s): 595055d

Deploy ddd58bf

Browse files

content-visibility was quietly shaving the top off every enzyme name

Source: https://github.com/WINTER4000/turingDNA/commit/ddd58bf0a34a50b432f11284b3eac7f91a168ceb

dee/static/app.css CHANGED
@@ -8103,16 +8103,40 @@ body[data-ui="bench"] #navTuring { display: none; }
8103
  .seqed-line .seqed-bases { position: relative; display: inline-block; }
8104
  .seqed-line .seqed-bases[style*="--w"] { width: calc(var(--w) * 1ch); }
8105
 
8106
- /* Cut sites, above the strand. The tick is the truth; the label just names it. */
8107
- .seqed-cut { height: 15px; position: relative; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8108
  .seqcut { position: absolute; bottom: 0; white-space: nowrap; }
8109
  .seqcut-tick {
8110
  display: block; width: 1px; height: 7px; margin-left: 0;
8111
  background: var(--ink-soft);
8112
  }
8113
  .seqcut b {
8114
- position: absolute; bottom: 6px; left: 0;
8115
  font-family: var(--font-ui); font-size: 9.5px; font-weight: 500;
 
8116
  letter-spacing: .02em; color: var(--ink-soft); transform: translateX(-1px);
8117
  }
8118
 
 
8103
  .seqed-line .seqed-bases { position: relative; display: inline-block; }
8104
  .seqed-line .seqed-bases[style*="--w"] { width: calc(var(--w) * 1ch); }
8105
 
8106
+ /* Cut sites, above the strand. The tick is the truth; the label just names it.
8107
+ The row must be TALL ENOUGH TO CONTAIN ITS OWN LABEL. `.seqed-line` carries
8108
+ `content-visibility: auto`, which applies paint containment — so anything a
8109
+ line paints outside its own box is clipped, silently. At `height: 15px` the
8110
+ label (16.1px tall at the default line-height, sitting at `bottom: 6px`)
8111
+ started 7.2px above the row's top edge and had that much shaved off the top
8112
+ of every enzyme name. Verified by hit-test, not by eye: a point inside the
8113
+ label but above the row returned the ancestor div with content-visibility
8114
+ on, and the <b> with it off.
8115
+ Two changes keep it inside: `line-height: 1` (a one-line 9.5px label has no
8116
+ use for a 1.7 line box) and a row tall enough for tick + label. Cheaper
8117
+ than exempting these rows from content-visibility, which would cost the
8118
+ repaint win that rule was added for. */
8119
+ .seqed-cut { height: 18px; position: relative; }
8120
+ /* The label's containing block is `.seqed-bases`, NOT the row — it has to be,
8121
+ because `left: Nch` is measured from the bases origin and that is what keeps
8122
+ a tick on its own base. In a cut row that span holds only absolutely
8123
+ positioned children, so it is zero-height, and as an inline-block its bottom
8124
+ lands on the line box's BASELINE — leaving a font-dependent descender gap
8125
+ (3px here) between it and the row's bottom edge. Every label rode that gap
8126
+ upward and out of the paint-contained row.
8127
+ `vertical-align: bottom` pins the anchor to the row's bottom edge instead,
8128
+ so the label's clearance is arithmetic rather than a property of whatever
8129
+ font happens to load. */
8130
+ .seqed-cut .seqed-bases { vertical-align: bottom; }
8131
  .seqcut { position: absolute; bottom: 0; white-space: nowrap; }
8132
  .seqcut-tick {
8133
  display: block; width: 1px; height: 7px; margin-left: 0;
8134
  background: var(--ink-soft);
8135
  }
8136
  .seqcut b {
8137
+ position: absolute; bottom: 7px; left: 0;
8138
  font-family: var(--font-ui); font-size: 9.5px; font-weight: 500;
8139
+ line-height: 1;
8140
  letter-spacing: .02em; color: var(--ink-soft); transform: translateX(-1px);
8141
  }
8142
 
dee/static/index.html CHANGED
@@ -112,7 +112,7 @@
112
  <!-- ?v= query bumps invalidate browser + iframe asset caches when app.css /
113
  app.js change. Bump these numbers whenever you ship a frontend update —
114
  without them, users keep getting the stale file for up to a week. -->
115
- <link rel="stylesheet" href="/static/app.css?v=20260824-cuts" />
116
  <!-- The work catalog + the draggable rail. Kept out of app.css so two new
117
  self-contained surfaces stay reviewable; every colour is an app.css
118
  token, so both themes work with nothing added. -->
@@ -3132,9 +3132,9 @@
3132
  <!-- Cloning reference data must load before app.js so the Designer
3133
  can read VECTORS / ENZYMES / CLONING_METHODS / TAGS / LINKERS. -->
3134
  <script src="/static/cloning_db.js?v=20260530-ui-polish" defer></script>
3135
- <script src="/static/context.js?v=20260824-cuts" defer></script>
3136
- <script src="/static/lineage.js?v=20260824-cuts" defer></script>
3137
- <script src="/static/app.js?v=20260824-cuts" defer></script>
3138
  <!-- The decision trace, BEFORE cockpit.js: applyEvent calls TDTrace.push
3139
  on the very first event, and both are `defer`, so document order is
3140
  load order. Loading it after would drop the opening events of a
@@ -3143,7 +3143,7 @@
3143
  <!-- THE COCKPIT — the persistent orchestrator rail. Loads after app.js so
3144
  TDBench/TDStructure exist when a tool result asks the workspace to
3145
  render something. This is the only conversation surface in the app. -->
3146
- <script src="/static/cockpit.js?v=20260824-cuts" defer></script>
3147
  <!-- structcard before catalog: the catalog calls TDStructCard.observe as
3148
  soon as it paints. Both are defer, so document order is load order. -->
3149
  <script src="/static/structcard.js?v=20260811-buildC" defer></script>
 
112
  <!-- ?v= query bumps invalidate browser + iframe asset caches when app.css /
113
  app.js change. Bump these numbers whenever you ship a frontend update —
114
  without them, users keep getting the stale file for up to a week. -->
115
+ <link rel="stylesheet" href="/static/app.css?v=20260824-cuts3" />
116
  <!-- The work catalog + the draggable rail. Kept out of app.css so two new
117
  self-contained surfaces stay reviewable; every colour is an app.css
118
  token, so both themes work with nothing added. -->
 
3132
  <!-- Cloning reference data must load before app.js so the Designer
3133
  can read VECTORS / ENZYMES / CLONING_METHODS / TAGS / LINKERS. -->
3134
  <script src="/static/cloning_db.js?v=20260530-ui-polish" defer></script>
3135
+ <script src="/static/context.js?v=20260824-cuts3" defer></script>
3136
+ <script src="/static/lineage.js?v=20260824-cuts3" defer></script>
3137
+ <script src="/static/app.js?v=20260824-cuts3" defer></script>
3138
  <!-- The decision trace, BEFORE cockpit.js: applyEvent calls TDTrace.push
3139
  on the very first event, and both are `defer`, so document order is
3140
  load order. Loading it after would drop the opening events of a
 
3143
  <!-- THE COCKPIT — the persistent orchestrator rail. Loads after app.js so
3144
  TDBench/TDStructure exist when a tool result asks the workspace to
3145
  render something. This is the only conversation surface in the app. -->
3146
+ <script src="/static/cockpit.js?v=20260824-cuts3" defer></script>
3147
  <!-- structcard before catalog: the catalog calls TDStructCard.observe as
3148
  soon as it paints. Both are defer, so document order is load order. -->
3149
  <script src="/static/structcard.js?v=20260811-buildC" defer></script>
tests/test_plasmid_editor_ui.py CHANGED
@@ -491,3 +491,58 @@ def test_the_control_strip_has_one_height():
491
  css = _code(_read(_APP_CSS))
492
  assert re.search(r"\.pe-focus \.seqtool-find \{[^}]*height: var\(--pe-ctl-h\)", css, re.S), \
493
  "the find group is off the shared control height again"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  css = _code(_read(_APP_CSS))
492
  assert re.search(r"\.pe-focus \.seqtool-find \{[^}]*height: var\(--pe-ctl-h\)", css, re.S), \
493
  "the find group is off the shared control height again"
494
+
495
+
496
+ def test_a_cut_row_is_tall_enough_to_paint_its_own_enzyme_name():
497
+ """`.seqed-line` carries `content-visibility: auto`, which applies paint
498
+ containment — anything a line paints outside its own box is CLIPPED, with
499
+ no warning and no layout change to notice it by.
500
+
501
+ The enzyme label is absolutely positioned inside that line, so the row has
502
+ to be tall enough to hold it. It was not: a 16.1px label (9.5px text at the
503
+ default line-height) sitting at `bottom: 6px` needed 22.1px inside a 15px
504
+ row, and the top 7.2px of every name on the map was shaved off. Confirmed
505
+ by hit-test at the time — a point inside the label but above the row
506
+ returned the ancestor div with content-visibility on, and the <b> with it
507
+ off.
508
+
509
+ So this asserts the ARITHMETIC that keeps it inside, which is the thing
510
+ that actually has to hold. A future tweak to the font size, the offset or
511
+ the row height fails here rather than silently cropping the label again.
512
+ """
513
+ css = _read(_APP_CSS)
514
+
515
+ row = _rule_bodies(css, r"\.seqed-cut")
516
+ assert row, ".seqed-cut rule is gone"
517
+ row_h = re.search(r"height:\s*([\d.]+)px", row[0])
518
+ assert row_h, ".seqed-cut lost its explicit height"
519
+
520
+ label = _rule_bodies(css, r"\.seqcut b")
521
+ assert label, ".seqcut b rule is gone"
522
+ body = label[0]
523
+ bottom = re.search(r"bottom:\s*([\d.]+)px", body)
524
+ size = re.search(r"font-size:\s*([\d.]+)px", body)
525
+ assert bottom and size, ".seqcut b lost its offset or its size"
526
+
527
+ # A one-line label with `line-height: 1` is exactly font-size tall. Without
528
+ # that declaration the used line box is ~1.7x, which is what overflowed.
529
+ assert re.search(r"line-height:\s*1\b", body), (
530
+ ".seqcut b needs line-height: 1 — the default line box is ~1.7x the "
531
+ "font size and pushes the label out of the paint-contained row"
532
+ )
533
+ needed = float(bottom.group(1)) + float(size.group(1))
534
+ assert float(row_h.group(1)) >= needed, (
535
+ f".seqed-cut is {row_h.group(1)}px but the label needs {needed}px "
536
+ f"(bottom {bottom.group(1)}px + {size.group(1)}px of text). The top of "
537
+ f"every enzyme name will be clipped by content-visibility."
538
+ )
539
+
540
+ # The label's containing block is `.seqed-bases`, which is a zero-height
541
+ # inline-block in a cut row. Left on the baseline it sits a font-dependent
542
+ # descender gap above the row's bottom edge, and the arithmetic above stops
543
+ # being true. Pinning it to the bottom is what makes the sum reliable.
544
+ anchor = _rule_bodies(css, r"\.seqed-cut \.seqed-bases")
545
+ assert anchor and "vertical-align: bottom" in anchor[0], (
546
+ ".seqed-cut .seqed-bases must be vertical-align: bottom, or the label "
547
+ "floats up by however much descender space the font happens to have"
548
+ )