/* The drawing's CSS, ported from the Application PoC's `oberflaeche/stil.css`
   (order 28). Every colour, gap, radius and height comes from `tokens.css`,
   every target size from the ergonomics (`--ergonomics-*`, set by the host from
   values with reason and source), every other size from the content. No box
   limit is chosen here. Only what the DRAWING needs moved: the PoC's header,
   catalog and editor tools did not.
   Class names inside block and kind trees (`tab`, `ring_button`, `block-*`,
   ...) are the FORMAT of those trees and keep the PoC's names; the host's own
   names are English. */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--plait-color-bg);
  color: var(--plait-color-text);
  font-family: var(--plait-type-ui-family);
  font-size: var(--plait-type-body-size);
  /* as Crew (@plait/ui-web `.plait-scope`, plait-platform-0160): the suit's body weight (Gold: light 300), so running text
     and the composer's placeholder are as thin as in the Hub; held by tests/crew-look.test.ts */
  font-weight: var(--plait-type-body-weight);
  line-height: var(--plait-type-body-line-height);
}

/* Order 33 step 8b: a choice (select) wears the suit like every other control, never the browser's white list;
   its script on its ground is the pair text on surface-elevated, which suit-pairs.ts measures in every suit. */
.button, input, button, select {
  height: var(--plait-control-height);
  border-radius: var(--plait-control-radius);
  border: 1px solid var(--plait-color-border);
  background: var(--plait-color-surface-elevated);
  color: var(--plait-color-text);
  padding: 0 var(--plait-space-sm);
  font-family: inherit; font-size: var(--plait-type-label-size);
}
/* Auftrag 10 of Service Suits (owner 2026-10-26, Tyrol Dolomites: their field rounds 5px, their buttons 0px): a FIELD wears
   the suit's corner of a field (`plait.field.radius`), a button keeps the control's; the standard of both is 8px. A radio,
   a box and an input that is a button are no fields; `:where` keeps the weight of a bare `input`, so a block's own rule wins. */
input:where(:not([type="radio"], [type="checkbox"], [type="button"], [type="submit"], [type="reset"])), select { border-radius: var(--plait-field-radius, var(--plait-control-radius)); }
option { background: var(--plait-color-surface-elevated); color: var(--plait-color-text); }
/* Auftrag 10 of Service Suits (owner 2026-10-26, Tyrol Dolomites: their h1 is Georgia): a heading a block or the carrier
   draws (`text` title, `form` heading and group, `markdown`, `flow`, a dialog's title) is set in the suit's face of a
   heading (`plait.type.heading.family`, suites.css); the standard is the interface's own stack. */
h1, h2, h3, h4 { font-family: var(--plait-type-heading-family, inherit); }
/* Auftrag 16 of Service Suits (owner 2026-11-01, Tyrol Dolomites: "da ist auf der webseite fast nichts in dieser serifen
   schrift. in der application fast allles.", then "1: ja"): the LARGE title that heads a page (h1) is set in the suit's face
   of a large title (`plait.type.display.family`, suites.css), h2 to h4 keep the heading's; the standard of the large title
   is the heading's own value, and a carrier without the new value draws the heading's. */
h1 { font-family: var(--plait-type-display-family, var(--plait-type-heading-family, inherit)); }
/* Auftrag 13 of Service Suits (owner 2026-10-27, Tyrol Dolomites: their labels are Montserrat over an interface in Inter):
   a LABEL a block or the carrier draws (the name of a field, a toggle's label, a group's name in a list, a setting's and an
   axis's name) is set in the suit's face of a label (`plait.type.label.family`, suites.css); a tab, a segment and a ring
   button read it in their own rule. The standard is the interface's own stack, so no other suite changes. */
.block-form .field_name, .block-toggle .label, .block-media-list .media-group, .carrier-settings-name, .hand-axis-name { font-family: var(--plait-type-label-family, inherit); }
/* Auftrag 35: a radio and a box are marks, not fields: their own size (never the height of a control), grown with
   the window step like the type beside them, in the accent, and drawn by the browser in the suit's scheme instead
   of white on a dark page. */
input[type="radio"], input[type="checkbox"] {
  height: auto; margin: 0; padding: 0; flex: none; zoom: var(--plait-step-scale);
  border: 0; background: none; accent-color: var(--plait-color-accent);
}
:root { color-scheme: light dark; }
:root[data-topic="gold-dark"], .stage-frame[data-topic="gold-dark"], :root[data-topic="dark"], .stage-frame[data-topic="dark"], :root[data-topic="one-dark"], .stage-frame[data-topic="one-dark"] { color-scheme: dark; }
:root[data-topic="gold-light"], .stage-frame[data-topic="gold-light"], :root[data-topic="light"], .stage-frame[data-topic="light"], :root[data-topic="one-light"], .stage-frame[data-topic="one-light"] { color-scheme: light; }
button { cursor: pointer; }
button:hover { border-color: var(--plait-color-accent); }
:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* 🔴 Auftrag AA (owner 2026-10-07 at the S25: "Blauer rand beim fokus auf suchfeld ist kacke"): a field one TYPES into
   shows its focus by its OWN edge, made lighter (the text tone of the suit), never by a second frame around it: the
   ring above stood 2px outside the field's own border, in dark-blue in the accent's blue, a double frame. A field
   matches :focus-visible whenever it holds the focus (by key and by finger alike; the caret says it too), so the
   keyboard still sees where it is (WCAG 2.4.7). The edge stands 3 to 1 against the resting edge and on every ground,
   measured per suit (suit-pairs.ts). It is 1px on purpose (the owner: quiet), so it does NOT claim the larger area of
   WCAG 2.4.13. The outline stays, TRANSPARENT: in forced colours (Windows high contrast) the system paints it, so the
   focus is never lost there. Every other control keeps the ring: there it only shows to the keyboard. */
textarea:focus-visible,
input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="file"]):not([type="color"]):focus-visible {
  outline: 2px solid transparent; outline-offset: 0; border-color: var(--plait-color-text);
}
/* 🔴 Auftrag 20 of Service Suits (owner 2026-11-02, the contact window of the video 1CDjK37a7vQ: "baue alle diese effekte in
   PLAIT nach … globale effekte."): the GLOW of the field one types into, a suite value (`plait.field.focus.glow`, standard
   `off`, so every suite looks as before). `on` lays a soft halo `glow-reach` wide around the field in the suite's accent, beside
   its lighter edge, never instead of it, never a second frame. Read by a style query: a value that is no `on` (or an engine
   without style queries) is `off`. */
@container style(--plait-field-focus-glow: on) {
  textarea, input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="file"]):not([type="color"]) {
    transition: box-shadow var(--field-motion, var(--plait-motion-quick)) var(--plait-motion-ease), border-color var(--field-motion, var(--plait-motion-quick)) var(--plait-motion-ease);
  }
  textarea:focus-visible,
  input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="file"]):not([type="color"]):focus-visible {
    box-shadow: 0 0 var(--plait-field-focus-glow-reach) var(--plait-color-accent-glow);
  }
}
/* the NAME of a field may wander (`plait.field.label.mode`, standard `above`: the name stands small above the field, as ever).
   `float` lets it rest INSIDE the empty field in its own colour and slide up to its place above when the field is touched or
   holds a value; it stays the real <label>'s text all the time (it is only moved, never replaced), so a screen reader and a
   tap on it work as before. Only a field that SAYS it is empty (`:placeholder-shown`; the blocks give a text field a
   placeholder of one space) lets its name rest inside, so a value is never covered; a choice always shows a value and keeps
   its name above. Only where the name stands above its field in a column (form, value check) and the field follows it at
   once; where a name stands beside its field (picture tap, model parts) nothing wanders. Reduced motion or effects off: it
   jumps, without moving. */
@container style(--plait-field-label-mode: float) {
  :is(.block-form, .block-value-check) .field > .field_name {
    transition: translate var(--field-motion, var(--plait-motion-quick)) var(--plait-motion-ease);
  }
  :is(.block-form, .block-value-check) .field:has(> .field_name + :is(input, textarea).field_value:placeholder-shown:not(:focus)) > .field_name {
    translate: var(--plait-space-sm) calc(50% + var(--plait-space-xs) + var(--plait-control-height) / 2);
    pointer-events: none;
  }
}
/* reduced motion or effects off: the field's name jumps and its glow comes without moving (`--field-motion`, the time both use) */
@media (prefers-reduced-motion: reduce) { :root { --field-motion: 0s; } }
:root[data-plait-effects="off"] { --field-motion: 0s; }
button[disabled] { opacity: var(--plait-opacity-disabled); cursor: not-allowed; }

/* The levels. */
.level { display: flex; gap: var(--plait-space-sm); padding: var(--plait-space-sm) var(--plait-space-md); }
.level[data-empty="yes"] { display: none; }
.level[data-level="1"] { padding-top: var(--plait-space-md); }
.level[data-level="2"] { padding-top: var(--plait-space-tabs-stack); }
.level[data-level="3"] { padding-top: var(--plait-space-tabs-stack); padding-bottom: var(--plait-space-tabs-content); }

/* The kinds of the switcher. */
.variant { display: flex; gap: var(--plait-space-sm); flex-wrap: wrap; }
.tab, .segment, .ring_button {
  height: var(--plait-control-height);
  border-radius: var(--plait-control-radius);
  border: 1px solid var(--plait-color-border);
  background: transparent; color: var(--plait-color-text-muted);
  padding: 0 var(--plait-space-md); cursor: pointer;
  font-family: var(--plait-type-label-family, inherit); font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight);
}
.tab.active, .segment.active, .ring_button.active {
  color: var(--plait-color-on-accent); background: var(--plait-color-accent); border-color: var(--plait-color-accent);
}
/* Auftrag 38d (c): a row of tabs as its suit lays it: the PLAIT suits keep the framed tab and the filled active one, a
   suit may lay them as words with a line under the active one (clean-04: "keine bunten Pillen") */
.tab { border-color: var(--plait-tab-edge); transition: color var(--plait-motion-quick) var(--plait-motion-ease); }
.tab.active { color: var(--plait-tab-active-text); background: var(--plait-tab-active-ground); border-color: var(--plait-tab-active-edge); box-shadow: var(--plait-tab-active-mark); }
/* Owner 2026-10-20 (PLAIT Sketch in Gold: "Oben statt der Buttons sollen Tabs sein (die gleichen wie aktuell in Crew)"):
   how a row of tabs RUNS and how a tab is SET are the suit's too. Without a suit's say every value below is the look
   above (a row that wraps, framed tabs in the label size); the GOLD suits lay the row as PLAIT Crew's tab strip
   (@plait/mount `.plait-mount-tabs`, ui-web underline tabs in Gold's `GOLD_B`): one line that scrolls sideways in
   itself, a rule under it, words in spaced capitals and the active one marked by the accent's hairline. */
.level:has(> .variant.tab_row) { border-bottom: var(--plait-tab-row-rule, 0 solid transparent); }
.variant.tab_row { flex-wrap: var(--plait-tab-row-wrap, wrap); overflow-x: var(--plait-tab-row-overflow, visible); scrollbar-width: none; min-width: 0; }
.variant.tab_row::-webkit-scrollbar { display: none; }
.variant.tab_row > .tab {
  flex-shrink: var(--plait-tab-shrink, 1);
  border-radius: var(--plait-tab-radius, var(--plait-control-radius));
  padding: 0 var(--plait-tab-inset, var(--plait-space-md));
  font-size: var(--plait-tab-size, var(--plait-type-label-size));
  text-transform: var(--plait-tab-case, none);
  letter-spacing: var(--plait-tab-tracking, normal);
  white-space: var(--plait-tab-space, normal);
}
.variant.tab_row > .tab:hover { border-color: var(--plait-tab-hover-edge, var(--plait-color-accent)); }
.variant.tab_row > .tab.active:hover { border-color: var(--plait-tab-active-edge); }
/* Owner 2026-10-18 („one ist immer noch unstrukturiert“): where a tab row stands on a tab row (PLAIT One: the groups on
   level 1, their surfaces on level 2), level 1 fills the width as one bar and level 2 reads as words below it, the active
   one underlined, so the eye sees which row is the group and which the page. A bar at the bottom (PLAIT Music) is untouched. */
.level[data-level="1"]:has(> .variant.tab_row) ~ .level[data-level="2"] { padding-top: var(--plait-space-xs); border-bottom: 1px solid var(--plait-color-border); }
.level[data-level="1"]:has(~ .level[data-level="2"]:not([data-empty="yes"])) > .variant.tab_row { width: 100%; }
.level[data-level="1"]:has(~ .level[data-level="2"]:not([data-empty="yes"])) > .variant.tab_row > .tab { flex: 1 1 auto; padding: 0 var(--plait-space-xs); }
.level[data-level="1"]:has(> .variant.tab_row) ~ .level[data-level="2"] .tab {
  height: auto; padding: var(--plait-space-xs) var(--plait-space-sm); border: 0; border-bottom: 2px solid transparent; border-radius: 0;
  background: transparent; box-shadow: none; color: var(--plait-color-text-muted);
}
.level[data-level="1"]:has(> .variant.tab_row) ~ .level[data-level="2"] .tab.active { color: var(--plait-color-text); border-bottom-color: var(--plait-color-accent); }
.segmented { gap: 0; }
.segmented .segment { border-radius: 0; border-left-width: 0; }
.segmented .segment:first-child { border-left-width: 1px; border-radius: var(--plait-control-radius) 0 0 var(--plait-control-radius); }
.segmented .segment:last-child { border-radius: 0 var(--plait-control-radius) var(--plait-control-radius) 0; }
.choice_field {
  height: var(--plait-control-height);
  border-radius: var(--plait-control-radius);
  border: 1px solid var(--plait-color-border);
  background: var(--plait-color-surface-elevated);
  color: var(--plait-color-text);
  padding: 0 var(--plait-space-sm);
  font-family: inherit; font-size: var(--plait-type-label-size);
}

/* 🔴 THE DIAMETER FOLLOWS. A ring carries N entries on its CIRCUMFERENCE: the
   circumference needed is N times the widest entry, the diameter that over pi.
   Computed in the kind, measured by the host; `--ring-diameter` comes from there. */
/* The RADIUS on which the ring's buttons stand: a number the PoC CHOSE (84px),
   named here in ONE place instead of standing twice inside a transform (order
   28b, finding 12 of order 28). Deriving it from the measured diameter is open. */
.ring_menu { --ring-radius: 84px; position: relative; height: var(--ring-diameter); width: var(--ring-diameter); }
/* 🔴 TWO SIZES: the VISIBLE one follows the ring's geometry, the TARGET size is
   what the finger must hit and may be larger. A hitbox is not the graphic. */
.ring_menu .ring_button {
  min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size);
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%) translate(calc(var(--ring-x) * var(--ring-radius)), calc(var(--ring-y) * var(--ring-radius)));
}

/* The area and its pieces. */
.area { display: grid; gap: var(--plait-space-md); padding: var(--plait-space-md); }
/* Auftrag 34c (G7): the head of the application, above the area of level 1 on every area; as tall as it needs, never more */
.head { display: grid; gap: var(--plait-space-md); padding: var(--plait-space-md) var(--plait-space-md) 0; }
.head[data-empty="yes"] { display: none; }
/* anzug-je-organisation Etappe 4: the organisation's row at the top of the root, one base for every screen: the logo as tall as
   two icons and as wide as it is, the word mark in the title's script; both in the suit's own colours, never a colour of their own */
.brand { display: flex; align-items: center; gap: var(--plait-space-sm); padding: var(--plait-space-sm) var(--plait-space-md) 0; color: var(--plait-color-text); }
.brand-logo { display: block; height: calc(var(--plait-size-icon) * 2); width: auto; max-width: 50%; }
.brand-wordmark { font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Auftrag 09.10. (C): a head whose every piece is folded (the name the portal already shows) takes no room */
.head[data-folded="yes"] { display: none; }
/* owner 2026-10-31 (render/way-back.ts, "Was soll dieser viereckige kantige button da?"): the way back of an opened area, a round
   sign and the name it leads to, quiet above the area; a finger target, never a box. Tokens only. */
.way-back { display: flex; padding: var(--plait-space-sm) var(--plait-space-md) 0; }
.way-back[data-empty="yes"] { display: none; }
.way-back-button { display: inline-flex; align-items: center; gap: var(--plait-space-xs); min-height: var(--ergonomics-target-size);
  padding: 0 var(--plait-space-md) 0 0; border: 0; border-radius: 999px; background: transparent; color: var(--plait-color-text-muted);
  font: inherit; font-size: var(--plait-type-label-size); cursor: pointer; }
.way-back-sign { display: inline-flex; align-items: center; justify-content: center; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size);
  border-radius: var(--plait-radius-symbol-button, 999px); }
.way-back-sign svg { width: var(--plait-size-icon); height: var(--plait-size-icon); fill: currentColor; }
.way-back-button:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
@media (hover: hover) { .way-back-button:hover { color: var(--plait-color-text); } }
.area[data-arrangement="side-by-side"] { grid-template-columns: 1fr 1fr; }

.piece {
  container-type: inline-size;
  /* Auftrag 38a: the ground and rim of a field are the suit's own (the PLAIT suits keep the card, dark-blue lays it flat);
     owner 2026-10-20: the Gold suits lay it flat too, no ground, no rim, no corner, no air inside (the block below) */
  background: var(--plait-piece-ground, var(--plait-color-piece));
  border: 1px solid var(--plait-piece-rim, var(--plait-color-piece-edge));
  border-radius: var(--plait-piece-radius, var(--plait-radius-md));
  padding: var(--plait-piece-padding);
}
/* plait-platform-0158 (owner 2026-10-09, PLAIT ChatAI): an entry the SURFACE lays flat (`settings.ground: "flat"`)
   stands on the page without the suit's card; what it holds sits in the middle of its cell's height. */
.piece[data-ground="flat"] { background: transparent; border-color: transparent; padding: 0; display: flex; flex-direction: column; justify-content: center; }
/* owner 2026-10-31 (PLAIT Pixel: "den hintergrund des arbeitsbereiches sehen. dieses karomuster. sonst absolut gar nichts."):
   the block work area (platform/blocks/01a193ed-11d2-7db5-a556-3d24fd4161f7) is ONE element filling its piece edge to edge,
   the checkerboard exactly as the owner chose it on 2026-10-23 ("Exakt so will ich den Hintergrund haben"), its two tones
   the suit's tokens; no margin, no padding, no border of its own */
.block-work-area { flex: 1 1 auto; align-self: stretch; width: 100%; margin: 0; padding: 0; border: 0;
  background: repeating-conic-gradient(var(--plait-color-checker-a) 0% 25%, var(--plait-color-checker-b) 0% 50%) 50% / 12px 12px; }
/* its piece keeps no rim and no air either, so the checkerboard reaches the area's edges */
.piece:has(> .block-work-area) { border-width: 0; padding: 0; }
/* Auftrag 35 (A6): the heading of a field is READ, not decorated: the full text colour, the label weight, as written
   (no capitals spaced apart in grey, which the owner's picture showed as the loudest and least legible line). */
.piece > h3 {
  margin: 0 0 var(--plait-space-sm);
  font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight);
  color: var(--plait-color-text);
}

/* States. Broken and empty are VISIBLE: a hole looks like a hidden entry, and
   nobody should have to guess the difference. */
.state { margin: 0; padding: var(--plait-space-sm) 0; font-size: var(--plait-type-caption-size); }
.state.broken { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.state.empty { color: var(--plait-color-text-muted); }
.state.carrier { color: var(--plait-color-text-muted); }
.state.too-old { color: var(--plait-color-warn); font-size: var(--plait-type-body-size); }
.state.only-in-app { font-size: var(--plait-type-body-size); }
/* E30 · the notice of a denial. Its colour comes from the token the runtime
   NAMES (`--notice-tone`, set on the element); the fallback keeps a missing
   token from making the text invisible. */
.denied { color: var(--notice-tone, var(--plait-color-text-muted)); font-size: var(--plait-type-caption-size); padding: var(--plait-space-md); }
/* E38 · the denied cell: frame and text in the tone of the notice, never in
   the tone of "not available" (duty 4: two situations, two pictures). */
.piece[data-state="denied"] { box-sizing: border-box; overflow: hidden; border-color: var(--plait-color-info); border-style: dashed; }
.state.denied-entry { color: var(--plait-color-info); }
.piece[data-state="broken"] { border-color: var(--plait-color-danger); }
.not-saved { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-danger-text, var(--plait-color-danger)); }

/* Boxes in boxes. Every box and every cell lies where the rule puts it; nothing
   flows. What holds more than is visible SCROLLS, and nothing is cut off (§4, E8).
   🔴 Teil W (owner 2026-10-07, "Warum all diese scrollbars?"): a box or a cell does NOT roll by itself. A box rolls
   where the rule says it holds more than its length (`data-scrolls`); a cell sized by its CONTENT never, unless what
   it holds is really larger than its room (a `max`: `data-holds-more`, ./render/layout.ts `markHoldsMore`); a box
   or cell that a rounding outgrew carried a scroll bar of its own before, each. */
.layout { position: relative; width: 100%; }
.layout .box { position: absolute; box-sizing: border-box; }
.layout .cell { position: absolute; box-sizing: border-box; }
.layout .box[data-scrolls="yes"][data-cut="stacked"] { overflow-y: auto; }
.layout .box[data-scrolls="yes"][data-cut="side_by_side"] { overflow-x: auto; }
/* a cell whose size the RULE gives (fixed, share, group) holds whatever comes and rolls when more comes (E8), from
   the start: a bar that came later took its width from what was already laid (the editor's stage) */
.layout .cell:not([data-size="content"]) { overflow: auto; }
.layout .cell[data-holds-more="height"] { overflow-y: auto; }
.layout .cell[data-holds-more="width"] { overflow-x: auto; }
.layout .cell[data-holds-more="both"] { overflow: auto; }
/* a row that rolls sideways by declaration (G6) rolls under the thumb, without a bar of its own on a phone */
@media (pointer: coarse) { .layout .box[data-rolls="yes"][data-cut="side_by_side"] { scrollbar-width: none; } }
.layout .cell > .piece { margin: 0; box-sizing: border-box; min-height: 100%; }
.layout-measuring { position: absolute; visibility: hidden; left: 0; top: 0; }
/* ── layers and views (owner 2026-10-17 through Planner Metric; ./render/layers.ts, @plait/surface overlay.ts and views.ts).
   For EVERY entry and every block: no block is named in this section (`tests/layers-no-block.test.ts` reads it).
   An entry over another lies above it (z-index; no element moves, so the keyboard's order stays the entries'). Its EMPTY
   places let a tap and a mouse through to the entry below; only its controls take them. Its ground: transparent (no
   surface; every glyph keeps a halo of the page's ground, so the text stands on the pair text/ground the suit already
   holds to E7), glass (the suit's glass, the foot's ground), solid (the suit's card, as any piece). */
.layout .cell[data-layer="lower"] { z-index: 1; }
.layout .cell[data-layer="upper"] { z-index: 2; pointer-events: none; }
.layout .cell[data-layer="upper"] :is(button, a[href], input, select, textarea, summary, label, [tabindex], [role="button"], [contenteditable="true"]) { pointer-events: auto; } /* layers: controls */
.layout .cell[data-overlay-ground="transparent"] > .piece { background: transparent; border-color: transparent; box-shadow: none;
  text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-sm) var(--plait-color-bg); }
.layout .cell[data-overlay-ground="glass"] > .piece { background: var(--plait-foot-ground); backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass); }
/* the switch of a view: beside the title, a finger's target */
.piece > .view-switches { display: flex; justify-content: flex-end; gap: var(--plait-space-xs); }
.view-switch { min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
/* ── end of layers and views */
/* Measured WITHOUT the size containment of a piece: `container-type: inline-size`
   makes the width a piece takes from its content zero, so every cell sized by
   its content got only its minimum (measured: the date fields of the time
   report, 44 pixels, their input 121). */
.layout-measuring > .piece { margin: 0; box-sizing: border-box; container-type: normal; }
.overlay { position: fixed; z-index: 10; padding: var(--plait-space-sm);
  background: var(--plait-color-surface); color: var(--plait-color-text);
  border: 1px solid var(--plait-color-info); border-radius: var(--plait-radius-sm); }
[data-overlay] { cursor: pointer; }

/* The blocks. Class names are the blocks' own (their tree is the format). */
.block-list { margin: 0; padding-left: var(--plait-space-lg); }
.block-list .empty { color: var(--plait-color-text-muted); }
.block-text { margin: 0; }
/* Auftrag 38b: the field a text is written into (the composer), in the suit like every control: the whole width,
   the ui font, never the browser's own handle to resize it */
.block-composer {
  display: block; width: 100%; height: auto; min-height: var(--plait-control-height); margin: 0; resize: none;
  border-radius: var(--plait-control-radius); border: 1px solid var(--plait-color-border);
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text);
  padding: var(--plait-space-sm); font-family: inherit; font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
/* 🔴 `table-layout: auto` with a minimum per column tells the truth about how
   narrow a table may become; `fixed` would claim any width is enough. */
.block-table { width: 100%; border-collapse: collapse; table-layout: auto; }
.block-table th, .block-table td { text-align: left; padding: var(--plait-space-sm); border-bottom: 1px solid var(--plait-color-border); }
.block-table th { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); text-transform: uppercase; letter-spacing: var(--plait-type-tracking-label); }
.block-table .stack { padding: var(--plait-space-sm) 0; border-bottom: 1px solid var(--plait-color-border); }
.block-table .pair { font-size: var(--plait-type-caption-size); }
/* A WORDING cell says what kind of statement it is (order 29): a capability the
   provider only STATES must not look like one somebody MEASURED, and one nobody
   measured recedes. The difference is in the drawing, not only in the word. */
.block-table .word.capability-declared, .block-table .word.context-declared-by-provider, .block-table .word.context-declared-by-caller { font-style: italic; }
.block-table .word.capability-unmeasured, .block-table .word.context-unmeasured { color: var(--plait-color-text-muted); }
/* ── table capabilities (owner 2026-10-17, ./render/table-capabilities.ts): drawn around EVERY table whose block declares
   capabilities, the same for every block; colours only from the suit, the accent blue, green only for ok. */
/* service-11 (owner 2026-10-20 "1: ja"): ONE column as wide as the piece's room, never as wide as the search field's own
   width; an `auto` column took that, and on a phone the tools and the table beside them stood 42 px out of their piece */
.table-capabilities { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--plait-space-xs); min-width: 0; }
.table-capabilities[aria-busy="true"] .table-scroll { opacity: var(--plait-opacity-disabled); }
.table-tools { display: flex; align-items: center; gap: var(--plait-space-xs); }
.table-search { flex: 1 1 auto; min-width: 0; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); background: var(--plait-color-surface); color: var(--plait-color-text);
  font: inherit; font-size: var(--plait-type-body-size); }
.table-spacer { flex: 1 1 auto; }
.table-tool { flex: none; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); display: inline-grid; place-items: center;
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); background: transparent; color: var(--plait-color-text); }
.table-tool svg { width: var(--plait-size-icon); height: var(--plait-size-icon); fill: currentColor; }
.table-tool[aria-expanded="true"] { border-color: var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.table-live { color: var(--plait-color-accent-text, var(--plait-color-accent)); font-size: var(--plait-type-caption-size); }
.table-tray, .table-subtray, .table-actions { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); align-items: center; }
.table-tray { padding: var(--plait-space-xs) 0; }
.table-subtray { flex-basis: 100%; }
.table-filter { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); align-items: center; flex-basis: 100%; }
.table-filter-name { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.table-chip { min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-sm); background: transparent; color: var(--plait-color-text); font: inherit; font-size: var(--plait-type-caption-size); }
.table-chip[aria-pressed="true"] { border-color: var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.table-said { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.table-said[data-said="table-failed"], .table-said[data-said="table-copy-failed"] { color: var(--plait-color-warn); }
.table-scroll { overflow-x: auto; min-width: 0; }
/* a head cell that sorts: a finger's target, the order said by its arrow (drawn from aria-sort, never a word of the code) */
.table-capabilities th[aria-sort] { cursor: pointer; }
.table-capabilities th[aria-sort="ascending"]::after { content: " \2191"; }
.table-capabilities th[aria-sort="descending"]::after { content: " \2193"; }
/* a row that may be tapped: chosen rows carry the accent, a folded long row shows two lines */
.table-capabilities [data-row][tabindex] { cursor: pointer; }
.table-capabilities [data-row][aria-selected="true"] { background: color-mix(in srgb, var(--plait-color-accent) 14%, transparent); }
.table-capabilities [data-row][aria-selected="true"] > :first-child { box-shadow: inset var(--plait-space-xs) 0 0 var(--plait-color-accent); }
.table-capabilities [data-long="folded"] [data-cell] { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.table-capabilities td[data-cell] { vertical-align: top; }
.table-yes-no { white-space: nowrap; }
.table-yes-no .table-chip { min-width: var(--ergonomics-target-size); }
.table-total td, .table-total .pair { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
.table-total td span { display: block; }
.table-chart { display: grid; gap: var(--plait-space-xs); flex-basis: 100%; }
.table-bar { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto; gap: var(--plait-space-sm); align-items: center; font-size: var(--plait-type-caption-size); }
.table-bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table-bar-track { display: block; height: var(--plait-space-sm); border-radius: var(--plait-radius-sm); border: 1px solid var(--plait-color-border); overflow: hidden; }
.table-bar-fill { display: block; height: 100%; width: calc(var(--share, 0) * 100%); background: var(--plait-color-accent); }
.table-bar-value { font-variant-numeric: tabular-nums; }
/* the full screen: the table over everything, on the suit's ground; the close button stays in its tool row */
.table-capabilities[data-full="yes"] { position: fixed; inset: 0; z-index: 40; overflow: auto; align-content: start;
  padding: var(--plait-space-md); background: var(--plait-color-bg); }
/* ── end of table capabilities */
/* plait-platform-0157 (owner 2026-10-09, PLAIT ChatAI: "UI ist schrecklich strukturiert"): a conversation as bubbles,
   the person's own on the right, an answer on the left over (almost) the whole width, the sender small above it. The
   piece around it lays no card of its own (no box in a box): the cell rolls, the bubbles are the only frames. Nothing
   runs out sideways: a long word breaks, a code block or a table rolls inside itself. Colours only from the suit. */
.piece[data-block="chat"] { display: flex; flex-direction: column; justify-content: flex-end; }
.piece[data-block="chat"] > h3:empty { display: none; }
/* the last line keeps air above the input line: it never ends under it (plait-platform-0158) */
.block-chat { display: flex; flex-direction: column; gap: var(--plait-space-md); min-width: 0; padding: var(--plait-space-xs) 0 var(--plait-space-md); }
.block-chat .message { display: flex; flex-direction: column; gap: var(--plait-space-xs); min-width: 0; max-width: 100%; }
.block-chat .message.own { align-self: flex-end; align-items: flex-end; max-width: 85%; }
.block-chat .message.foreign { align-self: stretch; align-items: flex-start; }
.block-chat[data-intrinsic="two_column"] .message.own { max-width: 70%; }
.block-chat .who { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); padding: 0 var(--plait-space-sm); overflow-wrap: anywhere; }
.block-chat .what {
  box-sizing: border-box; min-width: 0; max-width: 100%;
  padding: var(--plait-space-sm) var(--plait-space-md); border-radius: var(--plait-radius-lg);
  color: var(--plait-color-text); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
  overflow-wrap: anywhere; word-break: normal;
}
/* Owner 2026-10-19 (PLAIT Assistant as PLAIT Crew, `.chat-bubble--user` / `--assistant` of @plait/chat-ui): only the
   person's OWN post is a bubble, in the suit's material (Gold: black glass in the accent's rim); an answer is plain text
   over the whole width, no box, as Crew and the Claude app show it */
.block-chat .own .what {
  background: var(--chat-own-ground, color-mix(in srgb, var(--plait-color-accent) 28%, var(--plait-color-surface-elevated)));
  border: 1px solid var(--chat-own-rim, transparent); box-shadow: var(--chat-own-glow, none); margin-inline-end: var(--plait-space-xs);
  color: var(--chat-own-ink, inherit);
}
.block-chat .foreign .what { width: 100%; padding: 0 var(--plait-space-xs); background: transparent; border-radius: 0; }
.block-chat .what > :first-child { margin-top: 0; }
.block-chat .what > :last-child { margin-bottom: 0; }
.block-chat .md-paragraph { margin: 0 0 var(--plait-space-sm); }
.block-chat .md-title { margin: var(--plait-space-md) 0 var(--plait-space-xs); font-size: var(--plait-type-body-size); font-weight: var(--plait-type-title-weight); line-height: var(--plait-type-body-line-height); }
.block-chat .md-list { margin: 0 0 var(--plait-space-sm); padding-left: var(--plait-space-lg); }
.block-chat .md-list .md-list { margin: var(--plait-space-xs) 0 0; }
.block-chat .md-point + .md-point { margin-top: var(--plait-space-xs); }
.block-chat .md-rule { border: 0; border-top: 1px solid var(--plait-color-divider); margin: var(--plait-space-sm) 0; }
.block-chat .md-inline-code, .block-chat .md-code code { font-family: var(--plait-type-mono-family); font-size: var(--plait-type-caption-size); }
.block-chat .md-inline-code { padding: 0 var(--plait-space-xs); border-radius: var(--plait-radius-sm); background: var(--plait-color-surface); }
.block-chat .md-code { margin: 0 0 var(--plait-space-sm); padding: var(--plait-space-sm); border-radius: var(--plait-radius-sm); background: var(--plait-color-surface); overflow-x: auto; max-width: 100%; white-space: pre; overflow-wrap: normal; }
.block-chat .md-table { margin: 0 0 var(--plait-space-sm); overflow-x: auto; max-width: 100%; }
.block-chat .md-table table { border-collapse: collapse; font-size: var(--plait-type-caption-size); overflow-wrap: normal; }
.block-chat .md-table th, .block-chat .md-table td { text-align: left; padding: var(--plait-space-xs) var(--plait-space-sm); border-bottom: 1px solid var(--plait-color-divider); }
.block-chat .md-link { color: var(--plait-color-info); }
/* The card "open page" (plan seiten-als-function S5, @plait/blocks markdown-text, render/page-card.ts): a page a post
 * names is a button with its title, never its address. Tokens only; the accent is --plait-color-info, blue in every
 * suit (the same as the Hub's card, page-card.tsx), never violet. A finger target: the declared ergonomic target size
 * (44px, WCAG 2.5.5, ergonomics.json), never a number of its own here. In running text it stays inline; on a line of
 * its own it takes the width. */
.block-chat .page-card { display: inline-flex; align-items: center; gap: var(--plait-space-sm); max-width: 100%; box-sizing: border-box;
  min-height: var(--ergonomics-target-size); margin: var(--plait-space-xs) 0; padding: var(--plait-space-xs) var(--plait-space-md);
  vertical-align: middle; color: var(--plait-color-text); background: var(--plait-color-surface); border: 1px solid var(--plait-color-border);
  border-left: var(--plait-space-xs) solid var(--plait-color-info); border-radius: var(--plait-radius-md); font: inherit; text-align: left; cursor: pointer; }
.block-chat .page-card.alone { display: flex; width: 100%; }
.block-chat .page-card:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
@media (hover: hover) { .block-chat .page-card:hover { border-color: var(--plait-color-info); } }
.block-chat .page-card-icon { color: var(--plait-color-info); }
.block-chat .page-card-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.block-chat .page-card-open { flex: none; color: var(--plait-color-info); font-size: var(--plait-type-caption-size); }
/* Owner 2026-10-22 (render/page-view.ts, "Header und Tabs bleiben, der back-button im subheader"): a page opened from the
 * chat lies OVER the area and the foot, inside the carrier; head and tabs stay. Area and foot stay laid out underneath
 * (visibility, never display: a reread measures right and the chat keeps where its reader was). Tokens only. */
[data-page-view="open"] { position: relative; }
[data-page-view="open"] > .area, [data-page-view="open"] > .pages, [data-page-view="open"] > .foot { visibility: hidden; }
.page-view { z-index: 5; display: flex; flex-direction: column; box-sizing: border-box; background: var(--plait-color-bg); }
/* owner 2026-10-31 ("rechts oben ein rundes icon mit x"): no row; one round X floats at the top right over the page */
.page-view-close { position: absolute; top: var(--plait-space-sm); right: var(--plait-space-sm); z-index: 1; box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size);
  margin: 0; padding: 0; border: 1px solid var(--plait-color-border); border-radius: 50%; background: var(--plait-color-surface-elevated);
  color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised); cursor: pointer; }
.page-view-close:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.page-view-close svg { width: var(--plait-size-icon); height: var(--plait-size-icon); fill: currentColor; }
.page-view-frame { flex: 1 1 auto; min-height: 0; width: 100%; border: 0; display: block; background: var(--plait-color-bg); }
/* plait-platform-0158: an answer on its way says it quietly, one that did not come in the warning tone */
.block-chat .message.pending .what { width: auto; color: var(--plait-color-text-muted); font-style: italic; }
.block-chat .message.failed .what { border-left: var(--plait-space-xs) solid var(--plait-color-warn); padding-left: var(--plait-space-sm); }
/* 2026-10-10 (pictures in PLAIT ChatAI): a picture of a post, as wide as the bubble may be and never wider; one that is
   not shown or failed takes no room (its address stays on the element to be read) */
.block-chat .picture { display: block; max-width: 100%; height: auto; border-radius: var(--plait-radius-sm); }
.block-chat .picture:not([src]), .block-chat .picture[data-image-state="failed"] { display: none; }
/* Owner 2026-10-10 ("Darauf antworten"): the answered words above a post, the jump, the button under marked words and
   the bar above the input line (./render/quote.ts). Only the suit's tokens: the Ship suit draws them light and dark. */
.block-chat .quote { display: flex; flex-direction: column; gap: 2px; max-width: 100%; box-sizing: border-box; padding: var(--plait-space-xs) var(--plait-space-sm);
  border-left: 3px solid var(--plait-color-accent); border-radius: var(--plait-radius-sm); background: var(--plait-color-surface);
  color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); cursor: pointer; overflow-wrap: anywhere; }
.block-chat .quote .quote-text { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-style: italic; }
.block-chat .quote:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-chat .quote.lost { cursor: default; border-left-style: dashed; }
.block-chat .quote.lost .quote-text { text-decoration: line-through; }
.block-chat .quote .quote-lost { font-style: normal; color: var(--plait-color-warn); }
.block-chat .message[data-quoted="yes"] .what { outline: 2px solid var(--plait-color-accent); }
/* Owner 2026-10-22 (PLAIT Assistant wie Crew, @plait/chat-ui's `.chat-bubble__who`, `__actions`, `__tools`): the own post
   is ONE bubble holding its head (writer and moment), its words and its copy; an answer stays plain text over the width,
   its steps a quiet line above it and its copy and read-aloud under it. Tokens only; the bubble's materials are the
   suit's (`--chat-own-*`). The words themselves stay in `.what`, whose text the quote measures (./render/quote.ts). */
/* 🔴 Owner 2026-10-22 ("EXAKT so dargestellt wie aktuell in den Crew Sessions", planner-18): every value of the own bubble,
   its head and its copy row is Crew's OWN expression (@plait/chat-ui chat-block.tsx CHAT_CSS: `.chat-bubble--user`,
   `__who`, `__when`, `__actions`, `__copy`; the owner's messages carry `chat-bubble--tone-owner`, so the name is 600),
   written here word for word and held to it by tests/crew-look.test.ts: a change on Crew's side reddens it. */
.block-chat .message.own {
  box-sizing: border-box; align-items: stretch; gap: 0;
  max-width: 80%;
  padding: var(--plait-space-sm) var(--plait-space-md);
  border-radius: var(--plait-radius-lg);
  background: var(--plait-material-bubble-own, color-mix(in srgb, var(--plait-color-accent) 55%, black 45%));
  color: var(--plait-color-on-bubble-own, white);
  box-shadow: var(--plait-elevation-bubble-own, none);
  border: var(--plait-material-rim-width, 1px) solid transparent;
  position: relative;
  /* Crew's 4px of air for rim and glow, named (tests/style.test.ts); tests/crew-look.test.ts reads it back as 4px */
  --crew-bubble-air: 4px;
  margin-inline-end: calc(var(--plait-space-sm) + var(--crew-bubble-air));
}
@media (max-width: 600px) { .block-chat .message.own { max-width: 90%; } }
.block-chat .message.own .what { background: transparent; border: 0; box-shadow: none; margin: 0; padding: 0; border-radius: 0; }
.block-chat .message .head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--plait-space-xs) var(--plait-space-sm); padding: 0;
  color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* the page head (`.head`, app.ts) shares the class name; its padding must never reach a post's head */
.block-chat .message .head .author { color: var(--chat-own-ink, var(--plait-color-text)); font-weight: var(--plait-type-title-weight); }
.block-chat .message .steps { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--plait-space-xs); margin: 0; padding: 0 var(--plait-space-xs);
  color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); overflow-wrap: anywhere; }
.block-chat .message .steps .steps-icon { display: inline-flex; width: var(--plait-type-caption-size); height: var(--plait-type-caption-size); }
.block-chat .message .steps .steps-icon svg { width: 100%; height: 100%; fill: currentColor; }
.block-chat .message .steps .step[data-state="refused"], .block-chat .message .steps .step[data-state="unknown"] { color: var(--plait-color-warn); }
.block-chat .post-actions { display: flex; align-items: center; gap: var(--plait-space-xs); min-height: var(--ergonomics-target-size); }
/* as Crew (`.chat-bubble--user .chat-bubble__who`): the author in the bubble in the suit's label colour (Gold: champagne),
   and the copy row of the own bubble without a line of air of its own (the button keeps its finger size by its margin) */
.block-chat .message.own .head {
  display: flex; align-items: center; gap: var(--plait-space-xs); font-size: var(--plait-type-caption-size);
  color: var(--plait-color-on-bubble-own-label, var(--plait-color-on-bubble-own, white)); opacity: 0.9; letter-spacing: 0.04em;
}
.block-chat .message.own .head .author { color: inherit; font-weight: 600; }
.block-chat .message.own .head .when { font-weight: 300; letter-spacing: 0; opacity: 0.75; font-variant-numeric: tabular-nums; }
.block-chat .message .post-actions { display: flex; align-items: center; gap: var(--plait-space-xs); margin-top: var(--plait-space-xs); min-height: 0; }
.block-chat .message.own .post-actions { justify-content: flex-start; }
.block-chat .post-actions > button {
  display: inline-flex; align-items: center; justify-content: center; flex: none; margin: 0; cursor: pointer;
  gap: var(--plait-space-xs);
  border: none;
  background: transparent;
  color: color-mix(in srgb, var(--plait-color-accent-text, var(--plait-color-accent)) 70%, transparent);
  padding: 0 var(--plait-space-xs) 0 0;
  border-radius: var(--plait-radius-sm);
  line-height: 1;
}
.block-chat .post-actions > button[hidden] { display: none; }
.block-chat .post-actions > button .icon { display: inline-flex; width: var(--plait-size-icon, 20px); height: var(--plait-size-icon, 20px); }
.block-chat .post-actions > button svg { width: 100%; height: 100%; fill: currentColor; }
.block-chat .post-actions > button:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-chat .post-actions > button[data-copy-state="copied"], .block-chat .post-actions > button[data-speak-state="reading"] { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-chat .post-actions > button[aria-disabled="true"] { opacity: var(--plait-opacity-disabled, 0.5); cursor: default; }
.block-chat .post-said { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* Owner 2026-10-26 (Planner One: "nicht innerhalb der card nochmal eine card ... direkt bearbeitbar ... farblich oder
   effektlich hervorheben"): an own post being edited (./render/edit.ts). Its words become the field IN PLACE: no rim, no
   face, the bubble's own type and colour; the bubble itself is lifted by the suite's focus ring. Cancel and send
   are the send button's circle (the input line's values), the send with its face, the cancel without one. Tokens only. */
.block-chat .message .post-edit { display: none; }
.block-chat .message[data-editing] .post-edit, .block-chat .message:has(.post-edit:focus-within) .post-edit {
  display: flex; flex-direction: column; gap: var(--plait-space-xs);
}
.block-chat .message[data-editing] > .what, .block-chat .message:has(.post-edit:focus-within) > .what,
.block-chat .message[data-editing] > .post-actions, .block-chat .message:has(.post-edit:focus-within) > .post-actions { display: none; }
.block-chat .message.own[data-editing], .block-chat .message.own:has(.post-edit:focus-within) {
  outline: calc(2 * var(--plait-material-rim-width)) solid var(--plait-color-focus);
  outline-offset: var(--plait-material-rim-width);
  border-color: var(--plait-color-focus);
}
.block-chat .post-edit-field {
  box-sizing: border-box; width: 100%; min-width: 12rem; margin: 0; padding: 0; resize: none; overflow: hidden;
  border: 0; outline: none; background: transparent; box-shadow: none;
  color: inherit; font: inherit; line-height: inherit; overflow-wrap: anywhere;
}
.block-chat .post-edit-buttons { display: flex; justify-content: flex-end; gap: var(--plait-space-xs); }
.block-chat .post-edit-buttons > button[data-intrinsic="symbol"] {
  display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 0; cursor: pointer;
  width: var(--plait-control-height); height: var(--plait-control-height); border-radius: 50%;
  border: var(--plait-material-rim-width) solid transparent;
}
.block-chat .post-edit-buttons > button[data-intrinsic="symbol"] .icon { width: 1.15rem; height: 1.15rem; display: block; }
.block-chat .post-edit-buttons > .post-edit-send[data-intrinsic="symbol"] {
  background: var(--plait-material-send, var(--plait-color-accent));
  color: var(--plait-material-send-ink, var(--plait-color-on-accent));
  box-shadow: var(--plait-elevation-send, none);
}
.block-chat .post-edit-buttons > .post-edit-send path { stroke-width: var(--plait-material-send-stroke, 2.5); }
.block-chat .post-edit-buttons > .post-edit-cancel[data-intrinsic="symbol"] {
  background: transparent;
  color: var(--plait-material-control-mark, var(--plait-color-on-bubble-own, var(--plait-color-text-muted)));
  border: calc(2 * var(--plait-material-rim-width)) solid currentColor;
}
.block-chat .post-edit-buttons > button:focus-visible { outline: calc(2 * var(--plait-material-rim-width)) solid var(--plait-color-focus); outline-offset: calc(2 * var(--plait-material-rim-width)); }
.block-chat .post-edit-said { font-size: var(--plait-type-caption-size); color: var(--plait-color-warn); }
.block-chat .post-edit-said[data-receipt="yes"], .block-chat .post-edit-said[data-receipt=""] { display: none; }
@media (hover: hover) { .block-chat .post-actions > button:hover { color: var(--plait-color-accent-text, var(--plait-color-accent)); } }
/* Owner 2026-10-22 (./render/to-end.ts): the way to the end of a conversation, in the scroller's lower corner while the
   reader is away from the end; a holder of no height, so it moves nothing of the content (Crew's ChatScrollButton) */
.to-end { position: sticky; bottom: var(--plait-space-sm); display: flex; justify-content: flex-end; height: 0; overflow: visible; pointer-events: none; z-index: 5; }
.to-end[hidden] { display: none; }
.to-end-button {
  pointer-events: auto; transform: translateY(-100%); display: inline-flex; align-items: center; justify-content: center;
  width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); margin-inline-end: var(--plait-space-sm); padding: 0;
  border: 1px solid var(--chat-composer-rim, var(--plait-color-border)); border-radius: 50%;
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text); box-shadow: var(--plait-section-shadow, none); cursor: pointer;
}
.to-end-button svg { width: var(--plait-size-icon, 20px); height: var(--plait-size-icon, 20px); fill: currentColor; }
.to-end-button:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* Owner 2026-10-22 (./render/find.ts): the hits of a search of the drawn conversation, marked without an element of their
   own; the current one in the accent */
::highlight(plait-find) { background-color: color-mix(in srgb, var(--plait-color-accent) 28%, transparent); color: inherit; }
::highlight(plait-find-current) { background-color: color-mix(in srgb, var(--plait-color-accent) 60%, transparent); color: inherit; }
/* the input in its view `search`: the same box as the chat line, the field without a frame, the magnifier where send is */
.block-input[data-view="search"] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); box-sizing: border-box; }
.block-input[data-view="search"][data-line="yes"] { padding: var(--plait-space-xs); border: 1px solid var(--chat-composer-rim, var(--plait-color-border)); border-radius: var(--plait-radius-lg);
  background: var(--chat-composer-ground, var(--plait-color-surface)); }
.block-input[data-view="search"] > .find-field { flex: 1 1 0; min-width: 0; min-height: var(--ergonomics-target-size); box-sizing: border-box; padding: 0 var(--plait-space-sm);
  border: 0; background: transparent; color: var(--plait-color-text); font: inherit; font-size: var(--plait-type-body-size); }
.block-input[data-view="search"] > .find-field:focus-visible { outline: none; }
.block-input[data-view="search"]:has(> .find-field:focus-visible) { border-color: var(--chat-composer-focus, var(--plait-color-text)); }
.block-input[data-view="search"] > .input-buttons { display: contents; }
.block-input[data-view="search"] .find-go {
  display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 0;
  width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); border-radius: var(--plait-radius-symbol-button, 999px);
  background: var(--chat-send-ground, var(--plait-color-accent)); border: 1px solid var(--chat-send-rim, var(--plait-color-accent));
  color: var(--chat-send-ink, var(--plait-color-on-accent)); box-shadow: var(--chat-send-glow, none); cursor: pointer;
}
.block-input[data-view="search"] .find-go svg { width: var(--plait-size-icon, 20px); height: var(--plait-size-icon, 20px); fill: currentColor; }
.block-input[data-view="search"] > .find-said { flex-basis: 100%; order: 3; margin: 0; padding: 0 var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-input[data-view="search"] > .find-said:empty { display: none; }
::highlight(plait-quote) { background-color: color-mix(in srgb, var(--plait-color-accent) 45%, transparent); color: inherit; }
.reply-button { position: fixed; z-index: 30; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-md);
  border: 1px solid var(--plait-color-accent); border-radius: var(--plait-control-radius, var(--plait-radius-md));
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text); font: inherit; box-shadow: var(--plait-section-shadow, none); }
.reply-bar { position: fixed; z-index: 20; box-sizing: border-box; display: flex; align-items: center; gap: var(--plait-space-sm);
  padding: var(--plait-space-xs) var(--plait-space-sm); border-left: 3px solid var(--plait-color-accent); border-radius: var(--plait-radius-sm) var(--plait-radius-sm) 0 0;
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); box-shadow: var(--plait-section-shadow, none); }
.reply-bar[hidden] { display: none; }
.reply-bar-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-style: italic; }
.reply-bar-cancel { flex: none; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); border: 0; background: transparent; color: var(--plait-color-text); font: inherit; cursor: pointer; }
/* plait-platform-0158: a button's symbol form: the icon of the set, the old glyph only where no icon could be drawn */
.icon[data-icon-state="drawn"] + .glyph { display: none; }
.icon:not([data-icon-state="drawn"]):has(+ .glyph) { display: none; }
/* plait-platform-0158 (owner 2026-10-09, PLAIT ChatAI): the input as a chat LINE (`lines: "one"`), each button a round
   symbol a finger hits (the target size); the field grows with what is typed up to five lines and then rolls; what the
   input says after a hand-in stands under the line.
   🔴 Owner 2026-10-19 (PLAIT Assistant: "dass es so aussieht wie in PLAIT Crew"): the line is ONE composer box as Crew's
   (`.plait-composer`, @plait/ui-web styles.css): the field without a frame of its own, the paper clip and the round Send
   INSIDE the box after the field, the box's own edge says the focus. Its materials are the suit's (`--chat-*` below);
   a function strip the surface lays under it (`ground: "strip"`) is the box's lower section, see there. */
/* 🔴 Owner 2026-10-22 ("EXAKT so dargestellt wie aktuell in den Crew Sessions", planner-18): the values are Crew's own
   expressions (@plait/ui-web styles.css `.plait-composer`, `__input-row`, `__input`, `__action`, `__footer`,
   `.plait-composer-functions__cell`), word for word, held by tests/crew-look.test.ts. */
.block-input[data-line="yes"] {
  display: flex; flex-wrap: wrap; align-items: flex-end; box-sizing: border-box;
  gap: var(--plait-space-sm);
  padding: var(--plait-space-sm);
  border-radius: var(--plait-radius-lg);
  background: var(--plait-material-composer, var(--plait-color-surface));
  border: var(--plait-material-rim-width, 1px) solid var(--plait-material-composer-rim, var(--plait-color-border));
  box-shadow: var(--plait-elevation-composer, none);
  position: relative;
}
/* a line laid flat is the box itself: the flat piece keeps no transparent edge of its own around it, so the box's rim
   stands exactly on the cell's edge, where the strip below it stands too */
.piece[data-ground="flat"]:has(> .block-input[data-line="yes"]) { border-width: 0; }
.block-input[data-line="yes"] > .input-buttons { display: contents; }
.block-input[data-line="yes"] > .block-composer {
  order: 0; flex: 1 1 0; min-width: 0; width: auto; field-sizing: content; border-radius: 0;
  min-height: var(--plait-control-height);
  max-height: var(--plait-size-composer-max, 160px);
  border: none;
  background: transparent;
  color: var(--plait-color-text);
  font: inherit;
  line-height: 1.4;
  padding: var(--plait-space-xs) var(--plait-space-sm);
  overflow-y: auto;
}
.block-input[data-line="yes"] > .block-composer::placeholder { color: var(--plait-color-text-muted); }
.block-input[data-line="yes"] > .block-composer:focus-visible { outline: none; }
.block-input[data-line="yes"] > .input-buttons > * { order: 1; }
.block-input[data-line="yes"] > :not(.block-composer):not(.input-buttons) { order: 3; flex-basis: 100%; }
.block-input[data-line="yes"] button[data-intrinsic="symbol"] {
  display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 0;
  width: var(--plait-control-height);
  height: var(--plait-control-height);
  border-radius: var(--plait-radius-symbol-button, 999px);
  background: transparent; border-color: transparent; color: var(--chat-control-mark, var(--plait-color-text-muted));
}
/* as Crew (`.plait-composer svg`, `.plait-composer__action--send path`): the symbols of the line 1.15rem, the send arrow's
   line as thin as the suit says (Gold 1.5) */
.block-input[data-line="yes"] button[data-intrinsic="symbol"] .icon {
  width: 1.15rem;
  height: 1.15rem;
  display: block;
}
/* Owner 2026-11-01 08:06 ("Muss den hintergrund wie senden icon und büroklammer haben. Der ist bereits globalisiert. Auch
   in der application der back-buttobutton muss das A sein."): the carrier's create button and its way back wear the ONE
   circle of send and paper clip below: its face with the gold ring (the suit's `send` material paints the ring on the
   border box, so the border is transparent, never a colour; a gradient as a border colour drops the whole line and the
   browser's grey rim comes back), its ink and its light. */
.create, .way-back-sign {
  border: 1px solid transparent;
  background: var(--plait-material-send, var(--plait-color-accent));
  color: var(--plait-material-send-ink, var(--plait-color-on-accent));
  box-shadow: var(--plait-elevation-send, none);
}
/* plait-platform-0204, after 6ef3576fd (owner 2026-10-25: "Dieser Kreis soll als globales Element erstellt werden … Ändert
   man das Aussehen des Kreises an einer Stelle, so ist es überall aktualisiert."): EVERY button of the input (the blocks of
   its `buttons`, platform/blocks/input BUTTONS) wears Crew's ONE circle (`.plait-circle` of @plait/ui-web), its face, ink,
   light and the line of its symbol, by WHERE it stands and never by its name.
   🔴 Owner 2026-11-07 12:06 („Aber es ist nicht im kreis wie büroklammer und senden"): the rule named send and paper clip
   by their classes, so the microphone (`block-mic`) stood bare beside them; a button standing in `.input-buttons` now wears
   it, also inside its hull (`acting-hull`: paper clip and microphone, never send). Its FORM is the suite's and stands ONCE,
   on every symbol of the line above (`--plait-radius-symbol-button`, owner 12:30: „die icons und auch der kreis sind vom
   suite gesteuert"), its icon is not.
   🔴 Owner 2026-11-06 („Erstelle ein icon für den anker. Er soll auch im kreis dargestellt werdn.“): the anchor key stands
   in the line itself, beside `.input-buttons`; a symbol button standing THERE wears the same circle, by its place too. */
.block-input[data-line="yes"] > .input-buttons button[data-intrinsic="symbol"] path,
.block-input[data-line="yes"] > button[data-intrinsic="symbol"] path {
  stroke-width: var(--plait-material-send-stroke, 2.5);
}
.block-input[data-line="yes"] > .input-buttons button[data-intrinsic="symbol"],
.block-input[data-line="yes"] > button[data-intrinsic="symbol"] {
  border: 1px solid transparent;
  background: var(--plait-material-send, var(--plait-color-accent));
  color: var(--plait-material-send-ink, var(--plait-color-on-accent));
  box-shadow: var(--plait-elevation-send, none);
}
.block-input[data-line="yes"] > .input-buttons button[data-intrinsic="symbol"]:not(:disabled):active, .block-input[data-line="yes"] > button[data-intrinsic="symbol"]:not(:disabled):active { transform: scale(0.96); }
/* while it records (the microphone's `aria-pressed`) a ring in the suite's accent breathes around it, in its form */
.block-input[data-line="yes"] > .input-buttons button[data-intrinsic="symbol"][aria-pressed="true"] {
  outline: var(--plait-material-rim-width, 1px) solid var(--plait-color-accent); outline-offset: var(--plait-space-xs);
  animation: symbol-button-running var(--plait-motion-equalizer) ease-in-out infinite;
}
@keyframes symbol-button-running { 50% { outline-color: transparent; } }
@media (prefers-reduced-motion: reduce) { .block-input[data-line="yes"] > .input-buttons button[data-intrinsic="symbol"][aria-pressed="true"] { animation: none; } }
/* Owner 2026-10-19 (PLAIT Assistant as PLAIT Crew): the FUNCTION STRIP, Crew's `.plait-composer-functions` drawn by the
   carrier. An entry the surface lays on the ground `strip` is one CELL of it; the cells stand side by side in a box
   directly under an input line, and together they are the composer box's lower section: the rule above them is the
   line's own lower edge, a rule between two cells, the box's rim around the outside, its lower corners rounded. A
   cell that can be pressed carries Crew's corner wedge, green while it is on (`aria-pressed`). No block knows it stands
   in a strip: the surface says so, the carrier draws it. */
/* As Crew's `.plait-composer`: line and strip are ONE box. Its material, rim and light lie on the box that holds both
   (drawn in a layer of its own under them, so the laid-out cells keep their exact places), the line and the cells are
   clear on it, the strip's upper edge is the composer's rule, its cells end 1 px inside the rim. */
.layout .box:has(> .cell .block-input[data-line="yes"]):has(> .box > .cell > .piece[data-ground="strip"]) {
  isolation: isolate; overflow: hidden;
  /* its width is the measure of the rim's gold (`::before`), whatever its height */
  container-type: inline-size;
  /* the rim's width, named (tests/style.test.ts): the strip's cells end this far inside it */
  --crew-rim: var(--plait-material-rim-width, 1px);
  border-radius: var(--plait-radius-lg);
  box-shadow: var(--plait-elevation-composer, none);
}
.layout .box:has(> .cell .block-input[data-line="yes"]):has(> .box > .cell > .piece[data-ground="strip"])::before {
  content: ""; position: absolute; inset: 0; z-index: -1; box-sizing: border-box; border-radius: inherit; pointer-events: none;
  background: var(--plait-material-composer, var(--plait-color-surface));
  border: var(--crew-rim) solid var(--plait-material-composer-rim, var(--plait-color-border));
  /* 🔴 Owner 2026-10-22 13:04 ("1: ja": the rim's gold falls as in Crew at every height of the box): Crew's material
     unchanged, only the SIZE of its layers fixed: the fill covers the box, the rim's 135° gold lies on a SQUARE as wide as
     the box (`100cqw`; a box taller than wide keeps its own height), so a flat box shows the upper part of the same gold
     and its right edge never the bright end */
  background-size: 100% 100%, 100% max(100cqw, 100%);
  background-repeat: no-repeat;
}
.layout .cell:has(+ .box > .cell > .piece[data-ground="strip"]) .block-input[data-line="yes"] {
  background: transparent; border-color: transparent; border-radius: 0; box-shadow: none;
}
/* 🔴 Owner 2026-10-22 („Ja so golden. Aber etwas dünner und mit glanzeffekt."): the GLEAM of the word mark runs along the
   gold rim of the own bubble and of the composer (on the box when a strip hangs below it). Only the rim's ring shows it
   (a mask cuts the inside away), only a suit that declares a gleam (`--plait-material-rim-gleam`) has one, it runs in
   the suit's beat (`--plait-motion-rim-gleam`), and with less motion it stands still (the one rule below). */
.block-chat .message.own::after,
.block-input[data-line="yes"]::after,
.layout .box:has(> .cell .block-input[data-line="yes"]):has(> .box > .cell > .piece[data-ground="strip"])::after {
  content: ""; position: absolute; box-sizing: border-box; border-radius: inherit; pointer-events: none;
  --rim-width: var(--plait-material-rim-width, 1px);
  inset: calc(-1 * var(--rim-width));
  padding: var(--rim-width);
  background: var(--plait-material-rim-gleam, none) 0 0 / 300% 100% no-repeat;
  -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(black 0 0) content-box exclude, linear-gradient(black 0 0);
  animation: rim-gleam var(--plait-motion-rim-gleam, 3.6s) linear infinite;
}
.layout .box:has(> .cell .block-input[data-line="yes"]):has(> .box > .cell > .piece[data-ground="strip"])::after { inset: 0; z-index: 1; }
.layout .cell:has(+ .box > .cell > .piece[data-ground="strip"]) .block-input[data-line="yes"]::after { content: none; }
@keyframes rim-gleam { from { background-position: 150% 0; } to { background-position: -50% 0; } }
.layout .box > .box:has(> .cell > .piece[data-ground="strip"]) {
  clip-path: inset(0 var(--crew-rim) var(--crew-rim) var(--crew-rim) round 0 0 calc(var(--plait-radius-lg) - var(--crew-rim)) calc(var(--plait-radius-lg) - var(--crew-rim)));
}
.piece[data-ground="strip"] {
  display: flex; align-items: stretch; box-sizing: border-box; height: 100%; min-height: var(--ergonomics-target-size); margin: 0; padding: 0;
  border: 0; border-radius: 0; box-shadow: none; overflow: hidden;
  border-top: 1px solid var(--plait-material-composer-rule, var(--plait-color-border));
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--plait-color-surface-elevated) var(--plait-opacity-veil-from), transparent),
    color-mix(in srgb, var(--plait-color-surface-elevated) var(--plait-opacity-veil-to), transparent)
  );
}
.piece[data-ground="strip"] > h3 { display: none; }
.layout .cell + .cell > .piece[data-ground="strip"] {
  border-left: 1px solid var(--plait-material-composer-rule, var(--plait-color-border));
}
/* a text in a cell is a READING (Crew's readout): one quiet line, cut with an ellipsis where the cell ends */
.piece[data-ground="strip"] .block-text {
  align-self: center; flex: 1 1 auto; min-width: 0; padding: 0 var(--plait-space-sm);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted);
}
/* a button in a cell is flush with it: no face, no frame of its own, the cell's whole height a finger's target */
.piece[data-ground="strip"] .block-button { display: flex; flex: 1 1 auto; align-items: stretch; gap: 0; min-width: 0; }
.piece[data-ground="strip"] .block-button > button {
  position: relative; flex: 1 1 auto; height: auto; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-md);
  border: 0; border-radius: 0; background: transparent; box-shadow: none; color: var(--plait-color-text);
  font-size: var(--plait-type-caption-size); white-space: nowrap;
}
/* the wedge is a MARK, drawn as an edge (no ground, no text on it): a box of no height whose lower edge is the wedge's
   height, clipped to Crew's shape (`.plait-composer-functions__box`, 14 x 6, the left side slanted) */
/* 🔴 Owner 2026-10-22 (planner-18: "der burger-button ... hat in assistant auch dieses ding rechts unten"): as Crew's
   `composerCellBox` (@plait/chat-ui composer-functions.ts), a cell that only PRESSES carries no wedge, the burger none
   either; only a cell that holds a state (`aria-pressed`) has one */
.piece[data-ground="strip"] .block-button > button[aria-pressed]::after {
  content: ""; position: absolute; right: 0; bottom: 0; box-sizing: content-box; width: 14px; height: 0;
  border-bottom: 6px solid var(--chat-composer-mark, var(--plait-color-border));
  clip-path: polygon(38% 0, 100% 0, 100% 100%, 0 100%); pointer-events: none;
}
.piece[data-ground="strip"] .block-button > button[aria-pressed="true"]::after { border-bottom-color: var(--plait-color-ok); }
/* an accepted switch says its new state on the button itself; only an outcome that did not go through stands in words */
.piece[data-ground="strip"] .block-button > .delivery-result.accepted { display: none; }
/* The suit's materials of the chat (owner 2026-10-19, as PLAIT Crew wears them): without a suit's say every rule above
   falls back to the plain tokens, Crew's Ship look. The GOLD suit lays black glass with a rim in the accent, as Crew's
   `GOLD_B` set does (design-tokens sets/gold.ts: composer, send, own bubble), built only from the suit's own tokens.
   🔴 Owner 2026-10-22: Gold is the standard and wears the ids `dark` / `light` (the former `gold-*` ids are gone).
   🔴 Owner 2026-10-22 ("So wie es in crew sessions ist, so muss es in assistant sein"): every value now READS the suit's own
   material (`--plait-material-*`, `--plait-elevation-*`, generated into suites.css), the very variables Crew's Hub reads;
   the earlier hand-made gold stays only as the fallback. The rims lie in the material's border-box layer, so the rim
   colours are transparent here. */
/* 2026-10-24: PLAIT One is a copy of Gold (design-tokens plaitOneDark/Light) and wears Gold's laying too; without its
   ids here a One page drew the customers' framed tab pill (the launcher renderings of PLAIT Render). */
:root[data-topic="gold-dark"], .stage-frame[data-topic="gold-dark"], :root[data-topic="gold-light"], .stage-frame[data-topic="gold-light"], :root[data-topic="dark"], .stage-frame[data-topic="dark"], :root[data-topic="light"], .stage-frame[data-topic="light"], :root[data-topic="one-dark"], .stage-frame[data-topic="one-dark"], :root[data-topic="one-light"], .stage-frame[data-topic="one-light"] {
  --chat-composer-ground: var(--plait-material-composer, linear-gradient(180deg, var(--plait-color-surface), var(--plait-color-bg)));
  --chat-strip-ground: var(--plait-color-bg);
  --chat-composer-rim: var(--plait-material-composer-rim, color-mix(in srgb, var(--plait-color-accent) 75%, transparent));
  --chat-composer-rule: var(--plait-material-composer-rule, color-mix(in srgb, var(--plait-color-accent) 28%, transparent));
  --chat-composer-mark: var(--plait-material-composer-mark, var(--plait-color-accent));
  --chat-composer-focus: var(--plait-color-accent);
  --chat-composer-glow: var(--plait-elevation-composer, 0 0 var(--plait-space-md) color-mix(in srgb, var(--plait-color-accent) 12%, transparent));
  --chat-control-mark: var(--plait-color-accent);
  --chat-send-ground: var(--plait-material-send, linear-gradient(180deg, var(--plait-color-surface), var(--plait-color-bg)));
  --chat-send-rim: transparent;
  --chat-send-ink: var(--plait-material-send-ink, var(--plait-color-accent));
  --chat-send-glow: var(--plait-elevation-send, 0 0 var(--plait-space-md) color-mix(in srgb, var(--plait-color-accent) 28%, transparent));
  --chat-own-ground: var(--plait-material-bubble-own, linear-gradient(180deg, var(--plait-color-surface), var(--plait-color-bg)));
  --chat-own-rim: transparent;
  --chat-own-ink: var(--plait-color-on-bubble-own, var(--plait-color-text));
  --chat-own-glow: var(--plait-elevation-bubble-own, 0 0 var(--plait-space-sm) color-mix(in srgb, var(--plait-color-accent) 22%, transparent));
  /* Owner 2026-10-20 ("Im grunde so wie aktuell Crew. Oben statt der Buttons sollen Tabs sein ... und die Inhalte darunter
     nicht in Cards sondern sauber den ganzen Bildschirm nutzen, ohne dass Blöcke einzeln erkennbar sind"): the row of tabs
     as Crew's strip (hub `.plait-mount-tabs`: one line scrolling sideways, a rule under it, caption size, `sm` air beside
     a word; Gold's `GOLD_B`: capitals spaced .2em, the active word in the text colour over the accent's hairline fading out
     at both ends with a little light rising from it), and every field flat on the page: no ground, rim or corner of its
     own and no air inside, so no block reads as a box (a field that SAYS a state, denied or broken, keeps its rim). */
  --plait-tab-row-wrap: nowrap;
  --plait-tab-row-overflow: auto;
  --plait-tab-row-rule: 1px solid var(--plait-color-border);
  --plait-tab-shrink: 0;
  --plait-tab-radius: 0;
  --plait-tab-inset: var(--plait-space-sm);
  --plait-tab-size: var(--plait-type-caption-size);
  --plait-tab-case: uppercase;
  --plait-tab-tracking: 0.2em;
  --plait-tab-space: nowrap;
  --plait-tab-edge: transparent;
  --plait-tab-hover-edge: transparent;
  --plait-tab-active-text: var(--plait-color-text);
  --plait-tab-active-edge: transparent;
  --plait-tab-active-mark: none;
  --plait-tab-active-ground:
    linear-gradient(90deg, transparent, var(--plait-color-accent-muted) 16%, var(--plait-color-accent), var(--plait-color-accent-muted) 84%, transparent) bottom / 100% 1px no-repeat border-box,
    radial-gradient(46% 100% at 50% 100%, color-mix(in srgb, var(--plait-color-accent) 24%, transparent), color-mix(in srgb, var(--plait-color-accent) 8%, transparent) 45%, transparent) bottom / 100% var(--plait-space-md) no-repeat border-box;
  --plait-piece-ground: transparent;
  --plait-piece-rim: transparent;
  --plait-piece-radius: 0;
  --plait-piece-padding: 0px;
}
/* 🔴 THE HEIGHT FOLLOWS: an svg with a viewBox brings its own ratio. */
.block-picture { width: 100%; height: auto; }

.delivery-result { display: block; font-size: var(--plait-type-caption-size); }
/* Auftrag 34c (G7): a button-shaped block stands in a hull; its ways out stand beside the button, never in it */
.acting-hull { display: inline-flex; flex-wrap: wrap; align-items: flex-start; gap: var(--plait-space-sm); }
.delivery-result.accepted { color: var(--plait-color-text-muted); }
.delivery-result.rejected { color: var(--plait-color-warn); }
.delivery-result.not-reached { color: var(--plait-color-danger-text, var(--plait-color-danger)); }

.block-form { display: grid; gap: var(--plait-control-gap); }
/* Step 5c: two columns only where each can hold a field (half a phone's width); narrower, the form stands in one column instead of running out of its box. */
.block-form[data-intrinsic="two_column"] { grid-template-columns: repeat(2, minmax(calc(var(--plait-device-phone-short) / 2), 1fr)); }
.block-form .field_value { min-width: 0; }
.block-form .field { display: flex; flex-direction: column; gap: var(--plait-space-xs); }
.block-form .field_name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-form .submit { justify-self: start; }
.block-form .receipt { margin: 0; font-size: var(--plait-type-caption-size); }
.block-form .receipt[data-receipt="yes"] { color: var(--plait-color-ok); }
.block-form .receipt[data-receipt="no"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
/* PLAIT Reply (2026-10-11): the six kinds of field a rule needs, only the suit's tokens. A large text field and a
   group of days take the whole width of a two column form; a switch stands with its name in one line. */
.block-form .field_lines { width: 100%; resize: vertical; font: inherit; }
.block-form .field:has(> .field_lines[data-size="large"]), .block-form .field[role="group"] { grid-column: 1 / -1; }
.block-form .field_switch { flex-direction: row; align-items: center; justify-content: space-between; }
.block-form .field_toggle { accent-color: var(--plait-color-accent); }
.block-form .field_range { display: flex; align-items: center; gap: var(--plait-space-sm); }
.block-form .field_range > input { flex: 1; min-width: 0; accent-color: var(--plait-color-accent); }
.block-form .field_range_value { min-width: var(--plait-space-lg); text-align: end; font-variant-numeric: tabular-nums; color: var(--plait-color-text); }
.block-form .field_days { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-form .field_day { display: inline-flex; align-items: center; gap: var(--plait-space-xs); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); padding: var(--plait-space-xs) var(--plait-space-sm); }
.block-form .field_day > input { accent-color: var(--plait-color-accent); }
/* owner 2026-10-20: a code is one box per character, a dash between the groups; the boxes never stretch with the page */
.block-form .field:has(> .field_code) { grid-column: 1 / -1; min-width: 0; }
.block-form .field_code { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--plait-space-xs); width: 100%; min-width: 0; }
.block-form .field_code_cell { box-sizing: border-box; flex: 1 1 0; min-width: 0; max-width: calc(var(--ergonomics-target-size) * 0.9); height: var(--ergonomics-target-size); padding: 0; text-align: center; font-family: var(--plait-type-mono-family); font-size: var(--plait-type-title-size); text-transform: uppercase; }
.block-form .field_code_dash { flex: 0 0 auto; color: var(--plait-color-text-muted); font-size: var(--plait-type-title-size); }
/* owner 2026-10-21: the small paste sign beside the code's name; the tap area keeps the ergonomic size, the sign stays small */
.block-form .field:has(> .field_code_paste) { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
.block-form .field:has(> .field_code_paste) > :not(.field_name):not(.field_code_paste) { grid-column: 1 / -1; }
.block-form .field_code_paste { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: calc(var(--ergonomics-target-size) * 0.8); height: var(--ergonomics-target-size); padding: 0; border: none; background: transparent; color: var(--plait-color-text-muted); cursor: pointer; }
.block-form .field_code_paste:hover, .block-form .field_code_paste:focus-visible { color: var(--plait-color-text); }
/* Auftrag 6: PLAIT's colour picker (form kind `colour`, never the browser's own): closed a chip with the value, open the
   field of colour, four sliders and the value to type; every line, ground and tone from the suite, the opacity shown over a
   checkered ground of its surface and its border tone */
.block-form .field_colour { min-width: 0; border: 1px solid var(--plait-color-border); border-radius: var(--plait-field-radius, var(--plait-control-radius)); background: var(--plait-color-surface); }
.block-form .field_colour[open] { grid-column: 1 / -1; }
.block-form .field:has(> .field_colour[open]) { grid-column: 1 / -1; }
.block-form .field_colour_summary { display: flex; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm); cursor: pointer; list-style: none; color: var(--plait-color-text); }
.block-form .field_colour_summary::-webkit-details-marker { display: none; }
.block-form .field_colour_summary:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.block-form .field_colour_chip, .block-form .field_colour_plane { display: block; overflow: hidden; border: 1px solid var(--plait-color-border);
  background-color: var(--plait-color-surface); background-image: conic-gradient(var(--plait-color-border) 25%, transparent 0 50%, var(--plait-color-border) 0 75%, transparent 0);
  background-size: var(--plait-space-sm) var(--plait-space-sm); }
.block-form .field_colour_chip { flex: 0 0 auto; width: calc(var(--ergonomics-target-size) * 0.6); height: calc(var(--ergonomics-target-size) * 0.6); border-radius: var(--plait-radius-sm); }
.block-form .field_colour_swatch { display: block; width: 100%; height: 100%; }
.block-form .field_colour_shown { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--plait-type-mono-family); font-size: var(--plait-type-caption-size); }
.block-form .field_colour_body { display: grid; gap: var(--plait-space-sm); padding: var(--plait-space-sm); border-top: 1px solid var(--plait-color-border); }
.block-form .field_colour_plane { height: calc(var(--ergonomics-target-size) * 1.5); border-radius: var(--plait-radius-md); }
.block-form .field_colour_part { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); align-items: center; gap: var(--plait-space-sm); }
.block-form .field_colour_part_name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-form .field_colour_slider { width: 100%; min-width: 0; min-height: var(--ergonomics-target-size); accent-color: var(--plait-color-accent); }
.block-form .field_colour_text { font-family: var(--plait-type-mono-family); }
.block-form .field_colour_text[aria-invalid="true"] { border-color: var(--plait-color-danger); }
/* the heading of a group of fields over the whole width; a field a refusal names is marked by the danger token */
.block-form .field_group { grid-column: 1 / -1; margin: var(--plait-space-sm) 0 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
/* owner 2026-10-21 (the smartphone in PLAIT Browser): a form headed by a value of its source (the device's name), and the
   sentence of a fulfilled form in place of its fields */
.block-form .form_heading { grid-column: 1 / -1; margin: 0; font-size: var(--plait-type-body-size); font-weight: 600; color: var(--plait-color-text); }
.block-form .form_done { margin: 0; color: var(--plait-color-text-muted); }
.block-form .field_not_offered { font-size: var(--plait-type-caption-size); color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.block-form [aria-invalid="true"] { border-color: var(--plait-color-danger); outline: 1px solid var(--plait-color-danger); }

.block-storage .storage_pieces { margin: 0 0 var(--plait-space-sm); padding: 0; list-style: none; display: grid; gap: var(--plait-space-xs); }
.block-storage[data-intrinsic="grid"] .storage_pieces { grid-template-columns: 1fr 1fr; }
.block-storage .storage_piece { display: flex; gap: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); padding: var(--plait-space-sm); font-size: var(--plait-type-caption-size); }
.block-storage .piece_name { flex: 1; color: var(--plait-color-text); }
.block-storage .piece_size, .block-storage .piece_kind { color: var(--plait-color-text-muted); }

.block-status-card { display: grid; gap: var(--plait-space-sm); }
.block-status-card[data-intrinsic="grid"] { grid-template-columns: repeat(3, 1fr); }
.block-status-card .card { border: 1px solid var(--plait-color-border); border-left-width: var(--plait-mark-glow-core-width); border-radius: var(--plait-radius-sm); padding: var(--plait-space-sm); display: grid; gap: var(--plait-space-xs); }
.block-status-card .card[data-sound="warning"] { border-left-color: var(--plait-color-warn); }
.block-status-card .card[data-sound="good"] { border-left-color: var(--plait-color-ok); }
.block-status-card .card[data-sound="neutral"] { border-left-color: var(--plait-color-border); }
.block-status-card .card_title { margin: 0; font-size: var(--plait-type-body-size); }
/* 2026-10-24 (launcher renderings: "2026-10-24T06:40:00Zplan-erdgeschoss.jpg hochgeladen"): a point of the timeline is
   its moment and its text side by side, the moment small and muted, never glued to the text; no list numbers. */
.block-timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--plait-space-xs); }
.block-timeline .point { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--plait-space-xs) var(--plait-space-sm); }
.block-timeline .when { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); white-space: nowrap; }
.block-status-card .card_subline, .block-status-card .card_mark, .block-status-card .card_time { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }

.block-diagram { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: var(--plait-space-sm); align-items: end; }
.block-diagram .scale { margin: 0; padding: 0; list-style: none; display: grid; height: var(--plait-diagram-height); font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-diagram .bars { margin: 0; padding: 0; list-style: none; display: flex; gap: var(--plait-space-xs); align-items: end; height: var(--plait-diagram-height); }
.block-diagram .bar { flex: 1; background: var(--plait-color-accent); color: var(--plait-color-on-accent); height: var(--share); border-radius: var(--plait-radius-sm) var(--plait-radius-sm) 0 0; font-size: var(--plait-type-caption-size); text-align: center; }
.block-diagram .diagram_foot { grid-column: 1 / -1; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }

.block-document { max-height: var(--document_height); overflow-y: auto; border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); padding: var(--plait-space-sm); }
.block-document .edge_mark { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); text-transform: uppercase; letter-spacing: var(--plait-type-tracking-label); }
.block-document .document_head { margin: var(--plait-space-md) 0 var(--plait-space-xs); font-size: var(--plait-type-label-size); }
.block-document .document_paragraph { margin: 0 0 var(--plait-space-sm); }

.block-foreign-area { border: 1px dashed var(--plait-color-warn); border-radius: var(--plait-radius-sm); padding: var(--plait-space-sm); }
.block-foreign-area .foreign_mark { margin: 0 0 var(--plait-space-sm); font-size: var(--plait-type-caption-size); color: var(--plait-color-warn); text-transform: uppercase; letter-spacing: var(--plait-type-tracking-label); }
.block-foreign-area .foreign_frame { width: 100%; height: var(--foreign_height); border: 0; border-radius: var(--plait-radius-sm); background: var(--plait-color-bg); }
.block-foreign-area .foreign_reason { margin: 0 0 var(--plait-space-sm); font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* Owner 2026-10-25 (PLAIT Bootstrap, "zeigt eine html einfach auf der ganzen surface"): tier full fills the cell the
   LAYOUT sizes (a share), the frame takes every pixel below the mark, no dashed card around it. */
.layout .cell:not([data-size="content"]) > .piece[data-block="foreign-surface"]:has(.block-foreign-area[data-tier="full"]) { height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; }
.block-foreign-area[data-tier="full"] { height: 100%; box-sizing: border-box; display: flex; flex-direction: column; border: 0; border-radius: 0; padding: 0; }
.block-foreign-area[data-tier="full"] .foreign_mark { margin: 0; padding: var(--plait-space-xs) var(--plait-space-sm); }
.block-foreign-area[data-tier="full"] .foreign_frame { flex: 1 1 0; min-height: 0; height: auto; border-radius: 0; }

.block-tile-grid { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--plait-space-sm); grid-template-columns: repeat(var(--columns), 1fr); }
/* plait-app-0157: the count of columns also by the attribute the block writes, because a page under the offline bundle's
   policy (style-src 'self', the PLAIT App) refuses the inline `--columns` and the grid fell to one column */
.block-tile-grid[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
.block-tile-grid[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
.block-tile-grid[data-columns="5"] { grid-template-columns: repeat(5, 1fr); }
/* plait-app-0161 (owner 2026-10-24, "4: ja"): the apps of PLAIT One as a home screen shows them: no card around a tile
   (owner 2026-10-23: "Jede App heutzutage verwendet cards. Typisch KI."), the app's own icon over its name, the name
   small and on one line; the second line is kept for the reading voice only. An app without a picture shows its
   initial in the suit's gold on a quiet round. */
.block-tile-grid[data-columns="4"] { grid-template-columns: repeat(4, 1fr); }
.block-tile-grid[data-columns="8"] { grid-template-columns: repeat(8, 1fr); }
.block-tile-grid[data-look="icons"] { gap: var(--plait-space-md) var(--plait-space-xs); align-content: start; }
.block-tile-grid[data-look="icons"] .tile, .block-tile-grid[data-look="icons"] .tile:not([data-shows="only"]):hover { border: 0; background: none; }
.block-tile-grid[data-look="icons"] .tile_handle { height: auto; display: grid; justify-items: center; align-content: start; gap: var(--plait-space-xs);
  padding: var(--plait-space-xs) 0; text-align: center; }
.block-tile-grid[data-look="icons"] .tile_icon { width: calc(var(--ergonomics-target-size) * 1.1); height: calc(var(--ergonomics-target-size) * 1.1); border-radius: 26%; object-fit: contain; display: block; }
.block-tile-grid[data-look="icons"] .tile_icon-none { display: grid; place-items: center; background: var(--plait-color-surface-elevated); color: var(--plait-color-accent-text, var(--plait-color-accent));
  font-weight: 200; font-size: var(--plait-type-title-size); border: 1px solid color-mix(in srgb, var(--plait-color-accent) 35%, transparent); }
.block-tile-grid[data-look="icons"] .tile_name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-body-weight); }
.block-tile-grid[data-look="icons"] .tile_subline { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.block-tile-grid[data-look="icons"] .tile_handle:focus-visible .tile_icon { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* plait-platform-0197 (owner 2026-10-26, the gallery as an application): pictures as tiles, each a square of the picture,
   no card around it; a heading row over every new day, the date in the suit's look (`plait.type.date.*`, the same values
   PLAIT One's start writes its date with) above a divider line across the whole grid. */
.block-tile-grid[data-look="pictures"] { gap: var(--plait-space-xs); align-content: start; }
.block-tile-grid[data-look="pictures"] .tile, .block-tile-grid[data-look="pictures"] .tile:hover { position: relative; border: 0; border-radius: var(--plait-radius-sm); background: var(--plait-color-surface-elevated); overflow: hidden; aspect-ratio: 1; }
.block-tile-grid[data-look="pictures"] .tile_picture_handle { display: block; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.block-tile-grid[data-look="pictures"] .tile_picture { display: block; width: 100%; height: 100%; object-fit: cover; }
.block-tile-grid[data-look="pictures"] .tile_picture_handle:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.block-tile-grid[data-look="pictures"] .tile_favorite { position: absolute; right: var(--plait-space-xs); bottom: var(--plait-space-xs); color: var(--plait-color-accent-text, var(--plait-color-accent)); font-size: var(--plait-type-caption-size); line-height: 1; }
.block-tile-grid .tile_day { grid-column: 1 / -1; padding: var(--plait-space-md) 0 var(--plait-space-xs); border-bottom: 1px solid var(--plait-color-border); }
.block-tile-grid .tile_day:first-child { padding-top: 0; }
.block-tile-grid .plait-date { font-size: var(--plait-type-date-size, var(--plait-type-caption-size)); font-weight: var(--plait-type-date-weight, 300); letter-spacing: var(--plait-type-date-tracking, 0em);
  text-transform: var(--plait-type-date-case, none); color: var(--plait-color-text-muted); }
.block-tile-grid .tile { border: 1px solid var(--plait-color-tile-border); border-radius: var(--plait-radius-lg); background: var(--plait-tile-ground); }
.block-tile-grid .tile_handle { width: 100%; height: var(--plait-tile-handle-height); min-height: var(--ergonomics-target-size); background: transparent; border: 0; color: var(--plait-color-text); font-size: var(--plait-type-label-size); cursor: pointer; }
.block-tile-grid .tile[data-sound="good"] { border-color: var(--plait-color-ok); }
.block-tile-grid .tile[data-sound="warning"] { border-color: var(--plait-color-warn); }
/* 2026-10-24: `accent` is EMPHASIS, not a status (green stays "good": a light on, a gate free); in Gold and One the tile
   wears the brushed rim and glow of a control, every other suit its accent edge. */
.block-tile-grid .tile[data-sound="accent"] { border-color: var(--plait-material-control-rim, var(--plait-color-accent)); background: var(--plait-material-control, var(--plait-color-surface-elevated)); box-shadow: var(--plait-elevation-control, none); }

.block-question-card { display: grid; gap: var(--plait-space-sm); }
.block-question-card .question { border: 1px solid var(--plait-color-info); border-radius: var(--plait-radius-md); padding: var(--plait-space-md); display: grid; gap: var(--plait-space-sm); }
.block-question-card .question_text { margin: 0; font-size: var(--plait-type-title-size); }
.block-question-card .asker_origin { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-question-card .answers { display: flex; gap: var(--plait-space-sm); flex-wrap: wrap; }
.block-question-card[data-intrinsic="one_below_another"] .answers { flex-direction: column; }
/* plait-platform-0198 (owner 2026-10-26, the question of PLAIT Gallery): ONLY its pictures, one alone over the width, two to
   four two by two, more three in a row; its info quiet below; the answers one row of equal buttons, the suggested one with
   the accent rim (as everywhere a suggestion is drawn); an answered question says its answer. A question with pictures
   stands on the surface itself, not in a second frame. */
.block-question-card .question:has(.question_pictures) { border: 0; padding: 0; gap: var(--plait-space-md); }
.block-question-card .question:has(.question_pictures) .question_text { color: var(--plait-color-heading, var(--plait-color-accent)); }
.block-question-card .question_pictures { display: grid; grid-template-columns: repeat(var(--question-columns, 1), minmax(0, 1fr)); gap: var(--plait-space-xs); }
.block-question-card .question_pictures[data-columns="2"] { --question-columns: 2; }
.block-question-card .question_pictures[data-columns="3"] { --question-columns: 3; }
.block-question-card .question_picture { display: block; width: 100%; height: auto; border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface-elevated); object-fit: contain; max-height: 50vh; }
.block-question-card .question_pictures:not([data-columns="1"]) .question_picture { aspect-ratio: 1 / 1; object-fit: cover; }
.block-question-card .question_info { margin: 0; color: var(--plait-color-text-muted); white-space: pre-wrap; }
.block-question-card .question:has(.question_pictures) .answers { flex-direction: row; flex-wrap: nowrap; }
.block-question-card .question:has(.question_pictures) .answer { flex: 1 1 0; min-width: 0; min-height: var(--ergonomics-target-size); }
.block-question-card .answer[data-suggested="yes"] { border-color: var(--plait-color-accent); box-shadow: inset 0 0 0 var(--plait-material-rim-width) var(--plait-color-accent); }
.block-question-card .question_answered { margin: 0; color: var(--plait-color-text-muted); }
.block-question-card .question_answered strong { color: var(--plait-color-accent-text, var(--plait-color-accent)); }

.block-message-list { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--plait-space-xs); }
.block-message-list .message { display: grid; grid-template-columns: 8rem 1fr auto auto; gap: var(--plait-space-sm); align-items: baseline; padding: var(--plait-space-sm); border-bottom: 1px solid var(--plait-color-border); }
.block-message-list[data-intrinsic="stacked"] .message { grid-template-columns: 1fr auto; }
.block-message-list .from { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-message-list .time { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-message-list .unread { color: var(--plait-color-on-accent); background: var(--plait-color-accent); border-radius: var(--plait-radius-sm); padding: 0 var(--plait-space-xs); font-size: var(--plait-type-caption-size); }
.block-message-list .message[data-read="false"] .subject { font-weight: var(--plait-type-label-weight); }

.block-calendar { display: grid; gap: var(--plait-space-sm); grid-template-columns: repeat(var(--days), 1fr); }
.block-calendar .tag { border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); padding: var(--plait-space-sm); }
.block-calendar .day_head { margin: 0 0 var(--plait-space-sm); font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-calendar .appointments { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--plait-space-xs); }
.block-calendar .appointment { display: flex; gap: var(--plait-space-sm); font-size: var(--plait-type-caption-size); border-left: var(--plait-mark-glow-core-width) solid var(--plait-color-accent); padding-left: var(--plait-space-sm); }
.block-calendar .appointment_time { color: var(--plait-color-text-muted); }

.block-map { display: grid; gap: var(--plait-space-sm); }
.block-map .tier { display: flex; gap: var(--plait-space-sm); flex-wrap: wrap; justify-content: center; }
.block-map .node { border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-lg); background: var(--plait-color-surface-elevated); color: var(--plait-color-text); padding: var(--plait-space-xs) var(--plait-space-md); cursor: pointer; font-size: var(--plait-type-label-size); }
.block-map .node[data-group="shape"] { border-color: var(--plait-color-accent); }
.block-map .node[data-group="data"] { border-color: var(--plait-color-info); }
.block-map .node[data-group="outer"] { border-color: var(--plait-color-warn); }

/* E18 · THE MEASURING PLACE. It is VISIBLE and only pushed out of view.
   `display:none` or `visibility:hidden` would be zero wide, and zero is no
   measurement but a kind that fits everywhere because it was not there. The
   WIDTH is set by the host per measurement (`max-content` for a kind, which
   does not wrap; `min-content` for a block, which does); so none stands here. */
#measuring-place {
  position: absolute;
  left: -99999px;
  top: 0;
  pointer-events: none;
}

/* 🔴 AT THE MEASURING PLACE A TABLE CELL IS NOT BROKEN, and only there: the
   minimum of a column is its widest cell unbroken, not its longest word. The
   living table keeps wrapping. */
#measuring-place th, #measuring-place td { white-space: nowrap; }

/* ── Order 32 (E40): the decor layer. Beside the boxes, never in them. Both
   layers fill the shell and cut off what reaches beyond it; neither can be hit,
   focused or read aloud (the host adds aria-hidden and inert). The upper layer
   is cut out of every cell by the host (clip-path), so it covers no cell. */
.decor-layer { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.decor-element { position: absolute; overflow: hidden; container-type: size; }
.decor-element[data-decor-state="broken"] { display: none; }
.decor-slant {
  position: absolute; inset: 0; background: var(--decor-color);
  clip-path: polygon(calc(100cqh * tan(var(--decor-angle))) 0, 100% 0, 100% 100%, 0 100%);
}
.decor-slant[data-decor-side="end"] { clip-path: polygon(0 0, 100% 0, calc(100% - 100cqh * tan(var(--decor-angle))) 100%, 0 100%); }
.decor-backdrop { position: absolute; inset: 0; }
.decor-backdrop img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.decor-backdrop[data-decor-focus="top"] img { object-position: top; }
.decor-backdrop[data-decor-focus="bottom"] img { object-position: bottom; }
.decor-backdrop[data-decor-focus="start"] img { object-position: left; }
.decor-backdrop[data-decor-focus="end"] img { object-position: right; }
.decor-backdrop[data-decor-drift] img { scale: var(--plait-decor-drift-scale); animation: decor-drift var(--decor-drift) linear infinite alternate; }
/* The veil lies OVER the picture, always: text over a picture stands on it (E7, the suit's check measures exactly it). */
.decor-veil { position: absolute; inset: 0; background: var(--decor-veil); }
@keyframes decor-drift { from { translate: 0 0; } to { translate: var(--plait-decor-drift-distance) 0; } }
/* Less motion for the decor: since Auftrag 38a the ONE rule for every animation at the end of this sheet. */

/* ── Order 33: the editor's canvas and its stage. The frame stands for a
   device's window: the same ground and type as the body of a real page, its
   size from the suit's device names, its own scroll. Nothing here draws the
   surface: the nested host does, with the same rules as every page. */
.block-canvas { display: grid; gap: var(--plait-space-md); justify-items: start; align-items: start; }
/* Step 2: in a wide box the tools stand beside the stage, in a narrow one below it. */
/* Step 5b: the stage takes the whole column the tools leave (they keep their narrowest width), so the room it has never hangs on
   what it shows; a wider device is made smaller (fit) or scrolled (100 %). */
/* Auftrag 35 (A4): the tools are a column of the EDITOR, so their width follows the window step; the stage's does not. */
.block-canvas[data-intrinsic="full"] { grid-template-columns: minmax(var(--plait-device-phone-short), 1fr) calc(var(--plait-device-phone-short) * 2 / 3 * var(--plait-step-scale)); }
.block-canvas .canvas-stage { justify-self: stretch; min-width: 0; overflow: auto; }
.stage-fit { overflow: hidden; }
.stage-fit > .stage-frame { transform-origin: top left; }
.stage-suit-refused { margin: 0 0 var(--plait-space-sm); }
.block-canvas .canvas-device { margin: 0; grid-column: 1 / -1; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.canvas-tools { display: grid; gap: var(--plait-space-md); min-width: 0; }
.canvas-tree { display: grid; gap: var(--plait-space-xs); }
.canvas-box, .canvas-cell { margin: 0; }
.canvas-box { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.canvas-cell { display: flex; flex-wrap: wrap; column-gap: var(--plait-space-sm); align-items: center; min-height: var(--plait-control-height); cursor: pointer; }
/* Step 6 (b): the size in words stands below the cell's name, in the full width of the tree. */
.canvas-cell .canvas-cell-size { flex-basis: 100%; padding-inline-start: calc(var(--plait-control-height) / 2); }
.canvas-cell[data-chosen="yes"] .canvas-cell-name { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.canvas-cell-size { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* The depth of a row in the tree: one step of space per level. */
[data-depth="1"].canvas-box, [data-depth="1"].canvas-cell { padding-inline-start: var(--plait-space-md); }
[data-depth="2"].canvas-box, [data-depth="2"].canvas-cell { padding-inline-start: calc(2 * var(--plait-space-md)); }
[data-depth="3"].canvas-box, [data-depth="3"].canvas-cell { padding-inline-start: calc(3 * var(--plait-space-md)); }
[data-depth="4"].canvas-box, [data-depth="4"].canvas-cell { padding-inline-start: calc(4 * var(--plait-space-md)); }
[data-depth="5"].canvas-box, [data-depth="5"].canvas-cell { padding-inline-start: calc(5 * var(--plait-space-md)); }
[data-depth="6"].canvas-box, [data-depth="6"].canvas-cell { padding-inline-start: calc(6 * var(--plait-space-md)); }
.canvas-actions, .canvas-sizes { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
.canvas-action[aria-pressed="true"] { border-color: var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.canvas-hint { margin: 0; flex-basis: 100%; color: var(--plait-color-text-muted); }
.stage-frame { position: relative; overflow: auto; background: var(--plait-color-bg); color: var(--plait-color-text); border: 1px solid var(--plait-color-border); box-sizing: content-box;
  /* Auftrag 35 (A4): the frame keeps scale 1 (tokens.css), so its type is set again here from its own tokens, never inherited from the editor's step */
  font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height); }
/* toggle (owner 2026-10-18: „Wtf wie unübersichtlich“): one row per thing, name left and the switch right on the same
   line, a thin rule between rows; the reason field across the whole width above. A locked row is one muted line. */
.block-toggle { display: grid; gap: var(--plait-space-sm); }
.block-toggle .reason { width: 100%; box-sizing: border-box; }
.block-toggle .row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--plait-space-xs) var(--plait-space-md);
  padding: var(--plait-space-sm) 0; border-top: 1px solid var(--plait-color-border); min-height: var(--plait-control-height); }
.block-toggle .row:first-of-type { border-top: 0; }
.block-toggle .label { min-width: 0; overflow-wrap: anywhere; font-weight: var(--plait-type-label-weight); }
.block-toggle .segments { display: flex; flex-shrink: 0; gap: 0; }
.block-toggle .segments .segment { border-radius: 0; border-left-width: 0; }
.block-toggle .segments .segment:first-child { border-left-width: 1px; border-radius: var(--plait-control-radius) 0 0 var(--plait-control-radius); }
.block-toggle .segments .segment:last-child { border-radius: 0 var(--plait-control-radius) var(--plait-control-radius) 0; }
.block-toggle .row[data-locked="yes"] .label { font-weight: var(--plait-type-body-weight); color: var(--plait-color-text-muted); }
.block-toggle .locked { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* Order 33, step 5: the switch of segments. Every choice a row, the radio
   visible (a choice is read at a glance, and the keyboard reaches it as
   itself); a choice that does not fit stands greyed with its reason. */
.block-segments { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
.block-segments[data-intrinsic="stacked"] { display: grid; justify-items: start; }
.segments-choice { display: flex; gap: var(--plait-space-sm); align-items: center; min-height: var(--plait-control-height); cursor: pointer; }
/* Step 6 (a): the CHOSEN option is the strongest: full text colour and label weight; the others are the muted text. Both are measured pairs of the suit. */
.segments-name { color: var(--plait-color-text-muted); font-weight: var(--plait-type-body-weight); }
/* the checked choice, also where the carrier and not the draft says which (the suit) */
.segments-choice:has(.segments-radio:checked) .segments-name { color: var(--plait-color-text); font-weight: var(--plait-type-label-weight); }
/* Greyed: the disabled control only (WCAG 1.4.3 exempts it); its REASON stays readable, it is information. */
.segments-choice[data-fits="no"] { cursor: not-allowed; }
.segments-choice[data-fits="no"] .segments-radio, .segments-choice[data-fits="no"] .segments-name { opacity: var(--plait-opacity-disabled); }
/* plait-platform-0197 (owner 2026-10-26, the gallery's filter): `look: chips`, the few choices as chips; the radio stays for
   the keyboard and the reading voice and is hidden; the held chip wears the accent rim, the others the control's material */
.block-segments[data-look="chips"] { display: flex; flex-wrap: nowrap; gap: var(--plait-space-xs); }
.block-segments[data-look="chips"][data-intrinsic="wrapped"] { flex-wrap: wrap; }
.block-segments[data-look="chips"] .segments-choice { position: relative; min-height: var(--plait-control-height); padding: 0 var(--plait-space-md); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-xl); background: var(--plait-material-control, transparent); gap: var(--plait-space-xs); }
.block-segments[data-look="chips"] .segments-radio { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; pointer-events: none; }
.block-segments[data-look="chips"] .segments-choice:has(.segments-radio:checked) { border-color: var(--plait-color-accent); }
.block-segments[data-look="chips"] .segments-choice:has(.segments-radio:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-segments[data-look="chips"] .segments-name { font-size: var(--plait-type-label-size); }
.segments-reason, .segments-empty { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* 2026-10-16: the held choice is gone and the preselected one holds now; said on its own line, in the colour of attention */
.segments-gone { margin: 0; flex-basis: 100%; font-size: var(--plait-type-caption-size); color: var(--plait-color-warn); }
/* Auftrag 35 (A2): more choices than a row holds are a LIST. Closed it is one control naming what is held.
   Owner 2026-11-02 (the choice of a Crew session: "Das ist ein schreckliches menü!!!! ... Zudem geht hier scrollen nicht"):
   open, the choices stand in a MENU the way the header's menu stands (`.plait-header-menu`, plait-app-0189): an opaque
   panel in a hairline of the wordmark's gold, the choices as rows, the held one in the accent with a check. The panel
   rolls INSIDE itself, never taller than most of the window, so the last choice is always reached; the roll stays in
   the panel (it never hands over to the page). It stays in the flow below the control, so no cell that rolls or cuts
   (`.layout .cell`) can hide it, and it never reaches past its cell's width. */
.block-segments[data-form="list"] { display: block; min-width: 0; }
.segments-list { min-width: 0; }
.segments-list > .segments-summary { border: 1px solid var(--plait-color-border); border-radius: var(--plait-control-radius);
  background: var(--plait-material-control, var(--plait-color-surface-elevated)); }
.segments-list[open] > .segments-summary { border-color: color-mix(in srgb, var(--plait-wordmark-halo, var(--plait-color-accent)) 55%, transparent); }
.segments-summary:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.segments-summary {
  display: flex; align-items: center; gap: var(--plait-space-sm);
  min-height: var(--plait-control-height); padding: 0 var(--plait-space-md);
  cursor: pointer; list-style: none; color: var(--plait-color-text); font-weight: var(--plait-type-label-weight);
}
.segments-summary::-webkit-details-marker { display: none; }
/* the chevron: two edges of a square, turned; it points down while closed, up while open */
.segments-summary::after {
  content: ""; margin-inline-start: auto; flex: none;
  width: var(--plait-space-sm); height: var(--plait-space-sm);
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-25%) rotate(45deg);
}
.segments-list[open] > .segments-summary::after { transform: translateY(25%) rotate(225deg); }
.segments-summary[data-held="no"] .segments-current { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.segments-current { min-width: 0; overflow-wrap: anywhere; }
.segments-options {
  display: grid; column-gap: var(--plait-space-md);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--plait-list-column-least)), 1fr));
  padding: var(--plait-space-xs) var(--plait-space-sm) var(--plait-space-sm);
  border-top: 1px solid var(--plait-color-border);
}
.segments-options .segments-choice {
  min-width: 0; padding: 0 var(--plait-space-sm); border-radius: var(--plait-radius-sm);
  border-inline-start: var(--plait-mark-glow-core-width) solid transparent;
}
.segments-options .segments-name { min-width: 0; overflow-wrap: anywhere; }
.segments-options .segments-choice:has(.segments-radio:checked) { border-inline-start-color: var(--plait-color-accent); background: var(--plait-color-surface); }
/* the opened list (owner 2026-11-02): the header menu's panel, rolling inside itself */
.segments-list > .segments-options {
  display: flex; flex-direction: column; gap: 0; box-sizing: border-box; min-width: 0; max-width: 100%;
  margin-top: var(--plait-space-xs); padding: var(--plait-space-xs);
  border: 1px solid color-mix(in srgb, var(--plait-wordmark-halo, var(--plait-color-accent)) 55%, transparent);
  border-radius: var(--plait-radius-lg);
  /* opaque: what lies under the menu never reads through it */
  background: var(--plait-color-surface); color: var(--plait-color-text);
  box-shadow: var(--plait-elevation-raised);
  /* never taller than most of the window (the small viewport of a phone where the browser knows it), rolled inside */
  max-height: 60vh; max-height: 60dvh;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y;
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--plait-wordmark-halo, var(--plait-color-accent)) 45%, transparent) transparent;
}
/* closed, the panel is not drawn at all: the browser would still lay it out, and a closed list would count as a second
   area rolling up and down (the check of a phone: ONE area scrolls) */
.segments-list:not([open]) > .segments-options { display: none; }
.segments-list > .segments-options > .segments-choice {
  position: relative; flex: none; display: flex; align-items: center; gap: var(--plait-space-sm);
  min-width: 0; min-height: var(--plait-control-height); padding: var(--plait-space-sm) var(--plait-space-md);
  border: 0; border-radius: var(--plait-radius-md); background: none;
}
/* the whole row is the finger's target: the radio lies over it unseen and stays what the keyboard and the voice reach */
.segments-list > .segments-options .segments-radio { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.segments-list > .segments-options .segments-name { flex: 1 1 auto; min-width: 0; color: var(--plait-color-text); overflow-wrap: anywhere; }
.segments-list > .segments-options > .segments-choice:hover,
.segments-list > .segments-options > .segments-choice:has(.segments-radio:focus-visible) {
  background: color-mix(in srgb, var(--plait-wordmark-halo, var(--plait-color-accent)) 14%, transparent);
}
.segments-list > .segments-options > .segments-choice:has(.segments-radio:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
/* the held one: the accent, the label's weight, a ground of the accent and a check at its end */
.segments-list > .segments-options > .segments-choice:has(.segments-radio:checked) { background: color-mix(in srgb, var(--plait-color-accent) 16%, transparent); }
.segments-list > .segments-options > .segments-choice:has(.segments-radio:checked) .segments-name {
  color: var(--plait-color-accent-text, var(--plait-color-accent)); font-weight: var(--plait-type-label-weight);
}
.segments-list > .segments-options > .segments-choice:has(.segments-radio:checked)::after {
  content: ""; flex: none; margin-inline-start: auto;
  width: calc(var(--plait-space-sm) * 0.6); height: calc(var(--plait-space-sm) * 1.2);
  border-right: 2px solid var(--plait-color-accent-text, var(--plait-color-accent)); border-bottom: 2px solid var(--plait-color-accent-text, var(--plait-color-accent));
  transform: translateY(-15%) rotate(45deg);
}
.segments-list > .segments-options > .segments-choice[data-fits="no"]:hover { background: none; }
/* Owner 2026-10-18 (PLAIT Control: "Das soll ein kleines icon irgendwo sein das dann ein menü aufklappt"): a switch with an
   icon is that icon alone, a finger's target in the suit's glass; pressed, its choices open BELOW it as a menu lying over
   what follows (it never takes room of its own, so the layout under it does not move). */
.block-segments[data-form="menu"] { display: block; position: relative; text-shadow: none; }
.segments-menu > .segments-icon { display: inline-grid; place-items: center; list-style: none; cursor: pointer;
  width: var(--plait-control-height); height: var(--plait-control-height); border-radius: 999px; color: var(--plait-color-accent-text, var(--plait-color-accent));
  background: color-mix(in srgb, var(--plait-color-surface) 72%, transparent); backdrop-filter: blur(var(--plait-space-sm)); -webkit-backdrop-filter: blur(var(--plait-space-sm));
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 35%, transparent); }
.segments-menu > .segments-icon::-webkit-details-marker { display: none; }
.segments-menu > .segments-icon:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.segments-menu[open] > .segments-icon { background: var(--plait-color-surface-elevated); }
.segments-menu > .segments-options { position: absolute; z-index: 3; top: calc(100% + var(--plait-space-xs)); left: 0;
  min-width: max-content; grid-template-columns: 1fr; padding: var(--plait-space-xs); border: 1px solid color-mix(in srgb, var(--plait-color-accent) 35%, transparent);
  border-radius: var(--plait-radius-md); background: color-mix(in srgb, var(--plait-color-surface-elevated) 92%, transparent);
  backdrop-filter: blur(var(--plait-space-sm)); -webkit-backdrop-filter: blur(var(--plait-space-sm)); }
/* closed, the choices are not drawn at all: the browser would still lay them out in the icon's width, where they reach
   out of their list (service-8 2026-10-20, Checked: "scrolls-sideways" 16 to 99 px on every closed menu of the Leitstand);
   important, because a menu's own panel rule (the entry menu, the scene's detail) sets its display and must not open it */
.segments-menu:not([open]) > .segments-options { display: none !important; }
.segments-menu > .segments-options[data-intrinsic="series"] { grid-auto-flow: column; grid-auto-columns: max-content; column-gap: var(--plait-space-xs); }
.segments-menu > .segments-options .segments-choice { position: relative; display: flex; align-items: center; min-height: var(--plait-control-height); cursor: pointer; }
/* the held one is the accent edge (as in a list), so the radio is not drawn; it stays the control the keyboard reaches */
.segments-menu > .segments-options .segments-radio { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.segments-menu > .segments-options .segments-choice:has(.segments-radio:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* Auftrag 35 (A5): a piece that could not reach its data says so in the MIDDLE of its cell, the way out below it. */
.piece[data-state="not-reached"] { display: grid; grid-template-rows: auto 1fr; }
.state-notice { display: grid; align-content: center; justify-items: center; gap: var(--plait-space-sm); text-align: center; padding: var(--plait-space-lg) var(--plait-space-md); }
/* Auftrag 38b: in a narrow cell (the controls of a mini player) the notice wraps inside its cell, never past it */
.state-notice, .state-notice > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.state-notice > .state.not-reached { padding: 0; font-size: var(--plait-type-title-size); color: var(--plait-color-text); }
.state-way { margin: 0; color: var(--plait-color-text-muted); }
/* a chevron pointing UP, where the choice is: two edges of a square, turned, drawn and never read aloud */
.state-way::before {
  content: ""; display: block; margin: 0 auto var(--plait-space-md);
  width: var(--plait-space-md); height: var(--plait-space-md);
  border-left: 2px solid var(--plait-color-accent); border-top: 2px solid var(--plait-color-accent);
  transform: rotate(45deg);
}
.carrier-refused { margin: 0; flex-basis: 100%; font-size: var(--plait-type-caption-size); color: var(--plait-color-danger-text, var(--plait-color-danger)); }
/* anzug-je-organisation Etappe 3: a setting the organisation fixed (the suit) is said beside its disabled choices, in the muted script: no danger, nothing refused */
.carrier-fixed { margin: 0; flex-basis: 100%; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.canvas-decor { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
/* Order 33, step 6: the check. Every device a column of its own, as wide as the room allows; each stage made smaller to fit (fit). */
/* Auftrag 35 (A4): a column of the check is a column of the EDITOR, so its least width follows the window step. */
.block-stages { display: grid; gap: var(--plait-space-md); grid-template-columns: repeat(auto-fill, minmax(calc(var(--plait-device-small-short) / 2 * var(--plait-step-scale)), 1fr)); align-items: start; }
.block-stages[data-intrinsic="one_below_another"] { grid-template-columns: minmax(0, 1fr); }
.stages-device { margin: 0; display: grid; gap: var(--plait-space-xs); min-width: 0; }
.stages-name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.stages-stage { min-width: 0; overflow: auto; }
/* PLAIT Render (RULE-033): every device in both modes side by side; the sheet wraps, each stage made smaller to its room (fit) or at its own pixels (actual, the stage scrolls). Tokens only. */
.block-render-stages { display: grid; gap: var(--plait-space-sm); min-width: 0; }
.render-stages-turn-all { justify-self: start; }
.render-stages-sheet { display: grid; gap: var(--plait-space-md); grid-template-columns: repeat(auto-fill, minmax(calc(var(--plait-device-small-short) * var(--plait-step-scale)), 1fr)); align-items: start; }
.block-render-stages[data-intrinsic="one_below_another"] .render-stages-sheet { grid-template-columns: minmax(0, 1fr); }
.render-stages-device { margin: 0; display: grid; gap: var(--plait-space-xs); min-width: 0; }
.render-stages-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-sm); }
.render-stages-name { flex: 1 1 auto; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.render-stages-stage { min-width: 0; overflow: auto; }
.block-screen-measure { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
.stage-check { margin: var(--plait-space-xs) 0 0; font-size: var(--plait-type-caption-size); }
.stage-check[data-stage-check="yes"] { color: var(--plait-color-ok); }
.stage-check[data-stage-check="no"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.stage-check[data-stage-check="unknown"] { color: var(--plait-color-text-muted); }
.block-checklist { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--plait-space-xs); }
.block-checklist .check { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-checklist .check-tier { font-size: var(--plait-type-caption-size); }
/* step 7 (a): the sentence takes the rest of the row and wraps inside it, never below its tier */
.block-checklist .check-text { flex: 1 1 0; min-width: 0; }
.block-checklist .tier-ok .check-tier { color: var(--plait-color-ok); }
.block-checklist .tier-warning .check-tier { color: var(--plait-color-warn); }
.block-checklist .tier-danger .check-tier { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.checklist-empty { margin: 0; color: var(--plait-color-text-muted); }
.carrier-warning { margin: var(--plait-space-xs) 0 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-warn); }
/* Order 33, step 8: a key figure is its number and what it counts, side by side with a gap between (never glued) */
.block-key-figure { display: grid; gap: var(--plait-space-xs); }
.block-key-figure .key_figure { display: flex; align-items: baseline; gap: var(--plait-space-sm); }
.block-key-figure .number { font-weight: var(--plait-type-label-weight); min-width: var(--ergonomics-target-size); text-align: end; }
/* 2026-10-24 (the home screen's hour was a small card): the clock look, the value large and thin above its line, centred;
   thin as every suit's title, in the figure size of every suit. */
.block-key-figure[data-look="clock"] { justify-items: center; text-align: center; }
.block-key-figure[data-look="clock"] .key_figure { flex-direction: column; align-items: center; gap: var(--plait-space-xs); }
.block-key-figure[data-look="clock"] .number { min-width: 0; text-align: center; font-size: calc(var(--plait-type-figure-size) * 2.5); font-weight: var(--plait-type-title-weight); line-height: 1; letter-spacing: 0.02em; color: var(--plait-color-text); }
.block-key-figure[data-look="clock"] .what_for { color: var(--plait-color-text-muted); font-size: var(--plait-type-body-size); }
/* plait-app-0161: PLAIT One's hour, as today's start page draws it: very large, the suit's thinnest weight
   (`--plait-type-figure-weight`, Light 300 in One; a thinner clock weight is a value of PLAIT Suits, not set here), the text a little muted; and its
   day alone, quiet, at the end of its box */
.block-key-figure[data-look="hour"] { justify-items: center; text-align: center; }
.block-key-figure[data-look="hour"] .key_figure { justify-content: center; }
.block-key-figure[data-look="hour"] .number { min-width: 0; text-align: center; font-family: "PLAIT UI", Roboto, var(--plait-type-ui-family); font-size: calc(var(--plait-type-figure-size) * 3.4); font-weight: var(--plait-type-figure-weight);
  line-height: 1; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; color: color-mix(in srgb, var(--plait-color-text) 88%, transparent); }
.block-key-figure[data-look="caption"] { justify-items: end; text-align: end; }
.block-key-figure[data-look="caption"] .key_figure { justify-content: flex-end; }
.block-key-figure[data-look="caption"] .what_for { color: var(--plait-color-text); font-size: var(--plait-type-label-size); font-weight: var(--plait-type-body-weight); }

/* ══ Auftrag 38a (PLAIT Music, the foundation; the owner's template `musicplayer-clean`: quiet, flat, one blue
   accent, never violet). Every size is a token or a measure of the content, every colour a token measured by
   suit-pairs.ts, every movement a motion token, and every movement stops when the device asks for less (below). */

/* a field without a label has no heading line (the clean template names a group by a text of step label) */
.piece > h3:empty { display: none; }

/* L12 · the steps of the type a text stands on */
.block-text.role-title { font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); line-height: var(--plait-type-body-line-height); color: var(--plait-color-text); }
.block-text.role-subline { color: var(--plait-color-text-muted); }
.block-text.role-label {
  font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-label-weight); letter-spacing: var(--plait-type-tracking-label);
  text-transform: uppercase; color: var(--plait-color-text-muted);
  padding-bottom: var(--plait-space-xs); border-bottom: 1px solid var(--plait-color-divider);
}
.block-text.role-caption { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* Teil AB: the sentence under a heading, in the same field, says what the field is (`text` with `sentence`) */
.block-text-with-sentence > .role-caption { padding-top: var(--plait-space-sm); }

/* L2 · the cover: the initial on its tone, a foreign picture laid over it only when the carrier showed one */
.block-cover { display: flex; justify-content: center; padding: var(--plait-space-xl) 0; }
/* a cover lays its field open, so a light behind it (the glow, decor below the boxes) shows around it */
.piece[data-block="cover"] { background: transparent; }
.cover {
  position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; overflow: hidden;
  aspect-ratio: 1; border-radius: var(--plait-radius-sm); background: var(--plait-color-cover-graphite); color: var(--plait-color-text-muted);
}
.cover[data-tone="slate"] { background: var(--plait-color-cover-slate); }
.cover[data-tone="moss"] { background: var(--plait-color-cover-moss); }
.cover[data-tone="rust"] { background: var(--plait-color-cover-rust); }
.cover[data-tone="steel"] { background: var(--plait-color-cover-steel); }
.cover[data-tone="sand"] { background: var(--plait-color-cover-sand); }
.cover[data-cover="large"] { width: min(100%, var(--plait-cover-largest)); }
.cover[data-cover="small"] { width: var(--plait-cover-small); }
.cover-initial { font-weight: var(--plait-type-body-weight); font-size: var(--plait-type-title-size); line-height: 1; }
.cover[data-cover="large"] .cover-initial { font-size: calc(var(--plait-cover-largest) / 5); font-weight: var(--plait-type-body-weight); }
.cover-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cover-image:not([src]), .cover-image[data-image-state="failed"] { display: none; }

/* L1 · rows with a picture on the left: air between them, no frame per row */
.block-media-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--plait-space-xs); }
.block-media-list .media-handle {
  display: flex; align-items: center; gap: var(--plait-space-md); width: 100%; height: auto; padding: var(--plait-space-sm) 0;
  background: transparent; border: 0; border-radius: 0; color: var(--plait-color-text); font: inherit; text-align: start;
}
.block-media-list button.media-handle { cursor: pointer; }
.block-media-list .media-text { flex: 1; min-width: 0; display: grid; gap: var(--plait-space-xs); }
.block-media-list .media-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--plait-color-text); }
.block-media-list .media-subline { display: flex; gap: var(--plait-space-sm); min-width: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-media-list .media-trailing { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
/* Auftrag AA: what a press on a row does, and what became of the last press: two quiet lines above the rows, never a row */
/* owner 2026-11-03 (PLAIT Pixel, ./render/project-folders.ts): the presses of a list whose rows open in place, and the name of a new folder */
.block-media-list .media-folders-bar { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-media-list .media-folders-press { min-height: var(--ergonomics-target-size); }
.block-media-list .media-folders-form form { display: flex; gap: var(--plait-space-xs); min-width: 0; }
.block-media-list .media-folders-form input { flex: 1 1 auto; min-width: 0; min-height: var(--ergonomics-target-size); }
.block-media-list .media-press, .block-media-list .media-outcome { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); min-width: 0; overflow-wrap: anywhere; }
/* the ACTIVE row: the accent in its title and a still mark, never a filled row */
.block-media-list .media-row[data-active="yes"] .media-title { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-media-list .media-active { display: inline-flex; align-items: flex-end; gap: calc(var(--plait-space-xs) / 2); height: var(--plait-type-caption-size); }
.block-media-list .media-active i {
  display: block; width: calc(var(--plait-space-xs) / 2); height: 100%; background: var(--plait-color-accent); transform-origin: bottom;
  animation: media-equalizer var(--plait-motion-equalizer) ease-in-out infinite;
}
.block-media-list .media-active i:nth-child(2) { animation-delay: calc(var(--plait-motion-equalizer) / -2); }
.block-media-list .media-active i:nth-child(3) { animation-delay: calc(var(--plait-motion-equalizer) / -3); }
@keyframes media-equalizer { 0%, 100% { transform: scaleY(0.35); } 50% { transform: scaleY(1); } }
/* a row whose work is under way (mark tone `running`, owner 2026-10-19): the dot breathes in the accent, the word stays still */
.block-media-list .media-mark[data-sound="running"] .media-mark-dot { display: inline-block; animation: media-running var(--plait-motion-equalizer) ease-in-out infinite; }
@keyframes media-running { 0%, 100% { opacity: 0.25; transform: scale(0.7); } 50% { opacity: 1; transform: scale(1.25); } }
@media (prefers-reduced-motion: reduce) { .block-media-list .media-mark[data-sound="running"] .media-mark-dot { animation: none; } }
/* the live view of PLAIT Sketch (owner 2026-10-19): the step working now above the pictures, its dot breathing the same way */
.block-picture-viewer-live { display: flex; flex-direction: column; gap: var(--plait-space-xs); min-height: 0; height: 100%; }
.block-picture-viewer-live > .block-picture-viewer { flex: 1; min-height: 0; }
.picture-viewer-now { display: flex; align-items: center; gap: var(--plait-space-xs); margin: 0; color: var(--plait-color-text-muted); }
.picture-viewer-now-dot { flex: none; width: 0.6em; height: 0.6em; border-radius: 50%; background: var(--plait-color-accent); animation: media-running var(--plait-motion-equalizer) ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .picture-viewer-now-dot { animation: none; } }
/* the trace player of PLAIT Sketch (owner 2026-10-19): one screen, the picture takes what is left, nothing scrolls but the detail */
.block-trace-player { display: flex; flex-direction: column; gap: var(--plait-space-xs); height: 100%; min-height: 0; }
.block-trace-player .trace-choice { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); flex: none; }
.block-trace-player .trace-pick { border: 1px solid var(--plait-color-border); background: var(--plait-color-surface); color: var(--plait-color-text); border-radius: var(--plait-control-radius); padding: var(--plait-space-xs) var(--plait-space-sm); font: inherit; }
.block-trace-player .trace-pick[aria-pressed="true"] { border-color: var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-trace-player .trace-running { display: flex; align-items: center; gap: var(--plait-space-xs); margin: 0; color: var(--plait-color-text-muted); flex: none; }
.block-trace-player .trace-rule { flex: none; font-size: var(--plait-type-label-size); }
.block-trace-player .trace-rule b { display: block; }
.block-trace-player .trace-values { flex: none; margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); font-variant-numeric: tabular-nums; }
.block-trace-player .trace-stage { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; background: var(--plait-color-surface-elevated); border-radius: var(--plait-radius-sm); overflow: hidden; }
.block-trace-player .trace-frame { position: relative; max-width: 100%; max-height: 100%; width: 100%; aspect-ratio: 4 / 3; }
.block-trace-player .trace-frame img, .block-trace-player .trace-frame canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
.block-trace-player .trace-frame img[hidden] { display: none; }
.block-trace-player .trace-keys { display: flex; align-items: center; gap: var(--plait-space-xs); flex: none; }
.block-trace-player .trace-key { flex: none; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); border: 1px solid var(--plait-color-border); background: var(--plait-color-surface); color: var(--plait-color-text); border-radius: var(--plait-control-radius); font: inherit; }
.block-trace-player .trace-key[aria-pressed="true"] { border-color: var(--plait-color-accent); }
.block-trace-player .trace-slider { flex: 1; min-width: 0; accent-color: var(--plait-color-accent); }
.block-trace-player .trace-count { flex: none; font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
.block-trace-player .trace-detail { flex: none; max-height: 30%; overflow-y: auto; font-size: var(--plait-type-caption-size); }

/* L3 · the slider: the browser's own range in the accent; the clock beside it in the quiet tone */
.block-slider { display: grid; gap: var(--plait-space-xs); }
.block-slider .slider-input { width: 100%; height: auto; margin: 0; padding: 0; border: 0; background: transparent; accent-color: var(--plait-color-accent); }
.block-slider .slider-times { display: flex; justify-content: space-between; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); font-variant-numeric: tabular-nums; }

/* L4, L5 · a button with an icon: the icon from the carrier's icon set, quiet; the active switch in the accent */
.icon { display: inline-flex; flex: none; width: var(--plait-size-icon); height: var(--plait-size-icon); }
.icon svg { width: 100%; height: 100%; fill: currentColor; }
/* owner 2026-10-22: an icon drawn as a LINE (Crew's send arrow, `line: true`): the current colour along the path, round
   ends, as `ArrowUpIcon` (@plait/ui-web chat-composer.tsx) draws it */
.icon svg[data-line="yes"] { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2.5; }
.button.with-icon { display: inline-flex; align-items: center; justify-content: center; gap: var(--plait-space-sm); }
.button.secondary.with-icon { background: transparent; border-color: transparent; color: var(--plait-color-text-muted); }
.button.secondary.with-icon:hover { color: var(--plait-color-text); }
.button.with-icon.active { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.button.icon-only { width: var(--plait-control-height); padding: 0; }
/* the one filled circle of the template: the primary action as a round accent */
.button.primary.icon-only {
  width: calc(var(--plait-control-height) * 1.75); height: calc(var(--plait-control-height) * 1.75); border-radius: 50%;
  background: var(--plait-color-accent); border-color: var(--plait-color-accent); color: var(--plait-color-on-accent);
  transition: transform var(--plait-motion-quick) var(--plait-motion-ease);
}
.button.primary.icon-only:active { transform: scale(0.96); }
.block-button:has(.with-icon) { display: flex; align-items: center; justify-content: center; gap: var(--plait-space-xl); flex-wrap: wrap; }

/* L13 · a tile with a second line */
.block-tile-grid .tile_handle:has(.tile_subline) { display: grid; align-content: center; gap: var(--plait-space-xs); }
.block-tile-grid .tile_subline { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* planner-34 (Master 2026-11-09): read from far (the page says `data-viewing-distance="far"`, ./render/remote.ts, with the
   remote), a tile is at least ergonomics.json `far-tile-size` wide and its text `far-type-size` high, as the owner saw PLAIT
   TV at the 75-inch television. How many stand side by side follows from that width, so the grid walk counts the DRAWN
   columns (./render/walk.ts). Every look of the grid alike, no surface named; after the looks, so it wins over them. */
[data-viewing-distance="far"] .block-tile-grid[data-columns] { grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--ergonomics-far-tile-size)), 1fr)); }
[data-viewing-distance="far"] .block-tile-grid .tile_handle, [data-viewing-distance="far"] .block-tile-grid .tile_name,
[data-viewing-distance="far"] .block-tile-grid .tile_subline { font-size: var(--ergonomics-far-type-size); }

/* the glow behind a cover (decorating, E40): a soft light, breathing slowly where the surface names a motion */
.decor-glow { position: absolute; inset: 0; background: radial-gradient(closest-side, var(--decor-color) 70%, transparent); filter: blur(var(--plait-space-xl)); }
.decor-glow[data-decor-motion] { animation: decor-breathe var(--decor-motion) ease-in-out infinite; }
/* plait-app-0161 (owner 2026-10-24, "4: ja"): the dust-field, PLAIT's gold dust as a decorating block. A quiet nebula of the
   haze token, and three layers of grains in the suit's gold, far to near: each a square tile of its own size holding
   four grains at uneven places (so no grid shows), the nearer the larger, brighter and faster. Middle and near lie in a
   slanting band, the galaxy's arm; the far grains everywhere. With a motion each layer drifts one tile diagonally per
   turn (so the turn is seamless) at its own pace; with less motion everything stands. */
/* the dust is the ground of the WHOLE screen, under the bars too: it stands fixed to the window, not to its anchor (a
   decor layer cuts nothing that is fixed), so the field reaches every edge whatever padding the page keeps */
.decor-dust { position: fixed; inset: 0; overflow: hidden;
  background: radial-gradient(130% 60% at 88% 8%, var(--decor-haze), transparent 62%), radial-gradient(110% 55% at 6% 94%, var(--decor-haze), transparent 66%); }
.decor-dust-layer { position: absolute; inset: -260px; --t: 113px; --g: 0.7px; --g2: 1.3px; opacity: 0.38; --grain: var(--plait-color-accent);
  background-image:
    radial-gradient(circle at 17% 23%, var(--grain) 0 var(--g), transparent var(--g2)),
    radial-gradient(circle at 71% 9%, var(--grain) 0 var(--g), transparent var(--g2)),
    radial-gradient(circle at 43% 67%, var(--grain) 0 var(--g), transparent var(--g2)),
    radial-gradient(circle at 88% 81%, var(--grain) 0 var(--g), transparent var(--g2));
  background-size: var(--t) var(--t); }
.decor-dust-layer[data-layer="middle"] { --t: 157px; --g: 1px; --g2: 1.6px; opacity: 0.55;
  -webkit-mask-image: linear-gradient(162deg, transparent 12%, #000 38%, #000 62%, transparent 88%); mask-image: linear-gradient(162deg, transparent 12%, #000 38%, #000 62%, transparent 88%); }
.decor-dust-layer[data-layer="near"] { --t: 211px; --g: 1.3px; --g2: 1.9px; opacity: 0.8;
  -webkit-mask-image: linear-gradient(162deg, transparent 22%, #000 44%, #000 56%, transparent 78%); mask-image: linear-gradient(162deg, transparent 22%, #000 44%, #000 56%, transparent 78%); }
.decor-dust[data-decor-motion] .decor-dust-layer { animation: decor-dust-drift var(--decor-motion) linear infinite; }
.decor-dust[data-decor-motion] .decor-dust-layer[data-layer="middle"] { animation-duration: calc(var(--decor-motion) * 0.75); }
.decor-dust[data-decor-motion] .decor-dust-layer[data-layer="near"] { animation: decor-dust-drift calc(var(--decor-motion) * 0.5) linear infinite, decor-dust-glint calc(var(--decor-motion) * 0.15) ease-in-out infinite; }
@keyframes decor-dust-glint { 0%, 100% { opacity: 0.8; } 50% { opacity: 0.45; } }
@keyframes decor-dust-drift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(calc(var(--t) * -1), calc(var(--t) * -1), 0); } }
@media (prefers-reduced-motion: reduce) { .decor-dust .decor-dust-layer { animation: none !important; } }
/* plait-app-0161: the word-mark, the brand's shape as a mask over the suit's wordmark brush (gold.css of the add-in in
   values: brush 1..7, gleam, halo), at the height the suit names for a head's mark. */
.decor-wordmark { position: absolute; inset: 0; --wm-h: calc(var(--plait-type-title-size) * 1.05); }
.decor-wordmark > span { position: absolute; top: 50%; height: var(--wm-h); aspect-ratio: 576 / 88.435; transform: translateY(-50%);
  -webkit-mask: var(--decor-mask) center / contain no-repeat; mask: var(--decor-mask) center / contain no-repeat; }
.decor-wordmark[data-decor-place="start"] > span { left: 0; }
.decor-wordmark[data-decor-place="center"] > span { left: 50%; transform: translate(-50%, -50%); }
.decor-wordmark[data-decor-place="end"] > span { right: 0; }
.decor-wordmark-brush { background: linear-gradient(90deg, var(--plait-wordmark-brush-1, var(--plait-color-accent)), var(--plait-wordmark-brush-2, var(--plait-color-accent)) 15%, var(--plait-wordmark-brush-3, var(--plait-color-accent)) 31%, var(--plait-wordmark-brush-4, var(--plait-color-accent)) 50%, var(--plait-wordmark-brush-5, var(--plait-color-accent)) 69%, var(--plait-wordmark-brush-6, var(--plait-color-accent)) 85%, var(--plait-wordmark-brush-7, var(--plait-color-accent)));
  background-size: 200% 100%; }
.decor-wordmark-gleam { background: linear-gradient(105deg, transparent 30%, var(--plait-wordmark-gleam, transparent) 50%, transparent 66%); background-size: 300% 100%; background-repeat: no-repeat; background-position: 120% 0; mix-blend-mode: screen; opacity: 0.85; }
.decor-wordmark-halo { background: var(--plait-wordmark-halo, var(--plait-color-accent)); filter: blur(var(--plait-space-sm)); opacity: 0.35; }
.decor-wordmark[data-decor-motion] .decor-wordmark-brush { animation: decor-wordmark-drift calc(var(--decor-motion) * 0.18) linear infinite; }
.decor-wordmark[data-decor-motion] .decor-wordmark-gleam { animation: decor-wordmark-gleam calc(var(--decor-motion) * 0.09) linear infinite; }
@keyframes decor-wordmark-drift { from { background-position: 0% 0; } to { background-position: 200% 0; } }
@keyframes decor-wordmark-gleam { 0%, 45% { background-position: 120% 0; } 100% { background-position: -120% 0; } }
@media (prefers-reduced-motion: reduce) { .decor-wordmark > span { animation: none !important; } }
/* on a light suit the brush's pale gold would vanish into the page: the same brush, deepened; the gleam stays faint */
:root[data-topic$="light"] .decor-wordmark-brush { background-image: linear-gradient(90deg, color-mix(in srgb, var(--plait-wordmark-brush-1, var(--plait-color-accent)) 55%, var(--plait-color-text)), color-mix(in srgb, var(--plait-wordmark-brush-3, var(--plait-color-accent)) 55%, var(--plait-color-text)) 31%, color-mix(in srgb, var(--plait-wordmark-brush-4, var(--plait-color-accent)) 55%, var(--plait-color-text)) 50%, color-mix(in srgb, var(--plait-wordmark-brush-6, var(--plait-color-accent)) 55%, var(--plait-color-text)) 85%, color-mix(in srgb, var(--plait-wordmark-brush-7, var(--plait-color-accent)) 55%, var(--plait-color-text))); }
:root[data-topic$="light"] .decor-wordmark-gleam { opacity: 0.35; }
@keyframes decor-breathe { 0%, 100% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.06); } }

/* L7 · the FOOT of the application (the mini player), below every area. 🔴 Auftrag 38d (b): it stands IN THE FLOW of
   the docked carrier (below), between the area and the bar, never over the area and never fixed to the window. */
.foot {
  position: relative; z-index: 2; margin: var(--plait-foot-gap); display: grid; gap: var(--plait-space-sm); padding: var(--plait-space-sm) var(--plait-space-md);
  background: var(--plait-foot-ground); border: 1px solid var(--plait-color-divider); border-radius: var(--plait-radius-lg);
  backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass);
  animation: foot-in var(--plait-motion-float-in) var(--plait-motion-ease) both;
}
.foot[data-empty="yes"] { display: none; }
/* 🔴 owner 2026-10-31 ("der globale hinzufügen/anlegen-button ... footer links unten"): the CARRIER's create button
   (./render/create.ts), bottom left at the same place on every area, in the suite's send material (the gold circle);
   lifted above the docked foot and bar (`--create-lift`, measured by the carrier); hidden where the area opens nothing */
.create {
  position: fixed; z-index: 3; padding: 0; cursor: pointer;
  left: calc(var(--plait-space-md) + env(safe-area-inset-left, 0px));
  bottom: calc(var(--create-lift, 0px) + var(--plait-space-md) + env(safe-area-inset-bottom, 0px));
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); border-radius: var(--plait-radius-symbol-button, 999px);
}
.create[hidden] { display: none; }
.create .icon { width: 1.25rem; height: 1.25rem; display: block; }
.create .icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
[data-page-view="open"] > .create { visibility: hidden; }
/* Auftrag 38c: every piece of the foot says only what the area already says: the foot is folded away, it takes no room */
.foot[data-folded="yes"] { display: none; }
.foot .piece { background: transparent; border: 0; padding: 0; }
/* Teil W: no `overflow: hidden` on the foot's cells any more; it hid the scroll bar a rounding made, and the cell
   measured to its content (./render/layout.ts) no longer needs it */
/* Auftrag 38b: in the foot a piece that could not reach its data says it in ONE short line: its word in the caption
   size, wrapped inside its cell, without the way out (the area above says it whole) */
.foot .state-notice { padding: 0; justify-items: start; text-align: start; }
.foot .state-notice > .state.not-reached { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); overflow-wrap: anywhere; }
.foot .state-way { display: none; }
/* Auftrag 38d (e): the mini player's position is the line along its edge (fx-08), without the clock of the large one */
.foot .slider-times { display: none; }
@keyframes foot-in { from { opacity: 0; transform: translateY(var(--plait-space-md)); } to { opacity: 1; transform: none; } }

/* L8 · the bar of areas at the bottom */
.variant.bottom_bar { width: 100%; flex-wrap: nowrap; gap: 0; }
.bottom_tab {
  flex: 1; height: var(--plait-bottom-room); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--plait-space-xs);
  background: transparent; border: 0; border-radius: 0; color: var(--plait-color-text-muted);
  font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-label-weight); letter-spacing: var(--plait-type-tracking-label); text-transform: uppercase;
  transition: color var(--plait-motion-quick) var(--plait-motion-ease);
}
/* Auftrag 38b: five areas stand on one line of a phone: the name in its own case on one line, never cut into two */
.variant.bottom_bar .bottom_tab { min-width: 0; padding-inline: var(--plait-space-xs); text-transform: none; letter-spacing: normal; white-space: nowrap; }
.bottom_tab:hover { color: var(--plait-color-text); }
.bottom_tab.active { color: var(--plait-color-text); }
/* owner 2026-10-19 06:09 ("der application-footer … immer noch zu hoch. Plus hässlich. Mach da denselben goldenen
   unterstrich wie bei den tabs im header."): no dot under the word; the active tab's mark is the header's line, the
   accent fading out to both ends with its light rising from it, at the bar's foot */
.bottom_tab { position: relative; }
.bottom_mark {
  position: absolute; left: 18%; right: 18%; bottom: 0; height: 2px; background: transparent;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 16%, black 84%, transparent); mask-image: linear-gradient(90deg, transparent, black 16%, black 84%, transparent);
}
.bottom_tab.active .bottom_mark { background: var(--plait-color-accent); box-shadow: 0 calc(var(--plait-space-xs) * -1) var(--plait-space-md) var(--plait-color-accent-glow); }

/* 🔴 Owner 2026-10-25 (the Schachbrett, ./render/board-turn.ts): the kind `board` draws one quiet mark per area at the
   bottom, the active one lit in the accent; the areas turn by strokes of the finger. A turn lets the area leave to the
   side the finger went and the next come from the other side, in the quick motion; at once where less motion is asked. */
.variant.board { width: 100%; display: flex; justify-content: center; align-items: center; gap: var(--plait-space-sm); flex-wrap: nowrap; }
.board_mark { display: inline-flex; align-items: center; justify-content: center; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size);
  padding: 0; border: 0; background: transparent; cursor: pointer; }
.board_mark:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.board_dot { width: var(--plait-space-sm); height: var(--plait-space-sm); border-radius: 50%; background: var(--plait-color-text-muted); opacity: 0.6; }
.board_mark.active .board_dot { background: var(--plait-color-accent); opacity: 1; box-shadow: 0 0 var(--plait-space-sm) var(--plait-color-accent-glow); }
/* plait-app-0174: the marks DRAW the board (./render/board-turn.ts `layMarks`): each stands in the column and row where its
   page lies, main pages one under the other, side pages beside the middle, sub pages below them; a cell half a touch target */
.variant.board[data-board-laid="yes"] { display: grid; justify-content: center; align-content: center; gap: 0;
  grid-template-columns: repeat(var(--board-columns, 1), calc(var(--ergonomics-target-size) * 0.6));
  grid-template-rows: repeat(var(--board-rows, 1), calc(var(--ergonomics-target-size) * 0.6)); }
.variant.board[data-board-laid="yes"] > .board_mark { min-width: 0; min-height: 0; width: 100%; height: 100%; }
[data-docked="yes"] > .level:has(> .variant.board) { order: 3; padding: 0; padding-bottom: max(0px, env(safe-area-inset-bottom, 0px) - var(--plait-page-below), var(--plait-bar-bottom) - var(--plait-keyboard-height)); }
[data-board-leave], [data-board-enter] { overflow: hidden; }
[data-board-leave] { transition: transform var(--plait-motion-quick) var(--plait-motion-ease), opacity var(--plait-motion-quick) var(--plait-motion-ease); opacity: 0; }
[data-board-leave="right"] { transform: translateX(-100%); }
[data-board-leave="left"] { transform: translateX(100%); }
[data-board-leave="down"] { transform: translateY(-100%); }
[data-board-leave="up"] { transform: translateY(100%); }
[data-board-enter] { animation: var(--plait-motion-quick) var(--plait-motion-ease) both; }
[data-board-enter="right"] { animation-name: board-from-right; }
[data-board-enter="left"] { animation-name: board-from-left; }
[data-board-enter="down"] { animation-name: board-from-below; }
[data-board-enter="up"] { animation-name: board-from-above; }
@keyframes board-from-right { from { transform: translateX(100%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes board-from-left { from { transform: translateX(-100%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes board-from-below { from { transform: translateY(100%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes board-from-above { from { transform: translateY(-100%); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { [data-board-leave], [data-board-enter] { transition: none; animation: none; } }

/* 🔴 Auftrag 38d (b): THE DOCKED CARRIER (`data-docked`, set by the host for an application with a foot or a bar at
   the bottom). A column exactly as tall as its place: the window here, the element standing for the document in a
   portal (`.stage-frame[data-plait-page]`, below). The area is the ONE box that scrolls; the foot and the bar stand
   below it in the flow, so they stay at the bottom whatever scrolls, and the area ends above them. */
[data-docked="yes"] { display: flex; flex-direction: column; height: 100dvh; overflow: hidden; }
[data-docked="yes"] > * { flex: none; }
[data-docked="yes"] > .area { order: 1; flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* Teil W: the lane for the bar is kept only where a bar TAKES room (a screen without touch: the boxes are laid at
   the width the area has, and a bar coming later would take it from them); a touch screen's bar lies over the
   content and needs no lane, and a lane there is a standing bar at the side */
@media not all and (pointer: coarse) { [data-docked="yes"] > .area { scrollbar-gutter: stable; } }
[data-docked="yes"] > .foot { order: 2; }
/* 🔴 Owner 2026-10-11 ("Also dass immer eine ganze Seite geblättert wird", D10 of the design standard): the areas of
   the bar at the bottom are PAGES side by side (./render/pages.ts). The browser turns them, as on the PLAIT Ship page:
   a scroller sideways that snaps to whole pages and stops at EVERY page, however fast the swipe; no script moves them.
   Each page is as wide as the place; up and down rolls the area inside it, never the pages. A picture of a page left
   (`data-picture`) does not roll and can do nothing. */
[data-docked="yes"] > .pages {
  order: 1; flex: 1 1 auto; min-height: 0; display: flex; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none;
}
[data-docked="yes"] > .pages::-webkit-scrollbar { display: none; }
.pages > .page {
  flex: 0 0 100%; min-width: 100%; min-height: 0; display: flex; flex-direction: column;
  scroll-snap-align: start; scroll-snap-stop: always;
}
/* the area rolls up and down only; sideways a swipe goes on to the pages (`overscroll-behavior-x` stays `auto`) */
.pages > .page > .area { flex: 1 1 auto; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: contain; }
@media not all and (pointer: coarse) { .pages > .page > .area:not([data-picture]) { scrollbar-gutter: stable; } }
.pages > .page > .area[data-picture] { overflow-y: hidden; }
[data-docked="yes"] > .level:has(> .variant.bottom_bar) {
  order: 3; padding: 0; padding-bottom: max(0px, env(safe-area-inset-bottom, 0px) - var(--plait-page-below), var(--plait-bar-bottom) - var(--plait-keyboard-height));
  background: var(--plait-bar-ground); border-top: 1px solid var(--plait-color-divider);
  backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass);
}
/* 🔴 plait-app-0161 (owner 2026-10-24 19:39, "2: ja"): THE KEYBOARD AND THE BARS, as the PLAIT App tells them
   (apps/plait/contract/bridge/keyboard-height.json). The docked column ends where the keyboard begins, so nothing the
   person needs lies under it and the page still never scrolls; a page drawn under the bars (PLAIT One) keeps its first
   box below the status bar and its foot above the navigation bar. Without the app every variable is absent and 0. */
:root { --plait-keyboard-height: 0px; --plait-bar-top: 0px; --plait-bar-bottom: 0px; --plait-inset-top: 0px; --plait-inset-bottom: 0px; }
[data-docked="yes"] { height: calc(100dvh - var(--plait-keyboard-height)); }
[data-docked="yes"] .pages > .page > .area { padding-top: calc(var(--plait-space-md) + var(--plait-bar-top)); }
/* owner 2026-11-04 01:52 ("1: ja"): a page with NO header above it (app.ts `data-headerless`) keeps the status bar free
   itself, never its first row under the clock. The status bar is what the window says (`env(safe-area-inset-top)`) or what
   the PLAIT App tells (`--plait-inset-top`); a page drawn under the bars that already pads its area by `--plait-bar-top`
   (PLAIT One) is not padded twice. */
[data-headerless="yes"] { box-sizing: border-box; padding-top: max(0px, max(env(safe-area-inset-top, 0px), var(--plait-inset-top, 0px)) - var(--plait-bar-top, 0px)); }

/* ══ Auftrag 38d (c, e): PLAIT Music after the owner's templates (`musicplayer-clean` the direction, `musicplayer-effects`
   the effects where the carrier carries them): every size a token or a measure, every colour a token, every movement a
   motion token that stops when the device asks for less (one rule, below). */

/* a) the one sentence of an area whose read answered nothing (./render/empty.ts): read in the body's size and the text
   colour, in the middle of its cell, never a small grey box */
/* plait-app-0174: a notice in a cell where a decor (the word mark) stands at the top begins BELOW it, never over it
   (./render/decor.ts `keepClear`: the cell carries how far down the decor reaches) */
.layout .cell[data-decor-clear="top"] .state-notice { align-content: start; justify-items: start; text-align: start; padding: calc(var(--decor-clear-top, 0) + var(--plait-space-xs)) 0 0; }
.layout .cell[data-decor-clear="top"] .state-notice > .state.not-reached { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.state-notice.empty-notice > .state.empty { padding: 0; font-size: var(--plait-type-body-size); color: var(--plait-color-text); }
.piece:has(> .empty-notice) { background: transparent; border-color: transparent; }
/* Owner 2026-10-19 (PLAIT Assistant as PLAIT Crew): an empty conversation says so quietly, small and low, right above
   the composer it points to, never as a large paragraph in the middle of the page */
.piece[data-block="chat"] > .empty-notice { align-content: end; padding: var(--plait-space-md) var(--plait-space-lg); }
.piece[data-block="chat"] > .empty-notice > .state.empty { max-width: 36ch; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }

/* e) the hover of a row: a quiet ground that comes and goes (fx: "Hover-Uebergaenge"), never a frame */
.block-media-list button.media-handle {
  border-radius: var(--plait-radius-sm);
  transition: background-color var(--plait-motion-quick) var(--plait-motion-ease), box-shadow var(--plait-motion-quick) var(--plait-motion-ease);
}
/* the ground reaches a little past the row by a shadow, never by a wider box: a row as wide as its cell never makes the cell roll */
.block-media-list button.media-handle:hover, .block-media-list button.media-handle:focus-visible {
  background: var(--plait-hover-ground); box-shadow: 0 0 0 var(--plait-space-xs) var(--plait-hover-ground);
}
.block-tile-grid .tile { transition: border-color var(--plait-motion-quick) var(--plait-motion-ease); }
.block-tile-grid .tile:not([data-shows="only"]):hover { border-color: var(--plait-color-accent); }

/* c) a block of WAYS only (every action opens an area, none hands in): a quiet list of rows, a hairline between them,
   the way pointed at by a chevron at the end (clean-02 "Schnellzugriff"); a block that also hands in keeps its row */
.block-button:not(:has(> [data-acts])):has(> [data-plait-go-area]) { display: grid; gap: 0; justify-content: stretch; }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area] {
  justify-content: flex-start; width: 100%; height: auto; min-height: var(--ergonomics-target-size); padding: var(--plait-space-sm) 0;
  border-radius: 0; font-size: var(--plait-type-body-size); color: var(--plait-color-text);
  transition: color var(--plait-motion-quick) var(--plait-motion-ease);
}
.block-button:not(:has(> [data-acts])) > [data-plait-go-area] + [data-plait-go-area] { border-top: 1px solid var(--plait-color-divider); }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area] .icon { color: var(--plait-color-text-muted); }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area]::after {
  content: ""; margin-inline-start: auto; width: var(--plait-space-sm); height: var(--plait-space-sm); flex: none;
  border-top: 1px solid currentColor; border-right: 1px solid currentColor; transform: rotate(45deg);
}
.block-button:not(:has(> [data-acts])) > [data-plait-go-area]:hover { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
/* Auftrag 09.10. of Planner Device: a way BACK (`kind: back`, the device card's way to the list) points back with its
   own icon before the word; it carries no chevron at its end, which says "onward" */
.block-button:not(:has(> [data-acts])) > [data-plait-go-area].back::after { content: none; }

/* c) the bar at the bottom: each area as wide as its name, so six names stand on one line of a phone */
.variant.bottom_bar .bottom_tab { flex: 1 1 auto; }

/* Owner 2026-10-22 (PLAIT Assistant on the S25: "dann soll der chatinhalt federn"): pulled beyond its end, a scroller's
   content follows the finger (render/spring.ts sets `--spring-offset`) and returns along the suit's spring. */
[data-spring] > * { transform: translateY(var(--spring-offset, 0px)); }
[data-spring="back"] > * { transition: transform var(--plait-motion-spring, 0.36s) var(--plait-motion-spring-ease, cubic-bezier(0.34, 1.56, 0.64, 1)); }

/* 🔴 ONE RULE FOR LESS MOTION (order 32 for the decor, since Auftrag 38a for everything): when the device asks for it,
   NOTHING moves, whatever token an animation or a transition reads; held by 38a-motion (every animation reads a
   motion token, and this rule stands) and by decor-gegen motion. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Auftrag D3: the PAGE of a host drawn inside another page (the Hub draws an application of plait-host into its
   content, in a shadow root of its own). The element stands for <html> and <body> (`HostOptions.page`): it carries
   the suit's tokens as a stage does (`.stage-frame`), the type the body would carry, fills the place it is given,
   and is the box its fixed parts (the bar at the bottom, the foot, an overlay) stand in (`contain`), never the other
   page's window. The two rules of the bar at the bottom read it where `body` cannot be reached. */
.stage-frame[data-plait-page] {
  display: block; height: 100%; margin: 0; border: 0; box-sizing: border-box; contain: layout paint;
  font-family: var(--plait-type-ui-family);
}
/* Auftrag 38d (b): a docked carrier in a page fills the element standing for the document, which then scrolls no more
   itself: the area is the one box that scrolls, and the foot and the bar stay where the place ends. */
.stage-frame[data-plait-page]:has(> [data-docked="yes"]) { overflow: hidden; }
.stage-frame[data-plait-page] > [data-docked="yes"] { height: 100%; }
/* 🔴 Auftrag 09.10. (B, the owner's S25: an empty strip below the bar in the Hub): a docked page REACHES down over the
   room its place's own frame keeps below it (a band kept for a footer that is not shown, the frame's safe area), as far
   as it is painted, measured by ./render/reach.ts (`--plait-page-reach`); the bar's safe area above then takes off what
   is still left below (`--plait-page-below`), so the safe area is kept once in all. Without a measure: as before. */
.stage-frame[data-plait-page]:has(> [data-docked="yes"]) { height: calc(100% + var(--plait-page-reach) + var(--plait-page-above)); margin-top: calc(-1 * var(--plait-page-above)); }
/* owner 2026-10-18 21:45 ("Die 3D anzeige nicht in einem Kasten sondern in ganz main bis an bildschirmrand … soll unter
   diesem gradient sichtbar sein und darunter verschwinden", ./render/entry-menu.ts `bleed`): an area holding an entry
   that bleeds has no margin; a docked page holding one reaches up over the room above its place (`--plait-page-above`,
   measured by ./render/reach.ts only where such an area stands on top, taken in the rule of the reach below), so its
   picture runs under the band's fade; the other
   areas of that page keep their start where it was, and what lies over the picture comes down by the same room */
.area[data-bleed="yes"] { padding: 0; gap: 0; }
.stage-frame[data-plait-page]:has(> [data-docked="yes"] .area[data-bleed="yes"]) .area:not([data-bleed="yes"]) { padding-top: calc(var(--plait-space-md) + var(--plait-page-above)); }
.area[data-bleed="yes"] .cell[data-layer="upper"] { transform: translate(var(--plait-space-sm), calc(var(--plait-page-above) + var(--plait-space-sm))); }
/* 2026-10-22 (PLAIT Camera, CK-plait-camera): what lies over the picture and is moved in by the margin never reaches past
   the area on the other side: a choice whose read failed says so in a line as wide as the cell, which stood a margin out */
.area[data-bleed="yes"] .cell[data-layer="upper"] { max-width: calc(100% - 2 * var(--plait-space-sm)); }
/* owner 2026-11-04 (PLAIT Pixel's session, measured at 411 x 803: the input line under the picture stood a margin below the
   window): what lies over the picture AFTER it in the layout (its lower part) is moved in by the margin UPWARDS, so the
   last line keeps the margin to the bottom edge as the first keeps it to the top */
.area[data-bleed="yes"] .cell[data-layer="lower"] ~ .cell[data-layer="upper"] { transform: translate(var(--plait-space-sm), calc(-1 * var(--plait-space-sm))); }
/* and an entry lying over a picture whose read did not reach its data says nothing over it when the picture below says it
   already (both read one function: two sentences laid over each other, measured at 390 x 844 without a relay) */
.area[data-bleed="yes"] .layout:has(.cell[data-layer="lower"] > .piece[data-state="not-reached"]) .cell[data-layer="upper"] > .piece[data-state="not-reached"] { display: none; }
/* owner 2026-10-19 05:06 ("Ordne die buttons innerhalb des viewers sauber an"): every icon over the picture stands on the
   same edge: the pieces lying over it keep no margin of their own (the floors' piece kept the card's, the figures' none,
   so the two icons stood one margin apart), the top one level with the sources' icon on the right */
.area[data-bleed="yes"] .cell[data-layer="upper"] > .piece { padding: 0; }
/* an entry behind an icon (./render/entry-menu.ts `menu`): the piece is only its icon until it is opened */
.piece[data-menu="yes"] { padding: 0; background: transparent; border: 0; box-shadow: none; }
.piece[data-menu="yes"] > .entry-menu { position: relative; }
/* the piece's title moves into the menu with everything else: an empty one takes no room there either */
.piece[data-menu="yes"] .entry-menu-options > h3:empty { display: none; }
.piece[data-menu="yes"] > .entry-menu > .entry-menu-options { display: grid; gap: var(--plait-space-sm); padding: var(--plait-space-sm); min-width: min(18rem, 80vw); }

/* Auftrag 39b: the floor plan (block floor-plan). The drawing is SVG in the cm of its view; the browser fits it into
   the box (preserveAspectRatio). Every fill is a token per art or mark (tokens.css), never a colour from the data. */
.block-floor-plan { display: flex; flex-direction: column; gap: var(--plait-space-sm); width: 100%; height: 100%; min-height: 0; }
.block-floor-plan .plan-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--plait-space-sm); }
/* owner 2026-10-10: what lies over and under the room shown, each on its own line below the hint */
.block-floor-plan .plan-stack { flex: 1 0 100%; margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
.block-floor-plan .plan-hint { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
.block-floor-plan .plan-back { min-height: var(--plait-control-height); }
/* Owner 2026-10-10 (Stockwerke, Teil W): the drawing is as wide as its cell and as high as its floor's own proportion
   asks (its width and height attributes); where the cell is sized by the rule it shrinks into it, where the cell is
   sized by its content (as a phone) it stands whole and the page rolls, never the box */
.block-floor-plan .plan-drawing { display: block; width: 100%; height: auto; max-height: 70vh; flex: 0 1 auto; min-height: 0; }
.block-floor-plan .plan-drawing:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-floor-plan .plan-kind-wall { fill: var(--plait-color-plan-wall); }
/* Planner Space: a body of the plan (a chimney, owner 2026-10-10 "Kamin.") */
.block-floor-plan .plan-kind-body { fill: var(--plait-color-plan-body); }
.block-floor-plan .plan-kind-floor { fill: var(--plait-color-plan-floor); }
.block-floor-plan .plan-kind-floor-held { fill: var(--plait-color-plan-floor-held); }
.block-floor-plan .plan-kind-outdoor { fill: var(--plait-color-plan-outdoor); }
.block-floor-plan .plan-kind-window { fill: var(--plait-color-plan-window); }
.block-floor-plan .plan-kind-door-inner { fill: var(--plait-color-plan-door-inner); }
.block-floor-plan .plan-kind-door-balcony { fill: var(--plait-color-plan-door-balcony); }
.block-floor-plan .plan-kind-door-entrance { fill: var(--plait-color-plan-door-entrance); }
.block-floor-plan .plan-line { fill: none; stroke-width: 1.5px; }
.block-floor-plan .plan-kind-rail { stroke: var(--plait-color-plan-rail); }
.block-floor-plan .plan-kind-grid { stroke: var(--plait-color-plan-grid); stroke-width: 1px; }
.block-floor-plan .plan-room { fill: transparent; cursor: pointer; }
.block-floor-plan .plan-room:hover { fill: var(--plait-hover-ground); }
/* Owner 2026-10-09: a click or a tap draws NO frame (no rectangle around the room); only the keyboard's focus shows,
   and then as the room's own outline in the focus token */
.block-floor-plan .plan-room:focus { outline: none; }
.block-floor-plan .plan-room:focus-visible { outline: none; stroke: var(--plait-color-focus); stroke-width: 3px; vector-effect: non-scaling-stroke; }
/* Owner 2026-10-09: what is drawn ON a room (its name, a point, the cross) never takes the pointer: hovering a name
   marks the room under it, a tap on a point goes to the room */
.block-floor-plan .plan-label, .block-floor-plan .plan-point, .block-floor-plan .plan-point-name, .block-floor-plan .plan-chosen, .block-floor-plan .plan-cross, .block-floor-plan .plan-kind, .block-floor-plan .plan-line { pointer-events: none; }
.block-floor-plan .plan-label { fill: var(--plait-color-text-muted); }
.block-floor-plan .plan-cross { stroke: var(--plait-color-text); stroke-width: 2px; fill: none; }
.block-floor-plan [data-placing="yes"] { cursor: crosshair; }
.block-floor-plan .plan-point { stroke: var(--plait-color-bg); stroke-width: 2px; vector-effect: non-scaling-stroke; }

/* PLAIT Metric (Planner Metric 2026-10-17, owner: "manuell zeichnen"): the drawing sheet of the function geometry, after the
   pattern of block-floor-plan. Lines and points keep their width at any zoom (non-scaling-stroke); the tip is the sheet's own. */
.block-geometry-sheet { display: flex; flex-direction: column; gap: var(--plait-space-sm); width: 100%; height: 100%; min-height: 0; }
.block-geometry-sheet .sheet-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--plait-space-sm); order: 2; }
/* the feature tree lies over the drawing's top left (overlay, Format 20): the steps and the hint stand at its foot, on the
   right, so the tree's fold switch never lies over Rückgängig or the hint (owner's picture 2026-10-17, measured 2026-10-19) */
.block-geometry-sheet .sheet-drawing { order: 1; }
.block-geometry-sheet .sheet-tools { display: flex; gap: var(--plait-space-xs); }
.block-geometry-sheet .sheet-tool[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-geometry-sheet .sheet-steps { display: flex; gap: var(--plait-space-xs); }
.block-geometry-sheet .sheet-step[aria-disabled="true"] { opacity: var(--plait-opacity-disabled); cursor: default; }
.block-geometry-sheet .sheet-hint { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
/* Owner 17.10. ("es erscheint immer nur dieser weiße rahmen"): the sheet fills its cell and never outgrows it; without this
   the drawing took its height from its width (1551 px in a cell of 509 px on a desktop) and most of it lay out of sight */
.layout .cell > .piece:has(> .block-geometry-sheet) { height: 100%; }
.block-geometry-sheet .sheet-drawing { display: block; flex: 1 1 0; width: 100%; height: 100%; max-height: none; min-height: 0; cursor: crosshair; touch-action: none; }
.block-geometry-sheet .sheet-grid { stroke: var(--plait-color-plan-grid); stroke-width: 1px; vector-effect: non-scaling-stroke; fill: none; pointer-events: none; }
.block-geometry-sheet .sheet-line { stroke: var(--plait-color-text); stroke-width: 2px; vector-effect: non-scaling-stroke; fill: none; pointer-events: none; }
.block-geometry-sheet .sheet-point { fill: var(--plait-color-text); pointer-events: none; }
.block-geometry-sheet .sheet-begun { fill: none; stroke: var(--plait-color-focus); stroke-width: 2px; vector-effect: non-scaling-stroke; pointer-events: none; }
.block-geometry-sheet .sheet-cross { stroke: var(--plait-color-text-muted); stroke-width: 1px; vector-effect: non-scaling-stroke; fill: none; pointer-events: none; }
.block-geometry-sheet .sheet-rubber { stroke: var(--plait-color-focus); stroke-width: 1.5px; stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; fill: none; pointer-events: none; }
.block-geometry-sheet .sheet-aim { fill: none; stroke: var(--plait-color-focus); stroke-width: 1.5px; vector-effect: non-scaling-stroke; pointer-events: none; }
.block-tool-palette { display: flex; flex-direction: column; gap: var(--plait-space-sm); }
.block-tool-palette[aria-orientation="horizontal"] { flex-direction: row; overflow-x: auto; }
.block-tool-palette .tool-palette-group { display: flex; flex-direction: inherit; gap: var(--plait-space-xs); }
.block-tool-palette .tool-palette-tool[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-tool-palette[data-intrinsic="palette-ribbon"] { flex-direction: row; flex-wrap: wrap; align-items: center; padding: var(--plait-space-xs) var(--plait-space-sm); border-bottom: 1px solid var(--plait-color-border); }
/* PLAIT Metric (owner 2026-10-19, a CAD ribbon as the picture: "coole icons für alles"): a tool is its icon, large, with its
   word below it; on a phone the word stays and the icon keeps its size, so a tool is found by its picture first. */
.block-tool-palette .tool-palette-tool[data-icon="yes"] { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--plait-space-xs); min-width: calc(var(--plait-size-icon) * 3); height: auto; min-height: var(--ergonomics-target-size, var(--plait-control-height)); padding-block: var(--plait-space-xs); }
.block-tool-palette .tool-palette-icon { width: calc(var(--plait-size-icon) * 1.6); height: calc(var(--plait-size-icon) * 1.6); }
.block-tool-palette .tool-palette-word { font-size: var(--plait-type-label-size); }
.block-feature-tree { display: flex; flex-direction: column; gap: 2px; padding: var(--plait-space-sm); border-right: 1px solid var(--plait-color-border); overflow: auto; height: 100%; }
.block-feature-tree .feature-tree-label { margin: 0 0 var(--plait-space-xs); font-size: var(--plait-type-label-size); letter-spacing: .15em; color: var(--plait-color-text-muted); text-transform: uppercase; }
.block-feature-tree .feature-tree-step { justify-content: flex-start; text-align: left; background: transparent; border: 0; min-height: var(--plait-control-height); }
.block-feature-tree .feature-tree-step[data-depth="1"] { padding-left: calc(var(--plait-space-lg) + var(--plait-space-sm)); color: var(--plait-color-text-muted); }
.block-feature-tree .feature-tree-step[aria-pressed="true"] { color: var(--plait-color-accent-text, var(--plait-color-accent)); background: var(--plait-hover-ground); }
.block-feature-tree .feature-tree-withdrawn { opacity: var(--plait-opacity-disabled); }
.block-switch-row { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); padding: var(--plait-space-xs) var(--plait-space-sm); border-top: 1px solid var(--plait-color-border); }
.block-switch-row .switch-row-switch { min-height: calc(var(--plait-control-height) * .8); }
.block-switch-row .switch-row-switch[aria-pressed="true"] { outline: 1.5px solid var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-geometry-sheet .sheet-selected { stroke: var(--plait-color-accent); fill: var(--plait-color-accent); }
/* PLAIT Metric, Länge (Planner Metric 2026-10-26): the line picked for a length thick in the focus colour, the field beside its unit */
.block-geometry-sheet .sheet-picked { stroke: var(--plait-color-focus); stroke-width: 4px; }
.block-geometry-sheet .sheet-length { display: flex; align-items: center; gap: var(--plait-space-xs); }
.block-geometry-sheet .sheet-length-field { width: 8em; min-height: var(--ergonomics-target-size, var(--plait-control-height)); text-align: right; }
.block-geometry-sheet .sheet-length-unit { color: var(--plait-color-text-muted); }
.block-geometry-sheet .sheet-length-set[aria-disabled="true"] { opacity: var(--plait-opacity-disabled); cursor: default; }
/* PLAIT Metric, Linien (Planner Metric 2026-10-19, marschplan sketch-to-cad S0): the sketch's clean sheet with every line
   the tool found over it, in the picture's own pixels; a line the owner named in its role's colour, an open one dashed,
   the held one thick and on top. The layer takes the taps (the block's onPoint), the picture none. */
.block-line-roles { display: flex; flex-direction: column; gap: var(--plait-space-sm); }
.block-line-roles .line-roles-state, .block-line-roles .line-roles-said, .block-line-roles .line-roles-empty { margin: 0; }
.block-line-roles .line-roles-said { color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
.block-line-roles .line-roles-picture { position: relative; width: fit-content; max-width: 100%; margin-inline: auto; }
.block-line-roles .line-roles-image { display: block; width: auto; max-width: 100%; max-height: 50dvh; border-radius: var(--plait-radius-md); }
.block-line-roles .line-roles-lines { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; touch-action: manipulation; overflow: visible; }
.block-line-roles .line-roles-picture[data-picture="absent"] .line-roles-lines { position: static; aspect-ratio: 2 / 1; }
.block-line-roles .line-roles-line { fill: none; stroke-width: 3px; stroke: var(--plait-color-text-muted); stroke-dasharray: 8 6; }
.block-line-roles .line-roles-line[data-role="outline"] { stroke: var(--plait-color-text); stroke-dasharray: none; }
.block-line-roles .line-roles-line[data-role="dimension"] { stroke: var(--plait-color-info); stroke-dasharray: none; }
.block-line-roles .line-roles-line[data-role="extension"] { stroke: var(--plait-color-info); stroke-dasharray: 3 4; }
.block-line-roles .line-roles-line[data-role="upstand"] { stroke: var(--plait-color-warn); stroke-dasharray: none; }
.block-line-roles .line-roles-line[data-role="leader"] { stroke: var(--plait-color-accent); stroke-dasharray: none; }
.block-line-roles .line-roles-line[data-role="writing"] { stroke: var(--plait-color-ok); stroke-dasharray: none; }
.block-line-roles .line-roles-line[data-role="none"] { stroke: var(--plait-color-border); stroke-dasharray: 2 6; }
.block-line-roles .line-roles-line[data-held="yes"] { stroke: var(--plait-color-focus); stroke-width: 6px; stroke-dasharray: none; }
.block-line-roles .line-roles-roles, .block-line-roles .line-roles-steps { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-line-roles .line-roles-role[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-line-roles .line-roles-role[aria-disabled="true"] { opacity: var(--plait-opacity-disabled); }
/* picture-tap (Freisteller, owner 2026-10-22 17:33 "1: ja"): the picture with the proposal over it, phone first. The mask is
   white where the proposal keeps and black where it leaves out; multiplied over the picture at half strength, what is
   left out is dimmed and what is kept stays as it is. The layer that takes the tap lies exactly over the picture. The
   two presses share one row, each at least the finger's target size. */
/* Owner 2026-11-01: the stage of the PLAIT Viewer (./render/viewer-frame.ts). The content over the checkerboard of the
   work area (the same tokens), the layers over the content; only the stage itself takes the hands (`touch-action: none`),
   so a swipe beside it still rolls the page and the page never zooms from it. Colours only from the suit's tokens. */
.block-viewer { position: relative; flex: 1 1 auto; align-self: stretch; width: 100%; min-height: 60dvh; margin: 0; }
/* the stage reaches its piece's edges, as the work area does */
.piece:has(> .block-viewer) { border-width: 0; padding: 0; }
/* owner 2026-11-05 (PLAIT Pixel's session, his phone video: „das ist die session in pixelmatrix. muss optimiert werden.“;
   the session's answer stood without a ground straight over the photo): what the surface lays BESIDE the stage in a cell
   of its own (never over it) is a sheet of its own: the stage keeps exactly its cell, so the picture is fitted into what
   stays above and nothing covers it; the sheet stands on the suit's surface, cut off from the picture by the divider, with
   the margin at its sides and below; a long conversation rolls inside its cell */
.layout .cell:has(.block-viewer):has(~ .cell:not([data-layer])) .block-viewer { min-height: 0; }
.layout .cell:has(.block-viewer) ~ .cell:not([data-layer]) { background: var(--plait-color-surface); padding: 0 var(--plait-space-sm); }
.layout .cell:has(.block-viewer) + .cell:not([data-layer]) { border-top: 1px solid var(--plait-color-divider); }
.layout .cell:has(.block-viewer) ~ .cell[data-size="content"]:not([data-layer]):last-child > .piece { transform: translateY(calc(-1 * var(--plait-space-sm))); }
.block-viewer .viewer-picture { position: absolute; inset: 0; overflow: hidden;
  background: repeating-conic-gradient(var(--plait-color-checker-a) 0% 25%, var(--plait-color-checker-b) 0% 50%) 50% / 12px 12px; }
.block-viewer .viewer-picture:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-viewer .viewer-stage { position: absolute; inset: 0; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; cursor: grab; }
.block-viewer .viewer-stage:active { cursor: grabbing; }
/* owner 2026-11-03 20:10 (Service Pixel): while a tap places something (an axis held, Ebene with Mittelpunkt or an axis) the
   placing cursor, never the pan hand (./render/viewer-perspective.ts `PLACING_ATTRIBUTE`) */
.block-viewer[data-viewer-placing="yes"] .viewer-stage, .block-viewer[data-viewer-placing="yes"] .viewer-stage:active { cursor: crosshair; }
.block-viewer .viewer-image { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.block-viewer .viewer-layers { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.block-viewer .viewer-layer { fill: none; stroke-width: 2px; vector-effect: non-scaling-stroke; }
.block-viewer .viewer-dot { stroke: var(--plait-color-bg); }
.block-viewer .viewer-dot.viewer-tone-accent { fill: var(--plait-color-accent); }
.block-viewer .viewer-dot.viewer-tone-ok { fill: var(--plait-color-ok); }
.block-viewer .viewer-dot.viewer-tone-danger { fill: var(--plait-color-danger); }
.block-viewer .viewer-dot.viewer-tone-text { fill: var(--plait-color-text); }
.block-viewer .viewer-dot.viewer-tone-muted { fill: var(--plait-color-text-muted); }
.block-viewer .viewer-tone-accent:not(.viewer-dot) { stroke: var(--plait-color-accent); }
.block-viewer .viewer-tone-ok:not(.viewer-dot) { stroke: var(--plait-color-ok); }
.block-viewer .viewer-tone-danger:not(.viewer-dot) { stroke: var(--plait-color-danger); }
.block-viewer .viewer-tone-text:not(.viewer-dot) { stroke: var(--plait-color-text); }
.block-viewer .viewer-tone-muted:not(.viewer-dot) { stroke: var(--plait-color-text-muted); }
/* owner 2026-10-27 (PLAIT Pixel, the perspective): „vertikal blau, x rot und y grün“; the drawing's axis colours of every suit */
.block-viewer .viewer-dot.viewer-tone-axis-x { fill: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-dot.viewer-tone-axis-y { fill: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-dot.viewer-tone-axis-z { fill: var(--plait-color-draw-axis-z); }
.block-viewer .viewer-tone-axis-x:not(.viewer-dot) { stroke: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-tone-axis-y:not(.viewer-dot) { stroke: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-tone-axis-z:not(.viewer-dot) { stroke: var(--plait-color-draw-axis-z); }
/* owner 2026-11-02 (Linien B1, V1): a layer or a piece of a line drawn thinner and dashed; widths are design-tokens'
   plait.border.draw-* (tokens.css), never a number here. A layer without them keeps the 2px above. */
.block-viewer .viewer-weight-thin { stroke-width: var(--plait-border-draw-line-thin); } /* also the thinner lines of a plane's grid (owner 02.11. evening „3: ja“) */
.block-viewer .viewer-stroke-dashed { stroke-dasharray: var(--plait-border-draw-dash) var(--plait-border-draw-dash-gap); }
/* Values at the root, so every page reads them declared (look 35-A1): PLAIT Pixel's origin plane fill and the breath
   of its open origin, the timeline fold's turn; the rules keep the same values as their fallback (a shadow root has no :root) */
:root { --plait-draw-area-opacity: 0.14; --plait-motion-origin-breathe: 1.8s; --plait-motion-fast: 150ms; }
/* owner 2026-11-03 23:06 (PLAIT Pixel, the origin as in Inventor, ./render/viewer-origin.ts): its planes an outline half
   see-through in the tone of their normal's axis, its point a fine point (never „kindische punkte“) */
.block-viewer .viewer-area { stroke-width: var(--plait-border-draw-line-thin); fill-opacity: var(--plait-draw-area-opacity, 0.14); stroke-opacity: 0.7; }
.block-viewer .viewer-area.viewer-tone-axis-x { fill: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-area.viewer-tone-axis-y { fill: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-area.viewer-tone-axis-z { fill: var(--plait-color-draw-axis-z); }
.block-viewer .viewer-area.viewer-tone-text { fill: var(--plait-color-text); }
.block-viewer .viewer-area.viewer-tone-accent { fill: var(--plait-color-accent); }
.block-viewer .viewer-dot.viewer-weight-thin { stroke-width: var(--plait-border-draw-line-thin); }
/* owner 2026-11-04 („1: ja … wenn er in der mitte erscheint bedeutet das nicht, dass er da gesetzt ist. darum soll der
   pulsieren/atmen und smooth blinken.“): the open origin breathes in its strength, softly; locked it stands still. With
   reduced motion it stands still and pale, so open and locked still differ. */
@keyframes origin-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.block-viewer[data-perspective-origin="open"] .viewer-layers [data-layer^="perspective-origin"] { animation: origin-breathe var(--plait-motion-origin-breathe, 1.8s) ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .block-viewer[data-perspective-origin="open"] .viewer-layers [data-layer^="perspective-origin"] { animation: none; opacity: 0.55; } }
/* what is said and pressed lies over the picture at its foot; only its own elements take the hands. Owner 2026-11-01
   20:53 „1: ja“ (S25, PLAIT App, gesture navigation: the hint lay behind Android's navigation bar): the foot keeps clear
   of the bottom edge by the safe area, and because a WebView often reports it as 0, by what the PLAIT App hands the page
   for it, `--plait-bar-bottom` (KeyboardCover) and `--plait-inset-bottom` (SurfaceInsets); the largest counts, never
   their sum. Without the app all three are 0. 🔴 Owner 2026-11-03 02:59 (the desktop Hub: the foot stood at the TOP, over
   the list of the projects, while the PLAIT App had it at the bottom): in a portal the carrier draws into a shadow root,
   where the `:root` rule that sets the two app variables to 0 never applies; an unset variable made the whole `bottom`
   invalid, so it fell back to `auto`, the top. Each value therefore carries its own 0. */
.block-viewer .viewer-over { position: absolute; left: var(--plait-space-sm); right: var(--plait-space-sm);
  bottom: calc(var(--plait-space-sm) + max(env(safe-area-inset-bottom, 0px), var(--plait-bar-bottom, 0px), var(--plait-inset-bottom, 0px)));
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--plait-space-xs); pointer-events: none; }
.block-viewer .viewer-over > * { pointer-events: auto; }
.block-viewer .viewer-sentence, .block-viewer .viewer-tap-at, .block-viewer .viewer-hint { margin: 0; padding: var(--plait-space-xs) var(--plait-space-sm);
  border-radius: var(--plait-radius-sm); background: var(--plait-color-surface); color: var(--plait-color-text); font-size: var(--plait-type-label-size); }
.block-viewer .viewer-sentence[hidden] { display: none; }
.block-viewer .viewer-presses { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-viewer .viewer-presses > button { min-height: var(--ergonomics-target-size); }
.block-viewer .viewer-hint { color: var(--plait-color-text-muted); }
.block-viewer .viewer-tap[hidden] { display: none; }
/* Owner 2026-11-01 „1: ja“ (Planner Control's points 9, 10, 11): the general presses + − and the whole picture at the
   right edge, the scale at the top right, a thin bar at the top while the content is read; presses and scale only over a
   content (`data-viewer-content`, set by the carrier). Colours only from the suit's tokens. */
.block-viewer .viewer-zoom { position: absolute; right: var(--plait-space-sm); top: 50%; transform: translateY(-50%); z-index: 1;
  display: flex; flex-direction: column; gap: var(--plait-space-xs); }
.block-viewer .viewer-zoom > button { min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); padding: 0;
  display: grid; place-items: center; font-size: var(--plait-type-title-size); line-height: 1; }
.block-viewer .viewer-scale { position: absolute; right: var(--plait-space-sm); top: var(--plait-space-sm); z-index: 1; margin: 0; pointer-events: none;
  padding: var(--plait-space-xs) var(--plait-space-sm); border-radius: var(--plait-radius-sm); background: var(--plait-color-surface);
  color: var(--plait-color-text); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
.block-viewer[data-viewer-content="no"] .viewer-zoom, .block-viewer:not([data-viewer-content]) .viewer-zoom,
.block-viewer[data-viewer-content="no"] .viewer-scale, .block-viewer:not([data-viewer-content]) .viewer-scale,
.block-viewer .viewer-scale:empty { display: none; }
.block-viewer .viewer-progress { position: absolute; left: 0; right: 0; top: 0; z-index: 1; height: 3px; background: var(--plait-color-surface); pointer-events: none; }
.block-viewer .viewer-progress[hidden] { display: none; }
.block-viewer .viewer-progress-done { height: 100%; width: 0; background: var(--plait-color-accent); }
/* Owner 2026-11-04 (PLAIT Pixel): „Die linienpunkte sollen so sein wie der ursprung. Einfacher kleiner punkt, viereckig“: a
   small filled square in its tone, no outline; under a hovering pen or mouse („hoover effekt“) it grows and carries a soft
   halo of its tone, a line under it is drawn heavier. The pointer says what it is over. */
.block-viewer .viewer-square:not(.viewer-weight-strong) { stroke: none; }
.block-viewer .viewer-square.viewer-tone-axis-x { fill: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-square.viewer-tone-axis-y { fill: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-square.viewer-tone-axis-z { fill: var(--plait-color-draw-axis-z); }
.block-viewer .viewer-square.viewer-tone-text { fill: var(--plait-color-text); }
.block-viewer .viewer-square.viewer-tone-accent { fill: var(--plait-color-accent); }
.block-viewer .viewer-square.viewer-weight-strong { stroke-width: 6px; stroke-opacity: 0.35; paint-order: stroke; }
.block-viewer .viewer-square.viewer-weight-strong.viewer-tone-axis-x { stroke: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-square.viewer-weight-strong.viewer-tone-axis-y { stroke: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-square.viewer-weight-strong.viewer-tone-axis-z { stroke: var(--plait-color-draw-axis-z); }
.block-viewer .viewer-square.viewer-weight-strong.viewer-tone-text { stroke: var(--plait-color-text); }
.block-viewer .viewer-segment.viewer-weight-strong { stroke-width: 3.5px; }
/* Owner 2026-11-03, started 2026-11-05 „1: ja“ (PLAIT Viewer V3, ./render/viewer-marks-svg.ts): areas with fill, hatching
   and holes, labels, arrows, lines dotted, thick and with a seam, OVER any drawer. Colours ONLY from the suit's tokens through
   the tone's class (never a colour in code); labels, widths and heads keep their size on the screen whatever the zoom. */
.block-viewer .viewer-tone-info:not(.viewer-dot) { stroke: var(--plait-color-info); }
.block-viewer .viewer-tone-warn:not(.viewer-dot) { stroke: var(--plait-color-warn); }
.block-viewer .viewer-dot.viewer-tone-info { fill: var(--plait-color-info); }
.block-viewer .viewer-dot.viewer-tone-warn { fill: var(--plait-color-warn); }
.block-viewer .viewer-stroke-dotted { stroke-dasharray: 0.1px var(--plait-border-draw-dash-gap); stroke-linecap: round; }
.block-viewer .viewer-weight-thick { stroke-width: 4px; }
.block-viewer .viewer-mark.viewer-tone-accent { --viewer-tone: var(--plait-color-accent); }
.block-viewer .viewer-mark.viewer-tone-ok { --viewer-tone: var(--plait-color-ok); }
.block-viewer .viewer-mark.viewer-tone-danger { --viewer-tone: var(--plait-color-danger); }
.block-viewer .viewer-mark.viewer-tone-text { --viewer-tone: var(--plait-color-text); }
.block-viewer .viewer-mark.viewer-tone-muted { --viewer-tone: var(--plait-color-text-muted); }
.block-viewer .viewer-mark.viewer-tone-info { --viewer-tone: var(--plait-color-info); }
.block-viewer .viewer-mark.viewer-tone-warn { --viewer-tone: var(--plait-color-warn); }
.block-viewer .viewer-mark.viewer-tone-axis-x { --viewer-tone: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-mark.viewer-tone-axis-y { --viewer-tone: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-mark.viewer-tone-axis-z { --viewer-tone: var(--plait-color-draw-axis-z); }
/* the base of a mark under every weight and stroke class (`:where`, so those win) */
.block-viewer :where(.viewer-mark) { stroke: var(--viewer-tone); fill: none; stroke-width: 2px; }
.block-viewer .viewer-region-body.viewer-fill-tint { fill: var(--viewer-tone); fill-opacity: var(--plait-draw-area-opacity, 0.14); }
.block-viewer .viewer-region-body.viewer-fill-strong { fill: var(--viewer-tone); fill-opacity: 0.45; }
.block-viewer .viewer-region-body.viewer-outline-off { stroke: none; }
.block-viewer .viewer-region-hatch { stroke: none; }
.block-viewer .viewer-hatch-line { stroke: var(--viewer-tone); stroke-width: var(--plait-border-draw-line-thin); fill: none; }
.block-viewer .viewer-hatch-dot { fill: var(--viewer-tone); stroke: none; }
.block-viewer .viewer-mark.viewer-halo { stroke: var(--plait-color-bg); stroke-opacity: 0.9; stroke-dasharray: none; stroke-width: 7px; stroke-linecap: round; }
.block-viewer .viewer-mark.viewer-halo.viewer-weight-thin { stroke-width: 4px; }
.block-viewer .viewer-mark.viewer-halo.viewer-weight-thick { stroke-width: 9px; }
.block-viewer .viewer-arrow-shaft { stroke-linecap: round; }
.block-viewer .viewer-arrow-head { stroke-linejoin: round; stroke-dasharray: none; }
.block-viewer .viewer-head-filled .viewer-arrow-head, .block-viewer .viewer-head-double .viewer-arrow-head { fill: var(--viewer-tone); }
.block-viewer .viewer-leader { stroke-width: var(--plait-border-draw-line-thin); stroke-dasharray: none; }
.block-viewer .viewer-label-text { fill: var(--viewer-tone); stroke: var(--plait-color-bg); stroke-width: 3px; stroke-dasharray: none; paint-order: stroke;
  stroke-linejoin: round; font-family: inherit; font-weight: 600; font-size: var(--plait-type-label-size); }
.block-viewer .viewer-label-small .viewer-label-text { font-size: var(--plait-type-caption-size); }
.block-viewer .viewer-label-large .viewer-label-text { font-size: var(--plait-type-title-size); }
.block-viewer[data-viewer-hover="grip"] .viewer-stage, .block-viewer[data-viewer-hover="origin"] .viewer-stage { cursor: move; }
/* a look of the picture (pixel-matrix's, ./render/viewer-look.ts) lies exactly over it; the carrier sets its transform */
.block-viewer .viewer-look { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; }
/* Owner 2026-11-03, started 2026-11-05 „1: ja“ (PLAIT Viewer V4, ./render/plan-drawer.ts): a floor plan with layers. Every
   colour a token of the suit: a kind of the function floor-plan its `plait.color.plan-*`, a category without a kind a tone. */
.block-viewer .viewer-plan { position: absolute; inset: 0; pointer-events: none; }
.block-viewer .viewer-plan-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.block-viewer .viewer-plan .plan-kind-wall { --viewer-plan-tone: var(--plait-color-plan-wall); }
.block-viewer .viewer-plan .plan-kind-floor { --viewer-plan-tone: var(--plait-color-plan-floor); }
.block-viewer .viewer-plan .plan-kind-outdoor { --viewer-plan-tone: var(--plait-color-plan-outdoor); }
.block-viewer .viewer-plan .plan-kind-rail { --viewer-plan-tone: var(--plait-color-plan-rail); }
.block-viewer .viewer-plan .plan-kind-window { --viewer-plan-tone: var(--plait-color-plan-window); }
.block-viewer .viewer-plan .plan-kind-door-inner { --viewer-plan-tone: var(--plait-color-plan-door-inner); }
.block-viewer .viewer-plan .plan-kind-door-balcony { --viewer-plan-tone: var(--plait-color-plan-door-balcony); }
.block-viewer .viewer-plan .plan-kind-door-entrance { --viewer-plan-tone: var(--plait-color-plan-door-entrance); }
.block-viewer .viewer-plan .plan-kind-chimney, .block-viewer .viewer-plan .viewer-plan-structure { --viewer-plan-tone: var(--plait-color-text); }
.block-viewer .viewer-plan .plan-kind-table, .block-viewer .viewer-plan .plan-kind-cabinet, .block-viewer .viewer-plan .viewer-plan-furniture { --viewer-plan-tone: var(--plait-color-plan-body); }
.block-viewer .viewer-plan .viewer-plan-rooms { --viewer-plan-tone: var(--plait-color-plan-floor); }
.block-viewer .viewer-plan .viewer-plan-walls { --viewer-plan-tone: var(--plait-color-plan-wall); }
.block-viewer .viewer-plan .viewer-plan-light-walls { --viewer-plan-tone: var(--plait-color-text-muted); }
.block-viewer .viewer-plan .viewer-plan-pre-walls { --viewer-plan-tone: var(--plait-color-warn); }
.block-viewer .viewer-plan .viewer-plan-plaster { --viewer-plan-tone: var(--plait-color-border); }
.block-viewer .viewer-plan .viewer-plan-tile-layer { --viewer-plan-tone: var(--plait-color-info); }
.block-viewer .viewer-plan .viewer-plan-demolition { --viewer-plan-tone: var(--plait-color-danger); stroke-dasharray: 6 4; }
.block-viewer .viewer-plan .viewer-plan-windows { --viewer-plan-tone: var(--plait-color-plan-window); }
.block-viewer .viewer-plan .viewer-plan-doors { --viewer-plan-tone: var(--plait-color-plan-door-inner); }
.block-viewer .viewer-plan .viewer-plan-rails { --viewer-plan-tone: var(--plait-color-plan-rail); }
.block-viewer .viewer-plan .viewer-plan-sanitary { --viewer-plan-tone: var(--plait-color-info); }
.block-viewer .viewer-plan .viewer-plan-beams-above { --viewer-plan-tone: var(--plait-color-text); stroke-dasharray: 8 5; }
.block-viewer .viewer-plan .viewer-plan-construction-lines { --viewer-plan-tone: var(--plait-color-plan-grid); }
.block-viewer .viewer-plan .viewer-plan-axes { --viewer-plan-tone: var(--plait-color-plan-grid); stroke-dasharray: 12 3 2 3; }
.block-viewer .viewer-plan .viewer-plan-dimensions { --viewer-plan-tone: var(--plait-color-warn); }
.block-viewer .viewer-plan .viewer-plan-area { fill: var(--viewer-plan-tone, var(--plait-color-plan-wall)); stroke: none; }
.block-viewer .viewer-plan .viewer-plan-knock-out { fill: var(--plait-color-bg); }
.block-viewer .viewer-plan :is(.viewer-plan-line, .viewer-plan-swing) { fill: none; stroke: var(--viewer-plan-tone, var(--plait-color-text)); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
.block-viewer .viewer-plan .viewer-plan-swing { stroke-width: 1px; }
.block-viewer .viewer-plan .viewer-plan-body { fill: var(--viewer-plan-tone, var(--plait-color-plan-body)); fill-opacity: 0.35; stroke: var(--viewer-plan-tone, var(--plait-color-plan-body));
  stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
.block-viewer .viewer-plan .viewer-plan-text { fill: var(--plait-color-text); stroke: var(--plait-color-bg); stroke-width: 3px; paint-order: stroke; stroke-linejoin: round;
  font-family: inherit; font-size: var(--plait-type-caption-size); text-anchor: middle; dominant-baseline: central; }
.block-viewer .viewer-plan .viewer-plan-name { font-weight: 650; font-size: var(--plait-type-label-size); }
.block-viewer .viewer-plan .viewer-plan-figure { fill: var(--plait-color-text-muted); }
.block-viewer .viewer-plan .viewer-plan-length { fill: var(--plait-color-warn); font-weight: 600; }
.block-viewer .viewer-plan .viewer-plan-device { stroke: var(--plait-color-bg); stroke-width: 2px; fill: var(--plait-color-accent); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-1 { fill: var(--plait-color-plan-mark-1); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-2 { fill: var(--plait-color-plan-mark-2); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-3 { fill: var(--plait-color-plan-mark-3); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-4 { fill: var(--plait-color-plan-mark-4); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-5 { fill: var(--plait-color-plan-mark-5); }
.block-viewer .viewer-plan .viewer-plan-device.plan-mark-6 { fill: var(--plait-color-plan-mark-6); }
/* Owner 2026-11-04: „zoombuttons in ein seitenmenü einklappen. So wie das bei samsung ist, aber viel dezenter und
   stylischer. Die buttons nur icons.“ (./render/viewer-panel.ts): a slim grip at the right edge, a narrow column of icons
   sliding in over the picture, half see-through with the picture blurred behind it, fine lines between its groups. Only
   over a content; colours only from the suit's tokens. */
/* the panel stands between the scale at the top and the foot, never beyond the stage; a longer column scrolls in itself */
.block-viewer .viewer-edge { position: absolute; right: 0; z-index: 2; display: flex; align-items: center; pointer-events: none; overflow: hidden;
  top: calc(var(--plait-space-sm) + var(--ergonomics-target-size)); bottom: calc(var(--plait-space-sm) + 2 * var(--ergonomics-target-size)); }
.block-viewer .viewer-edge > * { pointer-events: auto; }
.block-viewer[data-viewer-content="no"] .viewer-edge, .block-viewer:not([data-viewer-content]) .viewer-edge { display: none; }
.block-viewer .viewer-edge-grip { order: 2; width: 18px; min-height: calc(var(--ergonomics-target-size) * 1.6); padding: 0; margin: 0; border: 0; background: transparent;
  display: grid; place-items: center; cursor: pointer; touch-action: none; }
.block-viewer .viewer-edge-grip-bar { width: 4px; height: calc(var(--ergonomics-target-size) * 1.1); border-radius: 2px; background: var(--plait-color-text);
  opacity: 0.45; transition: opacity var(--plait-motion-quick) var(--plait-motion-ease), height var(--plait-motion-quick) var(--plait-motion-ease); }
.block-viewer .viewer-edge-grip:hover .viewer-edge-grip-bar, .block-viewer .viewer-edge-grip:focus-visible .viewer-edge-grip-bar { opacity: 0.85; }
.block-viewer .viewer-edge-grip:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.block-viewer .viewer-edge-column { order: 1; display: flex; flex-direction: column; gap: var(--plait-space-xs); max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--plait-space-xs); border-radius: var(--plait-radius-md); border: 1px solid color-mix(in srgb, var(--plait-color-border) 45%, transparent);
  background: color-mix(in srgb, var(--plait-color-surface) 88%, transparent);
  scrollbar-width: none; transform: translateX(calc(100% + var(--plait-space-lg))); opacity: 0; pointer-events: none;
  transition: transform var(--plait-motion-spring) var(--plait-motion-ease), opacity var(--plait-motion-quick) var(--plait-motion-ease); }
.block-viewer .viewer-edge[data-viewer-edge="open"] .viewer-edge-column { transform: none; opacity: 1; pointer-events: auto; }
.block-viewer .viewer-edge[data-viewer-edge="open"] .viewer-edge-grip-bar { height: calc(var(--ergonomics-target-size) * 0.7); opacity: 0.7; }
.block-viewer .viewer-edge-group { display: flex; flex-direction: column; gap: 2px; }
.block-viewer .viewer-edge-group + .viewer-edge-group { padding-top: var(--plait-space-xs); border-top: 1px solid color-mix(in srgb, var(--plait-color-border) 45%, transparent); }
.block-viewer .viewer-edge-press { width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); padding: 0; margin: 0; display: grid; place-items: center;
  border: 0; border-radius: var(--plait-radius-sm); background: transparent; color: var(--plait-color-text); cursor: pointer; }
.block-viewer .viewer-edge-press:hover { background: color-mix(in srgb, var(--plait-color-text) 10%, transparent); }
.block-viewer .viewer-edge-press:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.block-viewer .viewer-edge-press[aria-pressed="false"] { opacity: 0.38; }
.block-viewer .viewer-edge-press[aria-checked="true"] { background: color-mix(in srgb, var(--plait-color-accent) 22%, transparent); color: var(--plait-color-accent); }
.block-viewer .viewer-edge-tone-axis-x { color: var(--plait-color-draw-axis-x); }
.block-viewer .viewer-edge-tone-axis-y { color: var(--plait-color-draw-axis-y); }
.block-viewer .viewer-edge-tone-axis-z { color: var(--plait-color-draw-axis-z); }
@media (prefers-reduced-motion: reduce) { .block-viewer .viewer-edge-column, .block-viewer .viewer-edge-grip-bar { transition: none; } }
/* Owner 2026-11-01 (PLAIT Pixel, ./render/viewer-pipette.ts: „Die Werte will ich ohne Hintergrund über dem Viewer. Eventuell
   das Bild unter den Werten etwas unscharf machen"): the pipette's values over the top of the stage, no background of their
   own, the picture under them blurred; the mark a square around the tapped pixel. */
.block-viewer .viewer-pipette { --viewer-pipette-cell: 20px; position: absolute; left: var(--plait-space-sm); top: var(--plait-space-sm); z-index: 1;
  max-width: calc(100% - 2 * var(--plait-space-sm)); display: grid; gap: var(--plait-space-xs); padding: var(--plait-space-sm);
  border-radius: var(--plait-radius-md); background: transparent; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: var(--plait-color-text); text-shadow: 0 0 3px var(--plait-color-bg), 0 0 1px var(--plait-color-bg);
  font-size: var(--plait-type-label-size); font-variant-numeric: tabular-nums; touch-action: manipulation; }
.block-viewer .viewer-pipette-head { display: flex; align-items: center; gap: var(--plait-space-sm); }
.block-viewer .viewer-pipette-head > div { display: grid; }
.block-viewer .viewer-pipette-swatch { width: 32px; height: 32px; flex: none; border-radius: var(--plait-radius-sm); border: 1px solid var(--plait-color-bg); }
.block-viewer .viewer-pipette-windows { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: flex-start; }
.block-viewer .viewer-pipette-window { display: grid; gap: 1px; }
.block-viewer .viewer-pipette-window small { grid-column: 1 / -1; color: var(--plait-color-text); font-size: var(--plait-type-caption-size); }
.block-viewer .viewer-pipette-cell { width: var(--viewer-pipette-cell); height: var(--viewer-pipette-cell); padding: 0; border-radius: 2px;
  border: 1px solid color-mix(in srgb, var(--plait-color-bg) 55%, transparent); }
.block-viewer .viewer-pipette-middle { outline: 2px solid var(--plait-color-accent); outline-offset: -1px; }
.block-viewer .viewer-pipette-outside { background: repeating-linear-gradient(45deg, var(--plait-color-checker-a) 0 4px, var(--plait-color-checker-b) 4px 8px); }
.block-viewer .viewer-pipette-cell-value { margin: 0; }
/* Owner 2026-11-04 („Die Pipette zeigt den eingestellten Wert und darunter klein den Originalwert.“): the original's value,
   small and quieter under the value as the footer sets it. */
.block-viewer .viewer-pipette-original { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-viewer .viewer-pipette-mark { position: absolute; z-index: 1; pointer-events: none; box-sizing: border-box;
  border: 1px solid var(--plait-color-bg); outline: 2px solid var(--plait-color-accent); }
/* Owner 2026-11-01 („einfach zugriff auf die gallery hinzufügen“, ./render/viewer-gallery.ts): the gallery lies over the
   whole stage, its head fixed, the topic below it, the pictures (the gallery's own grid) taking the rest and scrolling inside. */
.block-viewer .viewer-gallery-panel { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; gap: var(--plait-space-sm);
  padding: var(--plait-space-sm); background: var(--plait-color-bg); color: var(--plait-color-text); overflow: hidden; }
.block-viewer .viewer-gallery-head { display: flex; align-items: center; justify-content: space-between; gap: var(--plait-space-sm); }
.block-viewer .viewer-gallery-title { margin: 0; font-size: var(--plait-type-title-size); }
.block-viewer .viewer-gallery-close { min-height: var(--ergonomics-target-size); }
.block-viewer .viewer-gallery-said { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
.block-viewer .viewer-gallery-said[hidden] { display: none; }
.block-viewer .viewer-gallery-grid { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.block-picture-tap { --picture-tap-dim: 0.5; display: flex; flex-direction: column; gap: var(--plait-space-sm); }
.block-picture-tap .picture-tap-modes { display: flex; gap: var(--plait-space-xs); }
.block-picture-tap .picture-tap-mode { flex: 1 1 0; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
.block-picture-tap .picture-tap-mode[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-picture-tap[data-intrinsic="picture-tap-compact"] .picture-tap-mode { padding-inline: var(--plait-space-xs); }
.block-picture-tap .picture-tap-picture { position: relative; width: fit-content; max-width: 100%; margin-inline: auto; }
.block-picture-tap .picture-tap-image { display: block; width: auto; max-width: 100%; max-height: 60dvh; border-radius: var(--plait-radius-md); }
.block-picture-tap .picture-tap-mask { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: multiply; opacity: var(--picture-tap-dim); pointer-events: none; border-radius: var(--plait-radius-md); }
.block-picture-tap .picture-tap-layer { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; touch-action: manipulation; overflow: visible; }
.block-picture-tap .picture-tap-piece { stroke: var(--plait-color-accent); stroke-width: 2px; }
.block-picture-tap .picture-tap-cross { fill: none; stroke: var(--plait-color-focus); stroke-width: 3px; }
.block-picture-tap .picture-tap-hint, .block-picture-tap .picture-tap-empty { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
/* picture-tap with lines (PLAIT Pixel, tab Linien, owner 2026-10-25 19:18): every line over the picture, an open one in the
   yellow of the warnings, a measured one green, the held one blue and wider; its measure at its middle with a halo of the
   surface so it reads on any photo. The font size comes from the block in the picture's own units (it scales with it).
   Below: the field for the measure, its unit beside it, and the presses, each at least the finger's target size. */
.block-picture-tap .picture-tap-line { fill: none; stroke: var(--plait-color-warning-yellow); stroke-width: 3px; stroke-linecap: round; }
.block-picture-tap .picture-tap-line[data-measured="yes"] { stroke: var(--plait-color-ok); }
.block-picture-tap .picture-tap-line[data-source="hand"] { stroke-dasharray: 6 4; }
.block-picture-tap .picture-tap-line-held { stroke: var(--plait-color-info); stroke-width: 6px; }
.block-picture-tap .picture-tap-measure-label { fill: var(--plait-color-text); stroke: var(--plait-color-surface); stroke-width: 0.15em; paint-order: stroke; font-weight: var(--plait-type-label-weight); pointer-events: none; }
.block-picture-tap .picture-tap-line-said { margin: 0; font-size: var(--plait-type-label-size); }
.block-picture-tap .picture-tap-measure-form { display: flex; flex-wrap: wrap; gap: var(--plait-control-gap); align-items: end; }
.block-picture-tap .picture-tap-measure-form .field { display: flex; flex: 1 1 100%; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.block-picture-tap .picture-tap-measure-form .field_name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-picture-tap .picture-tap-measure-form .field_value { flex: 1 1 auto; min-width: 0; min-height: var(--ergonomics-target-size); }
.block-picture-tap .picture-tap-measure-form .button { flex: 1 1 0; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
/* picture-tap with camera (PLAIT Pixel, tab Linien, Planner Control 2026-10-26: "ich klicke die parallelen in jede achsrichtung,
   3d automatisch"): a line in the colour of its axis (A teal, B orange, senkrecht blue, the plan's marks; never violet), the
   held one stays wider; the anchor and the reference's end as rings, the reference line dashed in the accent, the ground
   taps as dots with a halo of the surface. The tools and the axis presses share a row half and half, each at least the
   finger's target size. */
.block-picture-tap .picture-tap-line[data-axis="a"] { stroke: var(--plait-color-plan-mark-1); }
.block-picture-tap .picture-tap-line[data-axis="b"] { stroke: var(--plait-color-plan-mark-2); }
.block-picture-tap .picture-tap-line[data-axis="vertical"] { stroke: var(--plait-color-plan-mark-3); }
.block-picture-tap .picture-tap-reference { fill: none; stroke: var(--plait-color-accent); stroke-width: 3px; stroke-dasharray: 8 6; pointer-events: none; }
.block-picture-tap .picture-tap-anchor, .block-picture-tap .picture-tap-end { fill: none; stroke: var(--plait-color-focus); stroke-width: 3px; pointer-events: none; }
.block-picture-tap .picture-tap-end-held { stroke-dasharray: 4 3; }
.block-picture-tap .picture-tap-ground { fill: var(--plait-color-text); stroke: var(--plait-color-surface); stroke-width: 2px; pointer-events: none; }
.block-picture-tap .picture-tap-tools, .block-picture-tap .picture-tap-axes { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-picture-tap .picture-tap-tool, .block-picture-tap .picture-tap-axis, .block-picture-tap .picture-tap-ground-clear { flex: 1 1 0; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
.block-picture-tap .picture-tap-tool[aria-pressed="true"], .block-picture-tap .picture-tap-axis[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-picture-tap .picture-tap-reference-form { display: flex; flex-wrap: wrap; gap: var(--plait-control-gap); align-items: end; }
.block-picture-tap .picture-tap-reference-form .picture-tap-axes { flex: 1 1 100%; }
.block-picture-tap .picture-tap-reference-form .field { display: flex; flex: 1 1 100%; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.block-picture-tap .picture-tap-reference-form .field_name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-picture-tap .picture-tap-reference-form .field_value { flex: 1 1 auto; min-width: 0; min-height: var(--ergonomics-target-size); }
.block-picture-tap .picture-tap-reference-form .button.submit { flex: 1 1 0; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
/* picture-tap, Perspektive 3D (PLAIT Pixel v23, owner 2026-10-26 15:03: "Linien NICHT mehr ziehen ... Klick = Linie"): a
   line in no axis is OFFERED, thin in the cyan-near info blue (the bootstrap's turquoise; never violet), and a tap takes
   it; the start of a new line is a ring in the colour of the chosen axis; the axis presses, Letzte weg, Erkannte Kanten
   share rows like the tools, each at least the finger's target size; Mehr folds out anchor, end and ground. No 3D net is drawn. */
.block-picture-tap .picture-tap-line[data-offered="yes"] { stroke: var(--plait-color-info); stroke-width: 2px; }
.block-picture-tap .picture-tap-start { fill: none; stroke: var(--plait-color-focus); stroke-width: 3px; pointer-events: none; }
.block-picture-tap .picture-tap-start[data-axis="a"] { stroke: var(--plait-color-plan-mark-1); }
.block-picture-tap .picture-tap-start[data-axis="b"] { stroke: var(--plait-color-plan-mark-2); }
.block-picture-tap .picture-tap-start[data-axis="vertical"] { stroke: var(--plait-color-plan-mark-3); }
.block-picture-tap .picture-tap-camera { display: flex; flex-direction: column; gap: var(--plait-space-xs); }
.block-picture-tap .picture-tap-picks { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-picture-tap .picture-tap-pick, .block-picture-tap .picture-tap-last, .block-picture-tap .picture-tap-detected { flex: 1 1 0; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
.block-picture-tap .picture-tap-pick[aria-pressed="true"], .block-picture-tap .picture-tap-detected[aria-pressed="true"] { outline: 2px solid var(--plait-color-focus); }
.block-picture-tap .picture-tap-more { flex: 1 1 100%; }
.block-picture-tap .picture-tap-more-word { display: flex; align-items: center; min-height: var(--ergonomics-target-size); cursor: pointer; color: var(--plait-color-text-muted); }
.block-picture-tap .picture-tap-more[open] > .picture-tap-tools { margin-top: var(--plait-space-xs); }
.block-picture-tap .picture-tap-pick[data-axis="a"] { border-bottom: 3px solid var(--plait-color-plan-mark-1); }
.block-picture-tap .picture-tap-pick[data-axis="b"] { border-bottom: 3px solid var(--plait-color-plan-mark-2); }
.block-picture-tap .picture-tap-pick[data-axis="vertical"] { border-bottom: 3px solid var(--plait-color-plan-mark-3); }
.block-floor-plan .plan-chosen { fill: none; stroke-width: 2px; vector-effect: non-scaling-stroke; }
.block-floor-plan .plan-point.plan-mark-1, .plan-point-name.plan-mark-1 { fill: var(--plait-color-plan-mark-1); }
.block-floor-plan .plan-point.plan-mark-2, .plan-point-name.plan-mark-2 { fill: var(--plait-color-plan-mark-2); }
.block-floor-plan .plan-point.plan-mark-3, .plan-point-name.plan-mark-3 { fill: var(--plait-color-plan-mark-3); }
.block-floor-plan .plan-point.plan-mark-4, .plan-point-name.plan-mark-4 { fill: var(--plait-color-plan-mark-4); }
.block-floor-plan .plan-point.plan-mark-5, .plan-point-name.plan-mark-5 { fill: var(--plait-color-plan-mark-5); }
.block-floor-plan .plan-point.plan-mark-6, .plan-point-name.plan-mark-6 { fill: var(--plait-color-plan-mark-6); }
.block-floor-plan .plan-chosen.plan-mark-1 { stroke: var(--plait-color-plan-mark-1); }
.block-floor-plan .plan-chosen.plan-mark-2 { stroke: var(--plait-color-plan-mark-2); }
.block-floor-plan .plan-chosen.plan-mark-3 { stroke: var(--plait-color-plan-mark-3); }
.block-floor-plan .plan-chosen.plan-mark-4 { stroke: var(--plait-color-plan-mark-4); }
.block-floor-plan .plan-chosen.plan-mark-5 { stroke: var(--plait-color-plan-mark-5); }
.block-floor-plan .plan-chosen.plan-mark-6 { stroke: var(--plait-color-plan-mark-6); }
.block-floor-plan .plan-empty { margin: 0; color: var(--plait-color-text-muted); }
/* Auftrag 39b: a switch's choice may carry the mark of a point (segments, `mark` 1 to 6): a ring while open, filled when set */
.segments-mark { display: inline-block; width: var(--plait-space-sm); height: var(--plait-space-sm); margin-inline-end: var(--plait-space-xs); vertical-align: middle; overflow: visible; }
.segments-mark-dot { fill: none; stroke-width: 2px; }
.segments-mark-dot.plan-mark-1 { stroke: var(--plait-color-plan-mark-1); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-1 { fill: var(--plait-color-plan-mark-1); }
.segments-mark-dot.plan-mark-2 { stroke: var(--plait-color-plan-mark-2); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-2 { fill: var(--plait-color-plan-mark-2); }
.segments-mark-dot.plan-mark-3 { stroke: var(--plait-color-plan-mark-3); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-3 { fill: var(--plait-color-plan-mark-3); }
.segments-mark-dot.plan-mark-4 { stroke: var(--plait-color-plan-mark-4); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-4 { fill: var(--plait-color-plan-mark-4); }
.segments-mark-dot.plan-mark-5 { stroke: var(--plait-color-plan-mark-5); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-5 { fill: var(--plait-color-plan-mark-5); }
.segments-mark-dot.plan-mark-6 { stroke: var(--plait-color-plan-mark-6); }
.segments-mark[data-set="yes"] .segments-mark-dot.plan-mark-6 { fill: var(--plait-color-plan-mark-6); }
/* Auftrag 39b: the plan FILLS its cell (a field is otherwise at least as tall as its cell, `min-height`, which leaves
   a percentage of its child unresolved): the field takes the cell's height, the block the field's rest, the drawing
   the block's rest; the browser then fits the plan into that (preserveAspectRatio). */
.layout .cell > .piece[data-block="floor-plan"] { height: 100%; display: flex; flex-direction: column; }
.piece[data-block="floor-plan"] > .block-floor-plan { flex: 1 1 0; min-height: 0; height: auto; }

/* Planner Space: one floor as a tilted 2.5D section (block floor-section). SVG in the cm of the turned plan; every
   fill a token of the suit (tokens.css), every edge drawn at one screen width whatever the zoom. */
/* Owner 2026-10-18 ("viel strukturierter und übersichtlicher und im gold anzug"): the 3D scene is ONE card in the suit, the
   picture filling it, the weather and the way back to the start view lying on it, the ways a tap presses invisible to the eye
   (a keyboard and a reader still reach them), the sentence of loading in its middle. Every colour from the suit's tokens. */
/* isolate: the galaxy under the picture (z-index -1) stays inside the frame, over its background */
.block-floor-scene { position: relative; isolation: isolate; width: 100%; overflow: hidden; border-radius: var(--plait-radius-lg);
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 22%, transparent);
  background: radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--plait-color-accent) 9%, var(--plait-color-surface-elevated)) 0%, var(--plait-color-surface) 75%); }
.block-floor-scene[data-scene-time="evening"] { background: radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--plait-color-accent) 6%, var(--plait-color-bg)) 0%, var(--plait-color-bg) 75%); }
/* width 0 and a least width of 100 %: the canvas fills its frame and never asks the layout for its drawing buffer's width (owner 2026-10-18, the S25: the 3D folded to 68 px) */
.block-floor-scene .scene-canvas { display: block; width: 0; min-width: 100%; touch-action: none; }
.block-floor-scene .scene-ways { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.block-floor-scene .scene-sentence { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-floor-scene .scene-sentence[hidden] { display: none; }
/* owner 2026-10-18 20:40 ("Baue das in einen schönen schlichten footer. Die wetter pille wirkt viel zu klobig."): the
   weather, the way back and the menus' icons lie in ONE plain bar across the picture's edge, a hairline toward the
   picture, no pills: the weather as text on the left, the tools as bare icons and words on the right */
/* owner 2026-10-21 (a picture of the bar: "Würde hier Infozeile von funktionszeile trennen.", then "Ich würde das in den
   viewer direkt reinschreiben, links unten."): the bar is the function row alone, across the whole width; the weather and
   its source stand as text in the picture's corner beside the bar, no ground of their own */
.block-floor-scene .scene-hud { position: absolute; top: 0; left: 0; right: 0; display: flex; flex-direction: column; align-items: stretch; gap: 0;
  min-height: 0; padding: 0; box-sizing: border-box;
  background: color-mix(in srgb, var(--plait-color-surface) 78%, transparent); backdrop-filter: blur(var(--plait-space-sm)); -webkit-backdrop-filter: blur(var(--plait-space-sm));
  border-bottom: 1px solid color-mix(in srgb, var(--plait-color-accent) 18%, transparent); }
.block-floor-scene .scene-weather { position: absolute; top: 100%; left: 0; max-width: calc(100% - 2 * var(--plait-space-md)); margin: 0; padding: var(--plait-space-xs) var(--plait-space-md); text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-sm) var(--plait-color-bg); pointer-events: none; font-size: var(--plait-type-caption-size); line-height: 1.2; color: var(--plait-color-text); }
.block-floor-scene .scene-weather > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.block-floor-scene .scene-weather[hidden] { display: none; }
.block-floor-scene .scene-reset { display: inline-grid; place-items: center; margin: 0; padding: 0; width: var(--plait-control-height); height: calc(var(--plait-control-height) * 0.8);
  border: 0; border-radius: 999px; background: transparent; cursor: pointer; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
/* the weather's source stays whole (Google's policy: always visible beside its data): it may take a second line */
.block-floor-scene .scene-weather > .scene-weather-source { white-space: normal; }
.block-floor-scene .scene-tools .segments-menu > .segments-icon { height: calc(var(--plait-control-height) * 0.8); border-color: transparent; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
.block-floor-scene .scene-tools .segments-menu[open] > .segments-icon { background: var(--plait-color-surface-elevated); }
/* owner 2026-10-19 06:09 ("Ich will im viewer keine buttons haben. Baue auch die in den viewer-footer ein."): the entries
   lying over the scene stand in the bar's place (`data-plait-slot`, ./render/entry-menu.ts `slot`) as bare icons beside
   its own; every menu of the bar opens over the picture's whole width, above the bar, and rolls inside itself */
.block-floor-scene .scene-slot { display: flex; align-items: center; }
.block-floor-scene .scene-slot > .piece { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; container-type: normal; }
.block-floor-scene .scene-slot > .piece > h3 { display: none; }
.block-floor-scene .scene-tools .segments-menu, .block-floor-scene .scene-tools .block-segments[data-form="menu"] { position: static; }
.block-floor-scene .scene-tools .segments-menu > .segments-options { left: 0; right: 0; min-width: 0; max-height: var(--scene-menu-reach, 60vh); overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
.layout .cell:not([data-size="content"]) .block-floor-scene .scene-tools .segments-menu > .segments-options { top: auto; bottom: calc(100% + var(--plait-space-xs)); }
/* owner 2026-10-22 (the buildings' menu: "Die auswahl welches gebäude sieht schrecklich aus."): a switch of the bar
   opens like the detail's menu beside it, its choices as buttons one below the other (owner 2026-10-18 20:21: "die
   buttons immer schön untereinander"), never side by side over the picture's width; the held one has the accent edge */
.block-floor-scene .scene-tools .segments-menu > .segments-options,
.block-floor-scene .scene-tools .segments-menu > .segments-options[data-intrinsic="series"] { grid-auto-flow: row; grid-template-columns: 1fr; gap: var(--plait-space-xs); padding: var(--plait-space-sm);
  background: var(--plait-color-surface-elevated); }
.block-floor-scene .scene-tools .segments-menu > .segments-options .segments-choice { padding: 0 var(--plait-space-md); border: 1px solid var(--plait-color-border); border-radius: var(--plait-control-radius); }
.block-floor-scene .scene-tools .segments-menu > .segments-options .segments-choice:has(.segments-radio:checked),
.block-floor-scene .scene-tools .segments-menu > .segments-options .segments-choice[data-held="yes"] { border-color: var(--plait-color-accent); background: var(--plait-color-surface); }
.block-floor-scene .scene-tools .segments-menu > .segments-options .segments-choice[data-held="yes"] .segments-name { color: var(--plait-color-text); font-weight: var(--plait-type-label-weight); }
.block-floor-scene .scene-reset:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* owner 2026-10-19 (the SpaceNavigator): the 3D mouse's icon only where the browser can read one, glowing while PLAIT reads it */
.block-floor-scene .scene-hand[hidden] { display: none; }
.block-floor-scene .scene-hand[data-held="yes"] { box-shadow: 0 0 var(--plait-point-glow-size) var(--plait-color-accent-glow); }
/* owner 2026-10-19 ("1: ja" to the table of the 3D mouse's settings): its settings beside it, the small display on the
   picture (mode, fine, locks), gone after the setting's seconds of rest */
.block-floor-scene .scene-hand-settings[hidden] { display: none; }
.block-floor-scene .scene-hand-hud { position: absolute; top: var(--plait-space-sm); left: 50%; transform: translateX(-50%); padding: var(--plait-space-xs) var(--plait-space-md);
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 40%, transparent); border-radius: var(--plait-radius-xl);
  background: color-mix(in srgb, var(--plait-color-surface) 82%, transparent); color: var(--plait-color-text); font-size: var(--plait-type-caption-size); pointer-events: none; white-space: nowrap; }
.block-floor-scene .scene-hand-hud[hidden] { display: none; }
/* owner 2026-10-18 ("den detailgrad einstellen"): beside the way back the detail's icon, opened to one row per area;
   the menu lies over the picture's width under the tools (at the foot: above them), whatever side the icon stands on */
.block-floor-scene .scene-tools { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 0; padding: 0 var(--plait-space-xs); }
/* every icon its own place in the row (owner 2026-10-21: "Die Icons in der Menüleiste sehen nicht sauber angeordnet aus"):
   the entries the carrier moves into the slot stand in the row like the bar's own, never as one group */
.block-floor-scene .scene-tools > .scene-slot, .block-floor-scene .scene-tools > .scene-slot > .piece { display: contents; }
.block-floor-scene .scene-detail { position: static; }
/* owner 2026-10-18 20:21 ("Mach das menü strukturierter, d.h. die buttons immer schön untereinander", and a video where a
   finger in the menu rolled the whole page): the panel is never taller than the picture leaves it (`--scene-menu-reach`,
   measured by the carrier), rolls inside itself and never hands a roll on to the page */
.block-floor-scene .scene-detail > .segments-options { left: 0; right: 0; min-width: 0; display: grid; gap: var(--plait-space-md); padding: var(--plait-space-sm);
  max-height: var(--scene-menu-reach, 60vh); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y; }
.layout .cell:not([data-size="content"]) .block-floor-scene .scene-detail > .segments-options { top: auto; bottom: calc(100% + var(--plait-space-xs)); }
/* one group per area: its name, then its steps SIDE BY SIDE in one row of equal parts (owner 2026-10-18 20:42: "Die
   detailstufen sollen jeweils nebeneinander, nicht untereinander stehen. So verbraucht das zu viel Platz."); the menu of
   the time and the weather keeps them */
.block-floor-scene .scene-detail-area { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-floor-scene .scene-detail-name { flex: 1 0 100%; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-floor-scene .scene-detail-step { flex: 1 1 0; min-width: 0; justify-content: center; text-align: center; padding: 0 var(--plait-space-xs); border-radius: var(--plait-control-radius); border: 1px solid var(--plait-color-border); }
.block-floor-scene .scene-detail-step:has(.segments-radio:checked) { border-color: var(--plait-color-accent); background: var(--plait-color-surface); }
/* owner 2026-10-19 ("Baue dieses deteileinstellungsmenü smarter auf, nicht mit den fetten buttons. Mach auch überall ein
   symbo/icon/minizeichnung", then the third draft, "Ja alles, mach das volle programm"): the profiles in one row, what is
   detected now as small chips, the layers as tiles of drawing, name, step bars and WHY in the corner; below them the
   opened layer's steps, the rules and the table, each a section that opens (scene-menu.ts writes what changes) */
.block-floor-scene .scene-auto-panel { gap: var(--plait-space-sm); }
/* every control of the panel sizes to its content (the global button is one control high) and keeps its touch size */
.block-floor-scene .scene-auto-panel button { height: auto; min-height: calc(var(--plait-control-height) * 0.75); }
.block-floor-scene .scene-auto-panel .scene-auto-layer { min-height: calc(var(--plait-control-height) * 1.9); }
.block-floor-scene .scene-auto-panel .icon { width: var(--plait-size-icon); height: var(--plait-size-icon); flex: none; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-auto-label { font-size: var(--plait-type-caption-size); letter-spacing: 0.06em; text-transform: uppercase; color: var(--plait-color-text-muted); }
.block-floor-scene .scene-auto-profiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-profile { display: grid; justify-items: center; gap: 2px; padding: var(--plait-space-xs) 2px; border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md);
  background: none; color: var(--plait-color-text-muted); font: inherit; font-size: var(--plait-type-caption-size); cursor: pointer; min-width: 0; overflow-wrap: anywhere; }
.block-floor-scene .scene-auto-profile[aria-pressed="true"] { border-color: var(--plait-color-accent); color: var(--plait-color-text); background: var(--plait-color-surface); }
.block-floor-scene .scene-auto-now { display: grid; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-chips, .block-floor-scene .scene-auto-conds { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px var(--plait-space-xs); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-lg);
  font-size: var(--plait-type-caption-size); color: var(--plait-color-text); background: none; font-family: inherit; }
.block-floor-scene .scene-auto-chip .icon { width: 1em; height: 1em; }
.block-floor-scene .scene-auto-layers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-layer { position: relative; display: grid; justify-items: center; gap: 3px; padding: var(--plait-space-sm) 2px var(--plait-space-xs); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-md); background: var(--plait-color-surface); color: var(--plait-color-text-muted); font: inherit; font-size: var(--plait-type-caption-size); cursor: pointer; min-width: 0; }
.block-floor-scene .scene-auto-layer .icon { width: calc(var(--plait-size-icon) * 1.4); height: calc(var(--plait-size-icon) * 1.4); }
.block-floor-scene .scene-auto-layer[data-step="off"] .icon { color: var(--plait-color-text-muted); opacity: var(--plait-opacity-disabled); }
.block-floor-scene .scene-auto-layer[data-held="yes"], .block-floor-scene .scene-auto-layer[aria-expanded="true"] { border-color: var(--plait-color-accent); }
.block-floor-scene .scene-auto-name { min-width: 0; overflow-wrap: anywhere; text-align: center; }
.block-floor-scene .scene-auto-why { position: absolute; top: 3px; right: 3px; display: flex; }
.block-floor-scene .scene-auto-why .icon { width: 0.9em; height: 0.9em; }
.block-floor-scene .scene-auto-level { display: inline-flex; gap: 2px; align-items: flex-end; }
.block-floor-scene .scene-auto-level > i { width: 6px; height: 3px; border-radius: 1px; background: var(--plait-color-border); }
.block-floor-scene .scene-auto-level > i.on { background: var(--plait-color-accent); }
.block-floor-scene .scene-auto-steps, .block-floor-scene .scene-auto-editrow { display: flex; align-items: center; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-steps { padding-top: var(--plait-space-xs); border-top: 1px solid var(--plait-color-border); flex-wrap: wrap; }
.block-floor-scene .scene-auto-steps[hidden] { display: none; }
/* the cloud's storey and scaffold rows (owner 2026-10-19 "1: ja"): a whole line each under the cloud's steps */
.block-floor-scene .scene-auto-cut { flex: 1 0 100%; display: flex; align-items: center; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-cut > .scene-auto-name { flex: 0 0 4.5rem; text-align: start; }
.block-floor-scene .scene-auto-seg { display: flex; flex: 1 1 12rem; min-width: 0; border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm); overflow: hidden; }
.block-floor-scene .scene-auto-panel .scene-auto-step { flex: 1 1 0; min-width: 0; padding: 4px 2px; border: 0; border-radius: 0; background: none; color: var(--plait-color-text-muted); font: inherit; font-size: var(--plait-type-caption-size); cursor: pointer; }
.block-floor-scene .scene-auto-step[aria-pressed="true"] { background: var(--plait-color-surface-elevated); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-auto-let-go, .block-floor-scene .scene-auto-done, .block-floor-scene .scene-auto-reset, .block-floor-scene .scene-auto-add, .block-floor-scene .scene-auto-tool {
  display: inline-flex; align-items: center; gap: 4px; padding: 4px var(--plait-space-xs); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-sm);
  background: none; color: var(--plait-color-accent-text, var(--plait-color-accent)); font: inherit; font-size: var(--plait-type-caption-size); cursor: pointer; }
.block-floor-scene .scene-auto-section { border-top: 1px solid var(--plait-color-border); padding-top: var(--plait-space-xs); }
.block-floor-scene .scene-auto-section-head { display: flex; align-items: center; gap: var(--plait-space-xs); cursor: pointer; list-style: none; color: var(--plait-color-text); }
.block-floor-scene .scene-auto-section-head::-webkit-details-marker { display: none; }
.block-floor-scene .scene-auto-rules, .block-floor-scene .scene-auto-table { display: grid; gap: var(--plait-space-xs); padding-top: var(--plait-space-xs); }
.block-floor-scene .scene-auto-rule { border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); padding: var(--plait-space-xs); display: grid; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-rule[data-on="no"] { opacity: var(--plait-opacity-disabled); }
.block-floor-scene .scene-auto-rule[data-deciding="yes"] { border-color: var(--plait-color-accent); }
.block-floor-scene .scene-auto-rule-head { display: flex; align-items: center; gap: var(--plait-space-xs); }
.block-floor-scene .scene-auto-panel .scene-auto-rule-open { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; background: none; border: 0; padding: 0; color: inherit; font: inherit; text-align: start; cursor: pointer; }
.block-floor-scene .scene-auto-when, .block-floor-scene .scene-auto-none { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-floor-scene .scene-auto-arrow { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-auto-panel .scene-auto-switch { flex: none; width: 2.1rem; height: 1.2rem; min-height: 0; border-radius: 0.6rem; border: 1px solid var(--plait-color-border); background: var(--plait-color-bg); padding: 0; position: relative; cursor: pointer; }
.block-floor-scene .scene-auto-switch::after { content: ""; position: absolute; top: 0.1rem; left: 0.1rem; width: 0.9rem; height: 0.9rem; border-radius: 50%; background: var(--plait-color-text-muted); }
.block-floor-scene .scene-auto-switch[aria-pressed="true"] { background: var(--plait-color-surface-elevated); border-color: var(--plait-color-accent); }
.block-floor-scene .scene-auto-switch[aria-pressed="true"]::after { left: 0.95rem; background: var(--plait-color-accent); }
.block-floor-scene .scene-auto-editor { display: grid; gap: var(--plait-space-xs); padding-top: var(--plait-space-xs); border-top: 1px solid var(--plait-color-border); }
.block-floor-scene .scene-auto-cond[aria-pressed="true"] { border-color: var(--plait-color-accent); background: var(--plait-color-surface-elevated); }
.block-floor-scene .scene-auto-editrow .scene-auto-name { flex: 0 0 5.5rem; text-align: start; font-size: var(--plait-type-caption-size); }
.block-floor-scene .scene-auto-tools, .block-floor-scene .scene-auto-rule-foot { display: flex; gap: var(--plait-space-xs); justify-content: flex-end; flex-wrap: wrap; }
.block-floor-scene .scene-auto-rule-foot { justify-content: space-between; }
.block-floor-scene .scene-auto-grid { border-collapse: separate; border-spacing: 2px; width: 100%; table-layout: fixed; }
.block-floor-scene .scene-auto-grid th { font-weight: inherit; padding: 2px 0; }
.block-floor-scene .scene-auto-grid th .icon { width: 1.05em; height: 1.05em; display: block; margin: 0 auto; }
.block-floor-scene .scene-auto-grid th[data-now="true"] { border-bottom: 2px solid var(--plait-color-accent); }
.block-floor-scene .scene-auto-grid td { padding: 0; }
.block-floor-scene .scene-auto-grid td[data-now="true"] .scene-auto-cell { border-color: var(--plait-color-accent); }
.block-floor-scene .scene-auto-panel .scene-auto-cell { width: 100%; min-height: 1.9rem; display: grid; place-items: center; border: 1px solid transparent; border-radius: var(--plait-radius-sm);
  background: var(--plait-color-surface); color: var(--plait-color-text-muted); cursor: pointer; padding: 0; font: inherit; }
.block-floor-scene .scene-auto-cell .scene-auto-level > i { width: 3px; }
/* owner 2026-10-18 18:54: the time and the weather, each live or set by hand. A group shows either that it is live with the
   way to set it, or what is set with the way back to the live data (`data-mode`, marked by the carrier) */
.block-floor-scene .scene-when-group { display: grid; gap: var(--plait-space-xs); padding-bottom: var(--plait-space-sm); border-bottom: 1px solid var(--plait-color-border); }
.block-floor-scene .scene-when-group:last-child { padding-bottom: 0; border-bottom: 0; }
.block-floor-scene .scene-when-name { font-weight: var(--plait-type-label-weight); color: var(--plait-color-text); }
.block-floor-scene .scene-when-is-live { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-ok); }
.block-floor-scene .scene-when-mode { justify-self: stretch; min-height: var(--plait-control-height); padding: 0 var(--plait-space-md); border-radius: var(--plait-control-radius);
  border: 1px solid var(--plait-color-accent); background: transparent; color: var(--plait-color-accent-text, var(--plait-color-accent)); cursor: pointer; }
.block-floor-scene .scene-when-mode:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-floor-scene .scene-when-manual { display: grid; gap: var(--plait-space-sm); }
.block-floor-scene .scene-when-group[data-mode="live"] .scene-when-manual,
.block-floor-scene .scene-when-group[data-mode="live"] [data-scene-mode$=":live"],
.block-floor-scene .scene-when-group[data-mode="manual"] .scene-when-is-live,
.block-floor-scene .scene-when-group[data-mode="manual"] [data-scene-mode$=":manual"] { display: none; }
.block-floor-scene .scene-when-field { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--plait-space-xs); }
.block-floor-scene .scene-when-date { grid-column: 1 / -1; width: 100%; box-sizing: border-box; }
.block-floor-scene .scene-when-date { min-height: var(--plait-control-height); padding: 0 var(--plait-space-sm); border-radius: var(--plait-control-radius);
  border: 1px solid var(--plait-color-border); background: var(--plait-color-surface); color: var(--plait-color-text); color-scheme: inherit; }
.block-floor-scene .scene-when-clock { margin-inline-start: auto; font-variant-numeric: tabular-nums; color: var(--plait-color-text); }
.block-floor-scene .scene-when-minute { grid-column: 1 / -1; width: 100%; min-height: var(--ergonomics-target-size); margin: 0; accent-color: var(--plait-color-accent); }
.block-floor-scene .scene-weather-moment { font-variant-numeric: tabular-nums; color: var(--plait-color-text-muted); }
/* the sources of the picture (Google, OpenStreetMap, EOX, the Province): small, top right, never over the floors' icon;
   a tap on the page does not reach them (they are text), they take no room of the picture */
/* owner 2026-10-18: the sources behind an icon top right, a list one line each */
.block-floor-scene .scene-sources[hidden] { display: none; }
.block-floor-scene .scene-sources > .segments-options { display: grid; gap: var(--plait-space-xs); max-height: var(--scene-menu-reach, 60vh); overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
.block-floor-scene .scene-source { margin: 0; font-size: var(--plait-type-caption-size); line-height: 1.3; color: var(--plait-color-text); }
/* owner 2026-10-19 (MeteoAlarm's official warnings in Control): the warnings' icon in the bar only while one of level 2 or
   more is not yet over (the carrier, render/scene-warnings.ts), in the colour of the highest level; its panel one line per
   warning under each other: the level's colour as a stripe, kind and level, from and until, the area, the issuer linked,
   the description and the advice to open. Every colour a token (tokens.css `--plait-color-warning-…`) */
.block-floor-scene .scene-warnings[hidden] { display: none; }
.block-floor-scene .scene-warnings { --scene-warning-color: var(--plait-color-warning-yellow); }
.block-floor-scene .scene-warnings[data-level="3"], .block-floor-scene .scene-warning[data-level="3"] { --scene-warning-color: var(--plait-color-warning-orange); }
.block-floor-scene .scene-warnings[data-level="4"], .block-floor-scene .scene-warning[data-level="4"] { --scene-warning-color: var(--plait-color-warning-red); }
.block-floor-scene .scene-warning[data-level="2"] { --scene-warning-color: var(--plait-color-warning-yellow); }
/* the icon in the bar's gold like every other (owner 2026-10-21: "Das mit dem warndreieck hat nicht dieselbe farbe"); the level's colour stays on each warning in the panel */
.block-floor-scene .scene-warnings > .segments-icon { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-warnings > .segments-options { display: grid; gap: var(--plait-space-sm); max-height: var(--scene-menu-reach, 60vh); overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
.block-floor-scene .scene-warning { display: grid; grid-template-columns: var(--plait-space-xs) 1fr; gap: var(--plait-space-sm); align-items: stretch; }
.block-floor-scene .scene-warning-stripe { border-radius: var(--plait-control-radius); background: var(--scene-warning-color); }
.block-floor-scene .scene-warning-body { display: grid; gap: var(--plait-space-xs); min-width: 0; }
.block-floor-scene .scene-warning-body > p { margin: 0; font-size: var(--plait-type-caption-size); line-height: 1.3; color: var(--plait-color-text); overflow-wrap: anywhere; }
.block-floor-scene .scene-warning-head { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-floor-scene .scene-warning-level { color: var(--scene-warning-color); font-weight: var(--plait-type-label-weight); }
.block-floor-scene .scene-warning-when { font-variant-numeric: tabular-nums; }
.block-floor-scene .scene-warning-body > .scene-warning-area, .block-floor-scene .scene-warning-body > .scene-warning-source { color: var(--plait-color-text-muted); }
.block-floor-scene .scene-warning-link { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
/* owner 2026-10-26 (idea 6, the sun menu of the 3D, render/scene-sun.ts): the shadow and the light as the function sun
   answers them, a legend of swatches and ramps in the suit's own colours, the numbers of a tapped roof plane */
.block-floor-scene .scene-sun > .segments-options { display: grid; gap: var(--plait-space-sm); max-height: var(--scene-menu-reach, 60vh); overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; }
.block-floor-scene .scene-sun-legend[hidden], .block-floor-scene .scene-sun-wing[hidden] { display: none; }
.block-floor-scene .scene-sun-legend, .block-floor-scene .scene-sun-wing { display: grid; gap: var(--plait-space-xs); }
.block-floor-scene .scene-sun-line { display: flex; align-items: center; gap: var(--plait-space-sm); margin: 0; font-size: var(--plait-type-caption-size); line-height: 1.3; color: var(--plait-color-text); font-variant-numeric: tabular-nums; }
.block-floor-scene .scene-sun-swatch { flex: 0 0 auto; inline-size: calc(var(--plait-space-sm) * 4); block-size: var(--plait-space-sm); border-radius: var(--plait-control-radius); border: 1px solid var(--plait-color-border); }
.block-floor-scene .scene-sun-wing-head { margin: 0; font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-label-weight); color: var(--plait-color-text); }
.block-floor-scene .scene-sun-wing-list { display: grid; grid-template-columns: auto 1fr; gap: var(--plait-space-xs) var(--plait-space-sm); margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text); font-variant-numeric: tabular-nums; }
.block-floor-scene .scene-sun-wing-list > dd { margin: 0; text-align: end; }
.block-floor-scene .scene-sun-wing-list > dt { color: var(--plait-color-text-muted); }
/* owner 2026-10-26 (hail the third kind): a tapped face's damage category, its colour beside its word */
.block-floor-scene .scene-sun-wing-list > dd > .scene-sun-swatch { display: inline-block; vertical-align: middle; margin-inline-end: var(--plait-space-xs); }
.block-floor-scene .scene-warning-link:focus-visible, .block-floor-scene .scene-warning-headline:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-floor-scene .scene-warning-more { font-size: var(--plait-type-caption-size); color: var(--plait-color-text); }
.block-floor-scene .scene-warning-headline { cursor: pointer; min-height: var(--ergonomics-target-size); display: flex; align-items: center; }
.block-floor-scene .scene-warning-text { margin: var(--plait-space-xs) 0 0; line-height: 1.35; white-space: pre-line; overflow-wrap: anywhere; }
.block-floor-scene .scene-warnings-credit { color: var(--plait-color-text-muted); }
/* the weather's own source (Google's policy: on or next to its data, always visible): a small second line in the chip */
.block-floor-scene .scene-weather { display: flex; flex-direction: column; }
.block-floor-scene .scene-weather-source { font-size: calc(var(--plait-type-caption-size) * 0.75); color: var(--plait-color-text-muted); }
.block-floor-scene .scene-credits { position: absolute; top: var(--plait-space-xs); right: var(--plait-space-sm); left: 30%; margin: 0;
  text-align: right; font-size: calc(var(--plait-type-caption-size) * 0.8); line-height: 1.25; color: var(--plait-color-text-muted);
  text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg); pointer-events: none; }
.block-floor-scene .scene-credits[hidden] { display: none; }
.block-floor-scene .scene-note { margin: 0; padding: var(--plait-space-xs) var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* Owner 2026-10-18 ("Es soll nicht in einer card sein sondern am ganzen bildschirm"): in a cell the LAYOUT sizes (a share,
   not its content) the scene is no card: it fills the cell edge to edge, the picture its whole height (scene-3d.ts reads
   it), the weather and the way back lie at the foot, so the top is free for an entry lying over it (the floors). */
.layout .cell:not([data-size="content"]) > .piece[data-block="floor-scene"] { height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; }
.layout .cell:not([data-size="content"]) > .piece[data-block="floor-scene"] > .block-floor-scene { flex: 1 1 0; min-height: 0; height: 100%; border: 0; border-radius: 0; }
.layout .cell:not([data-size="content"]) .block-floor-scene .scene-hud { top: auto; bottom: 0; border-bottom: 0; border-top: 1px solid color-mix(in srgb, var(--plait-color-accent) 18%, transparent); }
/* owner 2026-10-22 (PLAIT Camera "Im Haus", picture im-haus-3d-v5): what the cameras see lies over the 3D. Its words stand
   where the scene places them (./render/scene-coverage.ts); the legend and the key figure at the top, the card of the second
   camera and the line of what the colours mean above the bar. Tones only: info for the view, accent for the proposal,
   danger for what furniture hides, warn for the dead zone; never violet. Nothing here takes a tap: the hands turn the 3D. */
.block-floor-scene .scene-coverage-labels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.block-floor-scene .scene-coverage-labels > * { position: absolute; left: 0; top: 0; white-space: nowrap; pointer-events: none; }
.block-floor-scene .scene-coverage-labels > [hidden] { display: none; }
.block-floor-scene .scene-coverage-room { display: flex; flex-direction: column; align-items: center; text-align: center; font-size: var(--plait-type-caption-size); letter-spacing: 0.12em; text-transform: uppercase; font-weight: 700;
  color: var(--plait-color-text); text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-xs) var(--plait-color-bg); }
.block-floor-scene .scene-coverage-room[data-seen="no"] { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-coverage-room-share { font-size: var(--plait-type-title-size); letter-spacing: 0; line-height: 1.1; }
.block-floor-scene .scene-coverage-room-with { font-style: normal; font-size: var(--plait-type-label-size); color: var(--plait-color-accent-text, var(--plait-color-accent)); margin-left: var(--plait-space-xs); }
.block-floor-scene .scene-coverage-room-private { color: var(--plait-color-text-muted); font-weight: 600; font-size: calc(var(--plait-type-caption-size) * 0.75); opacity: 0.75; }
.block-floor-scene .scene-coverage-room-name { font-size: calc(var(--plait-type-caption-size) * 0.85); }
/* the tags lie on the night of the house: its own ground, the tone in the edge and the glow, never as a ground */
.block-floor-scene .scene-coverage-tag { font-size: var(--plait-type-caption-size); letter-spacing: 0.1em; text-transform: uppercase; font-weight: 800; padding: var(--plait-space-xs) var(--plait-space-sm);
  border-radius: var(--plait-radius-sm); color: var(--plait-color-text); background: color-mix(in srgb, var(--plait-color-bg) 80%, transparent);
  backdrop-filter: blur(var(--plait-space-xs)); -webkit-backdrop-filter: blur(var(--plait-space-xs)); }
.block-floor-scene .scene-coverage-tag-live { border: 1px solid var(--plait-color-info); box-shadow: 0 0 var(--plait-space-md) var(--plait-color-info); }
.block-floor-scene .scene-coverage-tag-proposal { border: 1px dashed var(--plait-color-accent); }
.block-floor-scene .scene-coverage-tag-body { border: 1px solid var(--plait-color-danger); box-shadow: 0 0 var(--plait-space-md) var(--plait-color-danger); }
.block-floor-scene .scene-coverage { position: absolute; inset: 0; pointer-events: none; display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto 1fr auto; padding: var(--plait-space-md);
  padding-bottom: calc(var(--plait-space-xl) + var(--plait-space-lg)); box-sizing: border-box; gap: var(--plait-space-sm); }
.block-floor-scene .scene-coverage-left { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; align-items: flex-start; gap: var(--plait-space-sm); min-width: 0; }
/* the house dark behind the view, as in the picture; the note about north is the sun's and says nothing here */
.block-floor-scene[data-scene-coverage="laid"] { background: radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--plait-color-accent) 6%, var(--plait-color-bg)) 0%, var(--plait-color-bg) 75%); }
.block-floor-scene[data-scene-coverage="laid"] .scene-note { display: none; }
/* the bar and its menus (the camera, its place, its values, the private rooms) lie OVER the words of the view, never under them */
.block-floor-scene .scene-coverage, .block-floor-scene .scene-coverage-labels { z-index: 1; }
.block-floor-scene[data-scene-coverage="laid"] .scene-hud { z-index: 2; }
/* a form in a menu of the bar: one column, as wide as the screen allows, its explanations small */
.block-floor-scene .scene-tools .entry-menu-options { width: min(26rem, calc(100vw - 2 * var(--plait-space-md))); max-width: calc(100vw - 2 * var(--plait-space-md)); box-sizing: border-box; }
.block-floor-scene .scene-tools .entry-menu-options .block-form { grid-template-columns: minmax(0, 1fr); }
.block-floor-scene .scene-tools .entry-menu-options .field_what { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-floor-scene .scene-coverage-kpi { grid-column: 2; grid-row: 1; align-self: start; display: flex; flex-direction: column; align-items: flex-end; text-align: right; padding: var(--plait-space-sm) var(--plait-space-md);
  border-radius: var(--plait-radius-md); border: 1px solid var(--plait-color-accent); background: color-mix(in srgb, var(--plait-color-accent) 14%, color-mix(in srgb, var(--plait-color-bg) 82%, transparent));
  box-shadow: 0 0 var(--plait-space-lg) var(--plait-color-accent-glow); }
.block-floor-scene .scene-coverage-kpi-figure { font-size: calc(var(--plait-type-figure-size) * 1.4); font-weight: 800; line-height: 1; color: var(--plait-color-text); text-shadow: 0 0 var(--plait-space-md) var(--plait-color-accent-glow); }
.block-floor-scene .scene-coverage-kpi-figure small { font-size: var(--plait-type-label-size); color: var(--plait-color-accent-text, var(--plait-color-accent)); margin-left: 2px; }
.block-floor-scene .scene-coverage-kpi-word { font-size: var(--plait-type-caption-size); letter-spacing: 0.16em; text-transform: uppercase; color: var(--plait-color-text-muted); }
.block-floor-scene .scene-coverage-kpi-with { font-size: var(--plait-type-caption-size); letter-spacing: 0.14em; text-transform: uppercase; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-coverage-chips { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-floor-scene .scene-coverage-chip, .block-floor-scene .scene-coverage-level { display: inline-flex; align-items: center; gap: var(--plait-space-xs); font-size: calc(var(--plait-type-caption-size) * 0.8); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--plait-color-text); }
.block-floor-scene .scene-coverage-chip { padding: 2px var(--plait-space-sm); border-radius: var(--plait-radius-sm); border: 1px solid var(--plait-color-border); background: color-mix(in srgb, var(--plait-color-bg) 72%, transparent); }
.block-floor-scene .scene-coverage-legend { display: flex; flex-direction: column; gap: 2px; padding: var(--plait-space-xs) var(--plait-space-sm); border-radius: var(--plait-radius-sm); border: 1px solid var(--plait-color-border); background: color-mix(in srgb, var(--plait-color-bg) 72%, transparent); }
/* a swatch is a thick edge in its tone (the tone is the mark, never a ground) */
.block-floor-scene .scene-coverage-swatch { width: var(--plait-space-md); height: 0; border-radius: 2px; flex: none; border-top: var(--plait-space-sm) solid var(--plait-color-border); }
.block-floor-scene .scene-coverage-chip[data-kind="live"] .scene-coverage-swatch { border-top-color: var(--plait-color-info); }
.block-floor-scene .scene-coverage-chip[data-kind="proposal"] .scene-coverage-swatch { border-top-color: var(--plait-color-accent); }
.block-floor-scene .scene-coverage-chip[data-kind="furniture"] .scene-coverage-swatch { border-top-color: var(--plait-color-danger); }
.block-floor-scene .scene-coverage-chip[data-kind="private"] .scene-coverage-swatch { border-top-color: var(--plait-color-border); }
.block-floor-scene .scene-coverage-level[data-level="4"] .scene-coverage-swatch { border-top-color: color-mix(in srgb, var(--plait-color-info) 35%, var(--plait-color-text)); }
.block-floor-scene .scene-coverage-level[data-level="3"] .scene-coverage-swatch { border-top-color: color-mix(in srgb, var(--plait-color-info) 70%, var(--plait-color-text)); }
.block-floor-scene .scene-coverage-level[data-level="2"] .scene-coverage-swatch { border-top-color: var(--plait-color-info); }
.block-floor-scene .scene-coverage-level[data-level="1"] .scene-coverage-swatch { border-top-color: color-mix(in srgb, var(--plait-color-info) 50%, transparent); }
.block-floor-scene .scene-coverage-foot { grid-column: 1 / -1; grid-row: 3; display: flex; flex-direction: column; align-items: flex-start; gap: var(--plait-space-xs); min-width: 0; }
.block-floor-scene .scene-coverage-card { display: flex; flex-direction: column; gap: 2px; max-width: 100%; padding: var(--plait-space-sm) var(--plait-space-md); border-radius: var(--plait-radius-md);
  border: 1px solid var(--plait-color-accent); background: color-mix(in srgb, var(--plait-color-accent) 14%, color-mix(in srgb, var(--plait-color-bg) 85%, transparent)); }
.block-floor-scene .scene-coverage-card-title { font-size: var(--plait-type-caption-size); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 800; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-floor-scene .scene-coverage-card-where { font-size: var(--plait-type-body-size); color: var(--plait-color-text); }
.block-floor-scene .scene-coverage-card-gain { font-size: var(--plait-type-caption-size); color: var(--plait-color-text); opacity: 0.75; }
.block-floor-scene .scene-coverage-missing { margin: 0; max-width: 100%; padding: var(--plait-space-xs) var(--plait-space-sm); border-radius: var(--plait-radius-sm); font-size: var(--plait-type-caption-size);
  color: var(--plait-color-text); border: 1px solid var(--plait-color-warn); background: color-mix(in srgb, var(--plait-color-bg) 85%, transparent); }
.block-floor-scene .scene-coverage-info { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg); }
.block-floor-scene .scene-coverage-info b { color: var(--plait-color-text); font-weight: 700; }
.layout .cell:not([data-size="content"]) .block-floor-scene .scene-weather { top: auto; bottom: 100%; }
.block-floor-section { display: flex; flex-direction: column; gap: var(--plait-space-sm); width: 100%; min-height: 0; }
/* Auftrag 11.10.: the card takes the place the page leaves it (`render/fit.ts` sets its height); where the place is not measured it keeps the proportion of the start picture (`height: auto` from its width and height) */
.block-floor-section .section-drawing { display: block; width: 100%; height: auto; min-height: 0; }
/* Auftrag 11.10. (G1 to G9): the drawing is a VIEW with hands (a finger, two fingers, a mouse, a wheel). On this node and nowhere else a touch
   does not scroll or turn the page; outside it a swipe stays a swipe. */
[data-plait-gesture="view"] { touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; cursor: grab; }
[data-plait-gesture="view"]:active { cursor: grabbing; }
.block-floor-section .section-drawing:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-floor-section .section-floor { fill: var(--plait-color-section-floor); }
.block-floor-section .section-floor-held { fill: var(--plait-color-section-floor-held); }
.block-floor-section .section-outdoor { fill: var(--plait-color-section-outdoor); stroke: var(--plait-color-section-rail); stroke-width: 1px; vector-effect: non-scaling-stroke; }
.block-floor-section .section-face { stroke: var(--plait-color-section-crown); stroke-width: 0.5px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.block-floor-section .section-face-in-1 { fill: var(--plait-color-section-face-in-1); }
.block-floor-section .section-face-in-2 { fill: var(--plait-color-section-face-in-2); }
.block-floor-section .section-face-out-1 { fill: var(--plait-color-section-face-out-1); }
.block-floor-section .section-face-out-2 { fill: var(--plait-color-section-face-out-2); }
.block-floor-section .section-glass { fill: color-mix(in srgb, var(--plait-color-section-glass) var(--plait-opacity-section-glass), transparent); stroke: var(--plait-color-section-glass); stroke-width: 0.75px; vector-effect: non-scaling-stroke; }
.block-floor-section .section-rail { fill: color-mix(in srgb, var(--plait-color-section-rail) var(--plait-opacity-section-glass), transparent); stroke: var(--plait-color-section-rail); stroke-width: 1px; vector-effect: non-scaling-stroke; }
/* Planner Device F3 (owner 2026-10-17: "auf fenster tippen können und dann rollo steuern"): a window's pane that is a
   way (`window_opens`) shows it can be tapped, in the suit's accent (gold in the gold suit); the rim above it is a target only. */
.block-floor-section .section-glass-go { cursor: pointer; stroke: var(--plait-color-accent); stroke-width: 1.5px; }
.block-floor-section .section-glass-go:hover, .block-floor-section .section-glass-go:focus-visible { fill: color-mix(in srgb, var(--plait-color-accent) 45%, transparent); stroke-width: 2.5px; outline: none; }
.block-floor-section .section-glass-hit { cursor: pointer; }
.block-floor-section .section-crown { fill: var(--plait-color-section-crown); stroke: var(--plait-color-section-crown); stroke-width: 0.5px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
/* Planner Space: a body of the plan (a chimney, owner 2026-10-10 "Kamin.") in its own colours, never the wall's */
.block-floor-section .section-body.section-face-out-1 { fill: var(--plait-color-section-body-1); }
.block-floor-section .section-body.section-face-out-2 { fill: var(--plait-color-section-body-2); }
.block-floor-section .section-body.section-crown { fill: var(--plait-color-section-body-crown); }
.block-floor-section .section-edge { fill: none; stroke: var(--plait-color-section-edge); stroke-width: 1px; vector-effect: non-scaling-stroke; stroke-linejoin: round; pointer-events: none; }
.block-floor-section .section-room { fill: transparent; cursor: pointer; }
.block-floor-section .section-room:hover { fill: var(--plait-hover-ground); }
.block-floor-section .section-room:focus { outline: none; }
.block-floor-section .section-room:focus-visible { stroke: var(--plait-color-focus); stroke-width: 3px; vector-effect: non-scaling-stroke; }
.block-floor-section .section-label { fill: var(--plait-color-text-muted); pointer-events: none; }
/* the walls catch a tap and do nothing with it: a tap on a wall never opens the room behind it */
.block-floor-section .section-floor, .block-floor-section .section-outdoor, .block-floor-section .section-stem, .block-floor-section .section-glow,
.block-floor-section .section-mark, .block-floor-section .section-pill, .block-floor-section .section-pill-name { pointer-events: none; }
.block-floor-section .section-stem { fill: none; stroke-width: 1px; stroke-dasharray: 2 3; vector-effect: non-scaling-stroke; opacity: var(--plait-opacity-section-glass); }
.block-floor-section .section-glow { opacity: var(--plait-opacity-section-glass); }
.block-floor-section .section-mark { stroke: var(--plait-color-text); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
.block-floor-section .section-chosen { stroke-width: 3px; }
.block-floor-section .section-pill { fill: var(--plait-color-section-pill); stroke: var(--plait-color-section-pill-edge); stroke-width: 1px; vector-effect: non-scaling-stroke; }
.block-floor-section .section-pill-name { fill: var(--plait-color-text); }
.block-floor-section .section-glow.plan-mark-1, .block-floor-section .section-mark.plan-mark-1 { fill: var(--plait-color-plan-mark-1); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-1)); }
.block-floor-section .section-glow.plan-mark-2, .block-floor-section .section-mark.plan-mark-2 { fill: var(--plait-color-plan-mark-2); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-2)); }
.block-floor-section .section-glow.plan-mark-3, .block-floor-section .section-mark.plan-mark-3 { fill: var(--plait-color-plan-mark-3); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-3)); }
.block-floor-section .section-glow.plan-mark-4, .block-floor-section .section-mark.plan-mark-4 { fill: var(--plait-color-plan-mark-4); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-4)); }
.block-floor-section .section-glow.plan-mark-5, .block-floor-section .section-mark.plan-mark-5 { fill: var(--plait-color-plan-mark-5); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-5)); }
.block-floor-section .section-glow.plan-mark-6, .block-floor-section .section-mark.plan-mark-6 { fill: var(--plait-color-plan-mark-6); filter: drop-shadow(0 0 var(--plait-section-glow) var(--plait-color-plan-mark-6)); }
.block-floor-section .section-stem.plan-mark-1 { stroke: var(--plait-color-plan-mark-1); }
.block-floor-section .section-stem.plan-mark-2 { stroke: var(--plait-color-plan-mark-2); }
.block-floor-section .section-stem.plan-mark-3 { stroke: var(--plait-color-plan-mark-3); }
.block-floor-section .section-stem.plan-mark-4 { stroke: var(--plait-color-plan-mark-4); }
.block-floor-section .section-stem.plan-mark-5 { stroke: var(--plait-color-plan-mark-5); }
.block-floor-section .section-stem.plan-mark-6 { stroke: var(--plait-color-plan-mark-6); }
.block-floor-section .section-tools { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-floor-section .section-press { min-height: var(--plait-control-height); }
.block-floor-section .section-assumed, .block-floor-section .section-open, .block-floor-section .section-empty { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-label-size); }
/* owner 2026-10-09: what is assumed never looks measured. A mark whose height is assumed is hollow and dashed; the
   crown edge of a room whose height is assumed is dashed */
.block-floor-section .section-mark.section-mark-assumed { fill-opacity: 0; stroke-dasharray: 3 2; }
.block-floor-section .section-glow.section-glow-assumed { opacity: calc(var(--plait-opacity-section-dim) / 2); }
.block-floor-section .section-edge.section-edge-assumed { stroke-dasharray: 5 4; }
/* last, so it outweighs the opacity of a glow or a stem: what lies outside the room shown steps back */
.block-floor-section .section-dim { opacity: var(--plait-opacity-section-dim); }
.block-floor-section .section-glow.section-dim, .block-floor-section .section-stem.section-dim { opacity: calc(var(--plait-opacity-section-dim) / 2); }

/* Auftrag 40e (PLAIT Camera): the live picture fills its frame, never wider; its height follows the picture */
.block-live-video .live-stage { width: 100%; aspect-ratio: 16 / 9; position: relative; }
.block-live-video .live-media { display: block; width: 100%; height: 100%; object-fit: contain; position: relative; }
/* 2026-10-22: the camera's last still stands in the place at once; the video lies over it and is shown only once it
   plays, so the change from still to video is seamless (no black frame between) */
.block-live-video .live-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.block-live-video .live-poster:not([data-image-state="shown"]) { visibility: hidden; }
.block-live-video[data-live-state="playing"] .live-poster { visibility: hidden; }
.block-live-video:not([data-live-state="playing"]) .live-media[data-live-media="main"] { opacity: 0; }
/* while a picture is on its way or plays, the press to start stands back; close stays */
.block-live-video[data-live-state="connecting"] .live-start, .block-live-video[data-live-state="playing"] .live-start, .block-live-video[data-live-state="still"] .live-start { display: none; }
.block-live-video .live-actions { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); }

/* 2026-10-22 (owner over Planner Device: PLAIT Camera anew, the full picture "im exakten Control-Rahmen", the tab
   Vollbild): THE VIEWER (`frame: viewer`). In a cell the layout sizes it is no card, exactly as Control's 3D: edge to
   edge, the picture taking every height the line and the bar leave; the mark LIVE on the picture in the signal colour,
   the dots of the cameras at its foot; under it the line of the camera and the bar of its functions, gold icons with
   their word (Control's viewer-footer), the choice of the camera the bar's first place. Every value a token. */
.layout .cell:not([data-size="content"]) > .piece[data-block="live-video"] { height: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.layout .cell:not([data-size="content"]) > .piece[data-block="live-video"] > .block-live-video[data-live-frame="viewer"] { flex: 1 1 0; min-height: 0; height: 100%; }
.block-live-video[data-live-frame="viewer"] { position: relative; display: flex; flex-direction: column; width: 100%; min-height: 0; background: var(--plait-color-bg); }
.block-live-video[data-live-frame="viewer"] > .live-stage { flex: 1 1 0; min-height: calc(var(--plait-control-height) * 4); aspect-ratio: auto; overflow: hidden; touch-action: pan-y; background: var(--plait-color-bg); }
.block-live-video[data-live-frame="viewer"] > .live-stage:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
.block-live-video[data-live-frame="viewer"] .live-media, .block-live-video[data-live-frame="viewer"] .live-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.block-live-video[data-live-frame="viewer"] > .live-sentence { position: absolute; top: 0; left: 0; right: 0; margin: 0; padding: var(--plait-space-md); text-align: center; pointer-events: none;
  color: var(--plait-color-text); font-size: var(--plait-type-caption-size); text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-sm) var(--plait-color-bg); }
.block-live-video[data-live-frame="viewer"][data-live-state="playing"] > .live-sentence { display: none; }
.block-live-video[data-live-frame="viewer"].live-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--plait-space-md); min-height: calc(var(--plait-control-height) * 4); }
.block-live-video[data-live-frame="viewer"].live-empty > .live-sentence { position: static; }
.block-live-video[data-live-frame="viewer"] > .live-actions { position: absolute; left: 0; right: 0; top: 40%; justify-content: center; pointer-events: none; }
.block-live-video[data-live-frame="viewer"] > .live-actions > * { pointer-events: auto; }
.block-live-video[data-live-frame="viewer"] .live-stop { display: none; }
/* the mark LIVE: the signal colour (the suit's own blue), only while a picture plays or its stills come */
.block-live-video .live-badge { display: none; align-items: center; gap: var(--plait-space-xs); padding: var(--plait-space-xs) var(--plait-space-sm); border: 1px solid var(--plait-color-info);
  border-radius: var(--plait-radius-md); background: color-mix(in srgb, var(--plait-color-bg) 55%, transparent); color: var(--plait-color-text);
  font-size: var(--plait-type-caption-size); font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; line-height: 1; }
.block-live-video .live-badge::before { content: ""; width: 0.55em; height: 0.55em; border-radius: 50%; color: var(--plait-color-info); background: currentColor; box-shadow: 0 0 var(--plait-space-xs) currentColor; }
.block-live-video[data-live-state="playing"] .live-badge, .block-live-video[data-live-state="still"] .live-badge { display: inline-flex; }
.block-live-video[data-live-frame="viewer"] .live-badge { position: absolute; z-index: 1; top: var(--plait-space-md); right: var(--plait-space-md); }
.block-live-video .live-dots { position: absolute; z-index: 1; left: 0; right: 0; bottom: var(--plait-space-md); display: flex; justify-content: center; gap: var(--plait-space-sm); pointer-events: none; }
.block-live-video .live-dot { width: calc(var(--plait-space-lg) + var(--plait-space-sm)); height: calc(var(--plait-space-xs) * 1.5); border-radius: var(--plait-radius-sm); background: var(--plait-color-border); }
.block-live-video .live-dot[data-held="yes"] { background: var(--plait-color-accent); }
.block-live-video .live-info { flex: none; padding: var(--plait-space-sm) var(--plait-space-md); border-top: 1px solid var(--plait-color-border); border-bottom: 1px solid var(--plait-color-border); background: var(--plait-color-surface); min-width: 0; }
.block-live-video .live-info > p { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.block-live-video .live-info-name { color: var(--plait-color-text); font-size: var(--plait-type-body-size); }
.block-live-video .live-info-state { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-live-video .live-tool-said { color: var(--plait-color-text); font-size: var(--plait-type-caption-size); }
.block-live-video .live-tool-said:empty { display: none; }
/* the bar: every function its place across the width, a gold icon over its word */
.block-live-video .live-tools { position: relative; flex: none; display: flex; align-items: stretch; justify-content: space-around; gap: 0; padding: var(--plait-space-xs) var(--plait-space-xs);
  background: var(--plait-color-surface-elevated); min-width: 0; }
.block-live-video .live-tool { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; margin: 0;
  height: auto; padding: var(--plait-space-xs) 0; min-height: var(--plait-control-height); border: 0; border-radius: var(--plait-radius-md); background: transparent; cursor: pointer; color: var(--plait-color-accent-text, var(--plait-color-accent)); font-size: inherit; line-height: 1.25; }
.block-live-video .live-tool > .icon { width: var(--plait-size-icon); height: var(--plait-size-icon); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-live-video .live-tool-word { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: calc(var(--plait-type-caption-size) * 0.8);
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-live-video .live-tool[data-live-tool-state="not-yet"] { opacity: var(--plait-opacity-disabled); cursor: help; }
.block-live-video .live-tool[data-live-photo-state="getting"] { opacity: var(--plait-opacity-disabled); }
.block-live-video .live-tool:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: -2px; }
/* the choice of the camera in the bar's first place: the segments' icon stands as the bar's own (Control's slot) */
.block-live-video .live-slot { display: flex; align-items: center; justify-content: center; }
.block-live-video .live-slot > .piece { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; container-type: normal; }
.block-live-video .live-slot > .piece > h3 { display: none; }
.block-live-video .live-tool-camera:not(:has(.piece)) { display: none; }
.block-live-video .live-tool-camera > .live-slot { height: var(--plait-size-icon); }
.block-live-video .live-tool-camera > .live-slot .block-segments { padding: 0; min-height: 0; }
.block-live-video .live-slot .segments-menu, .block-live-video .live-slot .block-segments[data-form="menu"] { position: static; }
.block-live-video .live-slot .segments-menu > .segments-icon { height: var(--plait-size-icon); min-height: 0; padding: 0; border-color: transparent; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-live-video .live-slot .segments-menu > .segments-options { left: 0; right: 0; top: auto; bottom: calc(100% + var(--plait-space-xs)); min-width: 0; max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; }
/* the card of the tab Leitstand: the name, the mark and the choice in its head, the picture under it, never taller than most of the window */
.block-live-video[data-live-frame="card"] { position: relative; display: flex; flex-direction: column; gap: var(--plait-space-sm); }
/* the sentence and the ways out lie ON the picture, so the card is as high as its head and its picture in every state */
.block-live-video[data-live-frame="card"] > .live-sentence { position: absolute; left: 0; right: 0; top: 50%; margin: 0; padding: 0 var(--plait-space-md); text-align: center; pointer-events: none;
  color: var(--plait-color-text); font-size: var(--plait-type-caption-size); text-shadow: 0 0 var(--plait-space-xs) var(--plait-color-bg), 0 0 var(--plait-space-sm) var(--plait-color-bg); }
.block-live-video[data-live-frame="card"] > .live-actions { position: absolute; left: 0; right: 0; bottom: var(--plait-space-md); justify-content: center; pointer-events: none; }
.block-live-video[data-live-frame="card"] > .live-actions > * { pointer-events: auto; }
.block-live-video[data-live-frame="card"] > .live-head { position: relative; display: flex; align-items: center; gap: var(--plait-space-sm); min-width: 0; }
.block-live-video[data-live-frame="card"] > .live-head > .live-name { flex: 1 1 auto; min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--plait-type-caption-size); letter-spacing: 0.14em; text-transform: uppercase; color: var(--plait-color-text-muted); }
.block-live-video[data-live-frame="card"] > .live-head .segments-options { left: auto; right: 0; }
.block-live-video[data-live-frame="card"] > .live-stage { max-height: 62vh; overflow: hidden; border-radius: var(--plait-radius-md); background: var(--plait-color-bg); }
.block-live-video[data-live-frame="card"] .live-media, .block-live-video[data-live-frame="card"] .live-poster { object-fit: cover; }
.block-live-video[data-live-frame="card"][data-live-state="playing"] > .live-sentence { display: none; }
.block-live-video[data-live-frame="card"] .live-stop { display: none; }

/* ══ Auftrag 41b (PLAIT Control neu, owner 2026-10-09 "Alles freigegeben"): the look of the target pictures, ONLY from
   the tokens of 41a. An entry declares its ground (`settings.ground`, ./render/content.ts GROUNDS): `raised` stands out
   of the page as a panel lit from `--plait-relief-angle`, `inset` is a track let into it. Every shadow, light and glow
   is a token (`--plait-elevation-*`, `--plait-page-glow`, `--plait-color-*-glow`); no number of its own stands here
   (41b-numbers). Every colour read as text, ground or edge is a declared pair (suit-pairs.ts). */
.piece[data-ground="raised"] {
  background-color: var(--plait-color-relief-face-to); background-image: var(--plait-relief-face);
  border-color: transparent; border-radius: var(--plait-radius-lg); box-shadow: var(--plait-elevation-raised);
}
.piece[data-ground="inset"] {
  background: var(--plait-color-relief-ground); border-color: transparent; border-radius: var(--plait-radius-xl);
  box-shadow: var(--plait-elevation-inset); padding: var(--plait-space-xs);
}
/* the light at the top of a page that holds a raised panel: it rolls with the page, it never stands over a cell */
.area:has(.piece[data-ground="raised"]) { background-image: var(--plait-page-glow); background-repeat: no-repeat; background-attachment: local; }

/* a switch in an inset track: its choices side by side, each as wide as the others; the held one a raised face. The
   radio stays in the tree (focus, keyboard, the reading voice) and is only not drawn; its focus shows on the choice. */
.piece[data-ground="inset"] .block-segments:not([data-form="list"]) { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--plait-space-xs); }
.piece[data-ground="inset"] .block-segments:not([data-form="list"]) .segments-choice {
  position: relative; justify-content: center; min-height: var(--ergonomics-target-size); border-radius: var(--plait-radius-lg);
  transition: box-shadow var(--plait-motion-quick) var(--plait-motion-ease);
}
.piece[data-ground="inset"] .block-segments:not([data-form="list"]) .segments-radio { position: absolute; inset: 0; margin: 0; opacity: 0; }
.piece[data-ground="inset"] .block-segments:not([data-form="list"]) .segments-choice:has(.segments-radio:checked) {
  background-color: var(--plait-color-relief-face-to); background-image: var(--plait-relief-face); box-shadow: var(--plait-elevation-raised-small);
}
.piece[data-ground="inset"] .block-segments:not([data-form="list"]) .segments-choice:has(.segments-radio:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }

/* the large figure: a key figure on a raised entry is a row of raised panels, one per figure, its number in the figure
   size (the title times the factor, lighter than the body), the whole it belongs to small beside it, its sound a mark */
.piece[data-ground="raised"][data-block="key-figure"] { background: transparent; box-shadow: none; padding: 0; }
.piece[data-ground="raised"] .block-key-figure {
  display: grid; gap: var(--plait-space-md);
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--plait-device-phone-short) / 4), 1fr));
}
.piece[data-ground="raised"] .block-key-figure .key_figure {
  display: grid; align-content: start; gap: var(--plait-space-xs); padding: var(--plait-space-md);
  background-color: var(--plait-color-relief-face-to); background-image: var(--plait-relief-face);
  border-radius: var(--plait-radius-lg); box-shadow: var(--plait-elevation-raised);
}
.piece[data-ground="raised"] .block-key-figure .number {
  min-width: 0; text-align: start; line-height: 1; color: var(--plait-color-text);
  font-size: var(--plait-type-figure-size); font-weight: var(--plait-type-figure-weight); font-variant-numeric: tabular-nums;
}
.block-key-figure .of { margin-inline-start: var(--plait-space-xs); color: var(--plait-color-text-muted); font-size: var(--plait-type-body-size); }
.block-key-figure .what_for:has(> .figure-mark) { display: inline-flex; align-items: center; gap: var(--plait-space-sm); }
.piece[data-ground="raised"] .block-key-figure .what_for { color: var(--plait-color-text-muted); }
.block-key-figure .figure-mark { order: -1; flex: none; width: var(--plait-space-sm); height: var(--plait-space-sm); border-radius: 50%; background: currentColor; }
.block-key-figure .figure-mark[data-sound="good"] { color: var(--plait-color-ok); }
.block-key-figure .figure-mark[data-sound="warning"] { color: var(--plait-color-warn); }
.block-key-figure .figure-mark[data-sound="alarm"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); box-shadow: 0 0 var(--plait-point-glow-size) var(--plait-color-alarm-glow); }

/* Planner Device 2026-10-10: the reading of a scale (block scale-reading), the large thin figure of the key figures; a
   state that is no reading says its sentence in the warning tone; offline stands grey with its last report */
.block-scale-reading { display: grid; gap: var(--plait-space-xs); }
.block-scale-reading[data-intrinsic="side_by_side"] { grid-template-columns: auto 1fr; align-items: baseline; column-gap: var(--plait-space-md); }
.block-scale-reading .scale-what { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-scale-reading .scale-figure, .block-scale-reading .scale-note, .block-scale-reading .scale-state, .block-scale-reading .scale-seen { margin: 0; }
.block-scale-reading .scale-figure { font-variant-numeric: tabular-nums; line-height: 1; }
.block-scale-reading .scale-figure .number { font-size: var(--plait-type-figure-size); font-weight: var(--plait-type-figure-weight); color: var(--plait-color-text); }
.block-scale-reading .scale-figure.raw .number { color: var(--plait-color-text-muted); }
.block-scale-reading .scale-unit { color: var(--plait-color-text-muted); }
.block-scale-reading .scale-note { color: var(--plait-color-warn); font-size: var(--plait-type-caption-size); }
.block-scale-reading .scale-state { color: var(--plait-color-warn); }
.block-scale-reading .scale-seen { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-scale-reading[data-state="offline"] .scale-state { color: var(--plait-color-text-muted); }

/* a regulator on a raised panel: the track let in, the knob standing out of it (the browser's range, drawn) */
.piece[data-ground="raised"] .block-slider .slider-input {
  -webkit-appearance: none; appearance: none; height: var(--plait-space-sm); border-radius: var(--plait-radius-xl);
  background: var(--plait-color-control-track); box-shadow: var(--plait-elevation-inset-small);
}
.piece[data-ground="raised"] .block-slider .slider-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: var(--plait-space-lg); height: var(--plait-space-lg); border-radius: 50%;
  background: var(--plait-color-control-knob); box-shadow: var(--plait-elevation-raised-small);
}
.piece[data-ground="raised"] .block-slider .slider-input::-moz-range-thumb {
  width: var(--plait-space-lg); height: var(--plait-space-lg); border: 0; border-radius: 50%;
  background: var(--plait-color-control-knob); box-shadow: var(--plait-elevation-raised-small);
}

/* ══ Auftrag 41e (PLAIT Control, s-03 "Licht im Raum", ONLY READING). A level is a row of dots, a DISPLAY (role meter),
   never a handle: the lit dots in the text colour, or in the colour the device reports (set by the carrier through the
   CSSOM, `data-plait-swatch`), the others quiet. A group heading names the room (or "no room") above its rows. A tile
   that only shows is no button: no pointer, no hover that promises a press. */
.block-media-list .media-level { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--plait-space-xs); min-width: 0; overflow: hidden; color: var(--plait-color-text-muted); }
.block-media-list .media-level .dot { flex: 0 0 auto; width: var(--plait-space-xs); height: var(--plait-space-xs); border-radius: 50%; background-color: currentColor; opacity: var(--plait-opacity-disabled); }
.block-media-list .media-level .dot.lit { color: var(--plait-color-text); opacity: 1; }
.block-media-list .media-group { padding-block-start: var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-tile-grid .tile_shown { display: grid; align-content: center; justify-items: center; gap: var(--plait-space-xs); text-align: center; cursor: default; }

/* ══ Owner 2026-10-10 (D8, "in den Einstellungen"): THE CARRIER'S SETTINGS, drawn as the Ship look's dialog (D9) in
   the middle of the screen over the veil; render/settings.ts. Every colour, size and distance is a token: the dialog
   on the raised surface, the choices as tiles on the ground of a field, the chosen one framed in the green of `ok`
   with its glow, the foot's button on the accent. While a brightness is drawn these tokens ARE the mixed ones. */
.carrier-settings-veil {
  position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; padding: var(--plait-space-md);
  background: var(--plait-decor-veil);
}
.carrier-settings {
  display: grid; gap: var(--plait-space-md); width: min(100%, var(--plait-device-phone-short)); max-height: 100%; overflow-y: auto;
  padding: var(--plait-space-lg); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-xl);
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised);
  font-family: var(--plait-type-ui-family); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
.carrier-settings-head { display: flex; align-items: center; justify-content: space-between; gap: var(--plait-space-sm); }
.carrier-settings-title { margin: 0; font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); }
.carrier-settings-close {
  min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); border-radius: 50%;
  border: 1px solid var(--plait-color-border); background: var(--plait-color-surface-elevated); color: var(--plait-color-text); cursor: pointer;
}
.carrier-settings-section { display: grid; gap: var(--plait-space-sm); }
.carrier-settings-name { margin: 0; font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight); }
.carrier-settings-what, .brightness-absent, .brightness-gap, .brightness-note, .brightness-suit-other { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.brightness-kinds { display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(var(--plait-device-small-short) / 3), 1fr)); gap: var(--plait-space-sm); }
.brightness-kind {
  position: relative; display: grid; align-content: start; gap: var(--plait-space-xs); min-height: var(--ergonomics-target-size);
  padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-lg);
  background: var(--plait-color-piece); color: var(--plait-color-text); cursor: pointer;
}
.brightness-kind[data-held="yes"] { border-color: var(--plait-color-accent); box-shadow: 0 0 var(--plait-point-glow-size) var(--plait-color-accent-glow); }
.brightness-kind:has(> .brightness-radio:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.brightness-radio { position: absolute; opacity: 0; pointer-events: none; }
.brightness-kind-name { font-weight: var(--plait-type-label-weight); }
.brightness-kind-what { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.brightness-detail { display: grid; gap: var(--plait-space-sm); }
.brightness-scale { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size); }
.brightness-end { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.brightness-range { width: 100%; min-height: var(--ergonomics-target-size); accent-color: var(--plait-color-ok); }
.brightness-value { margin: 0; font-variant-numeric: tabular-nums; }
.brightness-sub { margin: 0; font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-label-weight); }
.brightness-rows { display: grid; gap: var(--plait-space-sm); }
.brightness-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--plait-space-sm); }
.brightness-row > .brightness-scale { grid-template-columns: 1fr; }
.brightness-row > .brightness-scale > .brightness-end { display: none; }
.brightness-lux { display: inline-flex; align-items: center; gap: var(--plait-space-xs); }
.brightness-time, .brightness-number {
  min-height: var(--ergonomics-target-size); padding-inline: var(--plait-space-sm); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-md); background: var(--plait-color-piece); color: var(--plait-color-text); font: inherit;
}
.brightness-number { width: calc(var(--plait-space-xl) * 3); }
.brightness-unit { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.brightness-remove, .brightness-add {
  min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); padding-inline: var(--plait-space-sm);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-piece); color: var(--plait-color-text); cursor: pointer; font: inherit;
}
.brightness-add { justify-self: start; }
.brightness-remove:disabled, .brightness-add:disabled { opacity: var(--plait-opacity-disabled); cursor: default; }
.brightness-invalid { margin: 0; color: var(--plait-color-danger-text, var(--plait-color-danger)); font-size: var(--plait-type-caption-size); }
.carrier-settings-foot { display: flex; justify-content: flex-end; }
.carrier-settings-apply {
  min-height: var(--ergonomics-target-size); padding-inline: var(--plait-space-lg); border: 1px solid var(--plait-color-accent);
  border-radius: var(--plait-radius-xl); background: var(--plait-color-accent); color: var(--plait-color-on-accent);
  font: inherit; font-weight: var(--plait-type-label-weight); cursor: pointer;
}

/* owner 2026-10-19 ("1: ja" to the table of the 3D mouse's settings, render/six-axis-panel.ts): the dialog of the
   carrier's settings, wider for its sections; the choices as small chips, the chosen one framed in the accent; a value
   set in the chosen layer carries the accent's dot; the live bars grow from their middle. Only tokens. */
.hand-settings { width: min(100%, var(--plait-device-tablet-short)); }
.hand-device, .hand-dots, .hand-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-sm); }
.hand-foot { justify-content: flex-end; }
.hand-chips { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.hand-chip {
  min-height: var(--ergonomics-target-size); padding-inline: var(--plait-space-sm); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-md); background: var(--plait-color-piece); color: var(--plait-color-text); font: inherit; cursor: pointer;
}
.hand-chip[data-held="yes"] { border-color: var(--plait-color-accent); box-shadow: 0 0 var(--plait-point-glow-size) var(--plait-color-accent-glow); }
.hand-chip:disabled { opacity: var(--plait-opacity-disabled); cursor: default; }
.hand-chip[hidden], .hand-file { display: none; }
.hand-chip:focus-visible, .hand-switch:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.hand-wide { justify-self: start; }
.hand-small { min-height: 0; padding-block: var(--plait-space-xs); font-size: var(--plait-type-caption-size); }
.hand-section { border-top: 1px solid var(--plait-color-border); padding-top: var(--plait-space-sm); }
.hand-summary { cursor: pointer; min-height: var(--ergonomics-target-size); display: flex; align-items: center; gap: var(--plait-space-xs); list-style: none; }
.hand-summary::-webkit-details-marker { display: none; }
.hand-summary::before { content: "\25B8"; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.hand-section[open] > .hand-summary::before { transform: rotate(90deg); }
.hand-section-body { display: grid; gap: var(--plait-space-sm); padding-top: var(--plait-space-sm); }
.hand-axis { display: grid; gap: var(--plait-space-xs); padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-lg); background: var(--plait-color-piece); }
.hand-axis-name { margin: 0; font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight); }
.hand-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size); }
.hand-slider { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto; }
.hand-slider:has(> .hand-small) { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto auto; }
.hand-choice { grid-template-columns: 1fr; }
.hand-label { position: relative; }
.hand-row[data-own="yes"] > .hand-label::after { content: ""; display: inline-block; width: var(--plait-space-xs); height: var(--plait-space-xs); margin-inline-start: var(--plait-space-xs);
  border-radius: 50%; background: var(--plait-color-accent); vertical-align: middle; }
.hand-value { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hand-switch { width: var(--plait-space-lg); height: var(--plait-space-lg); accent-color: var(--plait-color-ok); }
.hand-bars { display: grid; gap: var(--plait-space-xs); }
.hand-bar-row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) calc(var(--plait-space-xl) * 1.5); align-items: center; gap: var(--plait-space-sm); font-size: var(--plait-type-caption-size); }
.hand-bar { position: relative; height: var(--plait-space-sm); border-radius: var(--plait-radius-md); background: var(--plait-color-piece); overflow: hidden; }
.hand-bar-fill { position: absolute; top: 0; bottom: 0; left: 50%; width: 50%; transform-origin: left center; transform: scaleX(var(--hand-share, 0)); background: var(--plait-color-accent); }
.hand-bar-value { text-align: end; font-variant-numeric: tabular-nums; color: var(--plait-color-text-muted); }
.hand-dot { padding: var(--plait-space-xs) var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); font-size: var(--plait-type-caption-size); }
.hand-dot[data-held="yes"] { border-color: var(--plait-color-accent); background: var(--plait-color-accent); color: var(--plait-color-on-accent); }
.hand-preview { width: 100%; height: calc(var(--plait-space-xl) * 6); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-lg); background: var(--plait-color-piece); }
.hand-wizard-say { margin: 0; min-height: var(--ergonomics-target-size); font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.hand-wizard-say:empty { min-height: 0; }

/* Planner Device 2026-10-11 (PLAIT Control, the floor plan): the upload of the house's 3D file (block model-upload) and
   its reading (block model-read). Only tokens: the accent for the bar, a border line between the endings (no text in
   the style), the muted tone for what is said beside the action. */
.block-model-upload, .block-model-read { display: flex; flex-direction: column; align-items: flex-start; gap: var(--plait-space-sm); min-width: 0; }
.block-model-upload p, .block-model-read p { margin: 0; overflow-wrap: anywhere; }
.model-upload-accepts { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--plait-space-xs); font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-upload-ending { text-transform: uppercase; }
.model-upload-ending + .model-upload-ending { border-left: 1px solid var(--plait-color-border); padding-left: var(--plait-space-xs); }
.model-upload-note, .model-upload-preparing, .model-read-none, .model-read-reading, .model-read-in-plan { color: var(--plait-color-text-muted); }
.model-upload-progress { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-sm); width: 100%; }
.model-upload-bar { flex: 1 1 100%; width: 100%; accent-color: var(--plait-color-accent); }
.model-upload-part, .model-upload-percent { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-upload-failed, .model-read-failed, .model-read-refused { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.model-read-question { display: flex; flex-direction: column; gap: var(--plait-space-xs); width: 100%; padding-top: var(--plait-space-sm); border-top: 1px solid var(--plait-color-border); }
.model-read-answers { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.model-read-answer[data-proposed="yes"] { border-color: var(--plait-color-accent); }
.model-read-file-unit { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-read-missing { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); color: var(--plait-color-warn); }
.model-read-layers { margin: 0; padding-left: var(--plait-space-lg); font-size: var(--plait-type-caption-size); }
/* Planner Device 2026-10-11 (owner: an upload is not the whole house): the uploaded models and their parts (block
   model-parts), each assigned only expressly. "Zuordnen" and "Zuordnung entfernen" are the carrier's own disclosures. */
.block-model-parts { display: flex; flex-direction: column; gap: var(--plait-space-sm); min-width: 0; }
.block-model-parts p { margin: 0; overflow-wrap: anywhere; }
.model-parts-title { margin: 0; font-size: var(--plait-type-label-size); }
.model-parts-model { display: flex; flex-direction: column; gap: var(--plait-space-xs); padding-top: var(--plait-space-sm); border-top: 1px solid var(--plait-color-border); }
.model-parts-head, .model-part { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--plait-space-sm); }
.model-parts-format { text-transform: uppercase; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-parts-state, .model-parts-count, .model-part-elevation, .model-part-floor, .model-parts-none, .model-parts-no-parts { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-parts-state[data-state="assigned"] { color: var(--plait-color-ok); }
.model-parts-state[data-state="refused"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.model-part[data-proposed="yes"] .model-part-name { border-bottom: 1px solid var(--plait-color-accent); }
.model-parts-assign, .model-parts-remove { width: 100%; }
.model-parts-assign > summary, .model-parts-remove > summary { cursor: pointer; width: fit-content; }
.model-parts-form { display: flex; flex-direction: column; gap: var(--plait-space-sm); padding: var(--plait-space-sm) 0; }
.model-parts-floors, .model-parts-rooms, .model-parts-layers { display: flex; flex-direction: column; gap: var(--plait-space-xs); margin: 0; padding: 0; border: 0; }
.model-parts-choice, .model-parts-layer, .model-parts-field { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); }
.model-parts-conflicts { color: var(--plait-color-warn); display: flex; flex-direction: column; gap: var(--plait-space-xs); }
.model-parts-incomplete { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.model-parts-actions { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }

/* 2026-10-11 · the calm device list (PLAIT Control, owner on the S25: "Die Geraeteauflistung ist schrecklich"), every
   rule scoped to a list that asks for it (`data-lines="two"`, `data-picture="icon"`), so every other list stays as it was.
   One row: an icon on a quiet square in the accent, the name over the kind (one line each, cut with an ellipsis), the
   state alone at the right, a chevron; a hairline between rows; the room as a quiet heading above its rows. */
/* the step a line box is rounded up to: one whole CSS pixel, named (see the line-height rule below) */
.block-media-list[data-lines="two"] { gap: 0; --media-line-step: 1px; }
/* a hairline only between the rooms, never between two rows: the same everywhere (Planner Application 2026-10-11) */
.block-media-list[data-lines="two"] .media-group:not(:first-child) { border-top: 1px solid var(--plait-color-border); margin-top: var(--plait-space-sm); }
.block-media-list[data-lines="two"] .media-handle { gap: var(--plait-space-sm); padding: var(--plait-space-sm) 0; min-width: 0; }
.block-media-list[data-lines="two"] .media-text { flex: 1 1 0; gap: 0; }
.block-media-list[data-lines="two"] .media-title { font-weight: var(--plait-type-label-weight); }
.block-media-list[data-lines="two"] .media-subline { flex-wrap: nowrap; align-items: center; gap: var(--plait-space-xs); white-space: nowrap; overflow: hidden; }
.block-media-list[data-lines="two"] .media-subline-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* owner 2026-10-31 (the list of PLAIT Bootstrap: "Design muss dem Suite folgen. Und es muss plaitiger aussehen."): the
   square under a row's icon is the suit's CONTROL, the same face a control wears (Gold: black glass inside the brushed
   gold rim, its light around it; another suit its own control), the icon in the control's ink. Every value a token, so a
   change of suit changes the list; a suit without a control material falls back to the accent veil it wore before. */
.block-media-list[data-picture="icon"] .media-icon {
  display: inline-flex; flex: none; align-items: center; justify-content: center;
  width: calc(var(--plait-size-icon) * 1.75); aspect-ratio: 1; border-radius: var(--plait-radius-md);
  border: var(--plait-material-rim-width) solid var(--plait-material-control-rim, transparent);
  background: var(--plait-material-control, color-mix(in srgb, var(--plait-color-accent) var(--plait-opacity-veil-from), transparent));
  box-shadow: var(--plait-elevation-control, none);
  color: var(--plait-material-control-mark, var(--plait-color-accent));
}
/* the row a press leads from: its icon lights up with the hover ground, the chevron takes the control's ink */
.block-media-list[data-picture="icon"] button.media-handle:is(:hover, :focus-visible) .media-icon { box-shadow: var(--plait-elevation-control, none), 0 0 var(--plait-space-sm) var(--plait-decor-glow); }
.block-media-list[data-picture="icon"] .media-chevron { color: var(--plait-material-control-mark, var(--plait-color-text-muted)); }
.block-media-list .media-via { width: var(--plait-type-caption-size); height: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* the state keeps its place but never the name's: at most a little under half the row, a long state ("über Node, nicht
   erreichbar") breaks into a second line of its own at the right, its dot never apart from its word (a no-break space) */
.block-media-list .media-end { flex: 0 1 auto; max-width: 35%; overflow-wrap: anywhere; white-space: normal; text-align: end; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-media-list .media-chevron { color: var(--plait-color-text-muted); }
/* the chevron sits close to the state (half the row's gap), so a state with its moment breaks into two lines at most
   ("nicht erreichbar" / "seit 10:15") and the name keeps its room */
.block-media-list[data-lines="two"] .media-chevron { margin-inline-start: calc(var(--plait-space-xs) * -1); }
.block-media-list[data-lines="two"] .media-group {
  display: grid; gap: 0; padding: var(--plait-space-md) 0 var(--plait-space-xs);
  font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight); color: var(--plait-color-text-muted);
}
.block-media-list[data-lines="two"] .media-group:first-child { padding-top: 0; }
/* whole pixels per line: a row of fractional lines summed over many rows outgrew the cell measured for it (W-carriers,
   1920: by 1/32 px); a line box rounded up to the pixel keeps every row and heading a whole number tall */
.block-media-list[data-lines="two"] :is(.media-title, .media-subline, .media-group, .media-group-name, .media-group-note, .media-end) { line-height: round(up, calc(1em * var(--plait-type-body-line-height)), var(--media-line-step)); }
.block-media-list[data-lines="two"] .media-group-note { font-size: var(--plait-type-caption-size); font-weight: var(--plait-type-body-weight); }

/* ══ Planner Application 2026-10-14 (owner-approved order, PLAIT Music on the S25): the search field, the keyboard, the
   pages under a hand and the menu of a row. Every size, colour and movement a token. */

/* the one-line search field (`input type=search`, the composer) has the text area's look; its own clear button stays */
input.block-composer { box-sizing: border-box; }
/* plait-app-0161 (owner 2026-10-24, "4: ja"): the field as PLAIT asks on today's start page: round, smoked glass the dust
   shines through, a rim of the suit's gold that fades along its run, a quiet halo, the words in the middle and thin */
input.block-composer[data-look="ask"] { height: auto; min-height: var(--ergonomics-target-size); border-radius: 999px; text-align: center;
  padding: var(--plait-space-sm) var(--plait-space-lg); font-weight: 200; letter-spacing: 0.04em; font-size: var(--plait-type-body-size);
  border: 1px solid transparent; color: var(--plait-color-text);
  background: linear-gradient(180deg, color-mix(in srgb, var(--plait-color-surface) 55%, var(--plait-color-bg)), var(--plait-color-bg)) padding-box,
    linear-gradient(135deg, var(--plait-wordmark-brush-1, var(--plait-color-accent)), var(--plait-wordmark-gleam, var(--plait-color-accent)) 30%, var(--plait-color-accent) 60%, var(--plait-wordmark-brush-1, var(--plait-color-accent))) border-box;
  box-shadow: 0 0 var(--plait-space-xl) var(--plait-decor-glow); }
input.block-composer[data-look="ask"]::placeholder { color: var(--plait-color-text); opacity: 0.42; font-weight: 200; }
input.block-composer[data-look="ask"]:focus-visible { outline: none; box-shadow: 0 0 var(--plait-space-xl) var(--plait-decor-glow), 0 0 var(--plait-space-md) var(--plait-decor-glow); }
/* a search due or on its way: a quiet line moving along the field's lower edge, in the accent (active = blue) */
.piece[data-searching="yes"] .block-composer {
  background-image: linear-gradient(90deg, transparent, var(--plait-color-accent), transparent);
  background-size: 40% 2px; background-repeat: no-repeat; background-position: -40% 100%;
  animation: searching var(--plait-motion-equalizer) linear infinite;
}
@keyframes searching { to { background-position: 140% 100%; } }
/* a read asked and empty says what it was asked for, in the language's own quotation marks (`q`) */
.state.empty[data-asked="yes"] q { color: var(--plait-color-text); overflow-wrap: anywhere; }

/* 🔴 the keyboard is open (./render/keyboard.ts): the foot and the bar at the bottom fold, the hits stand right under the field */
[data-docked="yes"][data-keyboard="open"] > .foot,
[data-docked="yes"][data-keyboard="open"] > .level:has(> .variant.bottom_bar) { display: none; }

/* the pages: panned by the browser sideways and up and down, pinch zoom stays (a reading aid), no double-tap zoom
   (it delayed every tap); chosen, never left to the default */
[data-docked="yes"] > .pages { touch-action: manipulation; }

/* the menu of a row (`media-list` `actions`): three dots at the row's right end, a target as large as a finger */
.block-media-list .media-row[data-menu="yes"] { display: flex; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.block-media-list .media-row[data-menu="yes"] > .media-handle { flex: 1 1 0; min-width: 0; }
.block-media-list .media-more.icon, .block-media-list .media-act.icon {
  box-sizing: border-box; flex: none; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size);
  padding: calc((var(--ergonomics-target-size) - var(--plait-size-icon)) / 2); margin: 0;
  background: transparent; border: 0; border-radius: var(--plait-radius-sm); color: var(--plait-color-text-muted);
}
.block-media-list .media-more.icon:hover, .block-media-list .media-more[aria-expanded="true"], .block-media-list .media-act.icon:hover { color: var(--plait-color-accent-text, var(--plait-color-accent)); background: var(--plait-hover-ground); }
/* its panel: a glass dialog over the page (a popover, the top layer), in the middle of the screen over a veil */
.block-media-list .media-menu {
  box-sizing: border-box; width: min(calc(100% - 2 * var(--plait-space-md)), var(--plait-device-phone-short)); max-height: calc(100% - 2 * var(--plait-space-md));
  margin: auto; padding: var(--plait-space-md); display: grid; gap: var(--plait-space-xs); overflow-y: auto;
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-xl);
  background: var(--plait-foot-ground); backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass);
  color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised);
  font-family: var(--plait-type-ui-family); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
.block-media-list .media-menu:not([popover]) { margin: var(--plait-space-xs) 0 0; }
.block-media-list .media-menu:not([popover])[hidden] { display: none; }
.block-media-list .media-menu[popover]:not(:popover-open) { display: none; }
.block-media-list .media-menu::backdrop { background: var(--plait-decor-veil); }
.block-media-list .media-menu-title { margin: 0 0 var(--plait-space-xs); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); overflow-wrap: anywhere; }
.block-media-list .media-menu-item {
  display: flex; align-items: center; width: 100%; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-md);
  background: transparent; border: 0; border-radius: var(--plait-radius-sm); color: var(--plait-color-text); font: inherit; text-align: start;
}
.block-media-list .media-menu-item:hover, .block-media-list .media-menu-item:focus-visible { background: var(--plait-hover-ground); color: var(--plait-color-accent-text, var(--plait-color-accent)); }

/* ── words (F4, owner 2026-10-24, ./render/words.ts): the words of PLAIT's dictionary drawn in a field. The mirror lies
   exactly over the field (its place and the field's measures are set by the carrier through the CSSOM), takes no pointer
   and no focus, and draws the same text; while it stands beside the field, the field's own glyphs are not painted (its
   caret, its choosing and its value stay the field's). Every look comes from the suit: per display key the variables of
   design-tokens sets/lexicon-look.ts, and nothing here names a colour or a face. A hit's look is fitted to the room the
   field's own face gives the word (`--words-squeeze`), so a caret after it stands where the field draws it. */
.block-composer[data-words-drawn="yes"]:has(+ .words-mirror) { -webkit-text-fill-color: transparent; }
.words-mirror { position: absolute; margin: 0; border: 0; box-sizing: border-box; overflow: hidden; pointer-events: none; user-select: none;
  background: transparent; white-space: pre-wrap; }
.words-hit { position: relative; color: transparent; background: var(--words-ground); }
.words-look { position: absolute; left: 0; top: 0; white-space: pre; transform-origin: 0 50%; transform: scaleX(var(--words-squeeze, 1));
  color: var(--words-color); font-family: var(--words-family); font-weight: var(--words-weight); font-style: var(--words-style);
  letter-spacing: var(--words-tracking); text-transform: var(--words-case); text-shadow: 0 0 var(--words-glow) var(--words-color); }
.words-hit[data-words-line="under"] > .words-look, .words-hit[data-words-line="under"][data-words-split="yes"] { text-decoration-line: underline;
  text-decoration-style: var(--words-line); text-decoration-color: var(--words-line-color); text-decoration-thickness: var(--words-line-thickness);
  text-underline-offset: var(--words-line-offset); }
/* a hit the field breaks over two lines: in the field's face, with the colour, glow and line of its key */
.words-hit[data-words-split="yes"] { color: var(--words-color); text-shadow: 0 0 var(--words-glow) var(--words-color); }
.words-hit[data-words-split="yes"] > .words-look { display: none; }
.words-hit[data-words="brand"] { --words-family: var(--plait-type-lexicon-brand-family); --words-weight: var(--plait-type-lexicon-brand-weight); --words-style: var(--plait-type-lexicon-brand-style); --words-tracking: var(--plait-type-lexicon-brand-tracking); --words-case: var(--plait-type-lexicon-brand-case);
  --words-line: var(--plait-type-lexicon-brand-line); --words-line-thickness: var(--plait-type-lexicon-brand-line-thickness); --words-line-offset: var(--plait-type-lexicon-brand-line-offset); --words-glow: var(--plait-glow-lexicon-brand);
  --words-color: var(--plait-color-lexicon-brand); --words-line-color: var(--plait-color-lexicon-brand-line); --words-ground: var(--plait-color-lexicon-brand-ground); }
.words-hit[data-words="code"] { --words-family: var(--plait-type-lexicon-code-family); --words-weight: var(--plait-type-lexicon-code-weight); --words-style: var(--plait-type-lexicon-code-style); --words-tracking: var(--plait-type-lexicon-code-tracking); --words-case: var(--plait-type-lexicon-code-case);
  --words-line: var(--plait-type-lexicon-code-line); --words-line-thickness: var(--plait-type-lexicon-code-line-thickness); --words-line-offset: var(--plait-type-lexicon-code-line-offset); --words-glow: var(--plait-glow-lexicon-code);
  --words-color: var(--plait-color-lexicon-code); --words-line-color: var(--plait-color-lexicon-code-line); --words-ground: var(--plait-color-lexicon-code-ground); }
.words-hit[data-words="stage"] { --words-family: var(--plait-type-lexicon-stage-family); --words-weight: var(--plait-type-lexicon-stage-weight); --words-style: var(--plait-type-lexicon-stage-style); --words-tracking: var(--plait-type-lexicon-stage-tracking); --words-case: var(--plait-type-lexicon-stage-case);
  --words-line: var(--plait-type-lexicon-stage-line); --words-line-thickness: var(--plait-type-lexicon-stage-line-thickness); --words-line-offset: var(--plait-type-lexicon-stage-line-offset); --words-glow: var(--plait-glow-lexicon-stage);
  --words-color: var(--plait-color-lexicon-stage); --words-line-color: var(--plait-color-lexicon-stage-line); --words-ground: var(--plait-color-lexicon-stage-ground); }
.words-hit[data-words="product"] { --words-family: var(--plait-type-lexicon-product-family); --words-weight: var(--plait-type-lexicon-product-weight); --words-style: var(--plait-type-lexicon-product-style); --words-tracking: var(--plait-type-lexicon-product-tracking); --words-case: var(--plait-type-lexicon-product-case);
  --words-line: var(--plait-type-lexicon-product-line); --words-line-thickness: var(--plait-type-lexicon-product-line-thickness); --words-line-offset: var(--plait-type-lexicon-product-line-offset); --words-glow: var(--plait-glow-lexicon-product);
  --words-color: var(--plait-color-lexicon-product); --words-line-color: var(--plait-color-lexicon-product-line); --words-ground: var(--plait-color-lexicon-product-ground); }
.words-hit[data-words="name"] { --words-family: var(--plait-type-lexicon-name-family); --words-weight: var(--plait-type-lexicon-name-weight); --words-style: var(--plait-type-lexicon-name-style); --words-tracking: var(--plait-type-lexicon-name-tracking); --words-case: var(--plait-type-lexicon-name-case);
  --words-line: var(--plait-type-lexicon-name-line); --words-line-thickness: var(--plait-type-lexicon-name-line-thickness); --words-line-offset: var(--plait-type-lexicon-name-line-offset); --words-glow: var(--plait-glow-lexicon-name);
  --words-color: var(--plait-color-lexicon-name); --words-line-color: var(--plait-color-lexicon-name-line); --words-ground: var(--plait-color-lexicon-name-ground); }
.words-hit[data-words="term"] { --words-family: var(--plait-type-lexicon-term-family); --words-weight: var(--plait-type-lexicon-term-weight); --words-style: var(--plait-type-lexicon-term-style); --words-tracking: var(--plait-type-lexicon-term-tracking); --words-case: var(--plait-type-lexicon-term-case);
  --words-line: var(--plait-type-lexicon-term-line); --words-line-thickness: var(--plait-type-lexicon-term-line-thickness); --words-line-offset: var(--plait-type-lexicon-term-line-offset); --words-glow: var(--plait-glow-lexicon-term);
  --words-color: var(--plait-color-lexicon-term); --words-line-color: var(--plait-color-lexicon-term-line); --words-ground: var(--plait-color-lexicon-term-ground); }
.words-hit[data-words="own"] { --words-family: var(--plait-type-lexicon-own-family); --words-weight: var(--plait-type-lexicon-own-weight); --words-style: var(--plait-type-lexicon-own-style); --words-tracking: var(--plait-type-lexicon-own-tracking); --words-case: var(--plait-type-lexicon-own-case);
  --words-line: var(--plait-type-lexicon-own-line); --words-line-thickness: var(--plait-type-lexicon-own-line-thickness); --words-line-offset: var(--plait-type-lexicon-own-line-offset); --words-glow: var(--plait-glow-lexicon-own);
  --words-color: var(--plait-color-lexicon-own); --words-line-color: var(--plait-color-lexicon-own-line); --words-ground: var(--plait-color-lexicon-own-ground); }
.words-hit[data-words="unknown"] { --words-family: var(--plait-type-lexicon-unknown-family); --words-weight: var(--plait-type-lexicon-unknown-weight); --words-style: var(--plait-type-lexicon-unknown-style); --words-tracking: var(--plait-type-lexicon-unknown-tracking); --words-case: var(--plait-type-lexicon-unknown-case);
  --words-line: var(--plait-type-lexicon-unknown-line); --words-line-thickness: var(--plait-type-lexicon-unknown-line-thickness); --words-line-offset: var(--plait-type-lexicon-unknown-line-offset); --words-glow: var(--plait-glow-lexicon-unknown);
  --words-color: var(--plait-color-lexicon-unknown); --words-line-color: var(--plait-color-lexicon-unknown-line); --words-ground: var(--plait-color-lexicon-unknown-ground); }
/* ── end of words */
/* ── anchors (A1, owner 2026-10-24, ./render/anchor.ts): a mark `(*a)` is drawn by the words layer in the look of the display
   key `lexicon.code` (`data-words="code"` above, `data-words-anchor` names it); no value of its own until PLAIT Suits gives
   one. The button beside the field is the line's symbol button (above); a refusal stands under the line in the caption. */
/* the sign in the face of `lexicon.code`, in the colour every symbol of the line has (no colour of its own, so none passes unmeasured) */
.block-input > .anchor-key .glyph { font-family: var(--plait-type-lexicon-code-family); font-weight: var(--plait-type-lexicon-code-weight); }
/* above the rule that lays every other child of the line under it (`:not(.block-composer):not(.input-buttons)`) */
.block-input[data-line="yes"] > button.anchor-key:not(.block-composer):not(.input-buttons) { order: 0; flex: none; flex-basis: auto; }
.block-input:not([data-line="yes"]) > .anchor-key { min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); }
.block-input > .anchor-said { margin: 0; padding: 0 var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-input[data-line="yes"] > .anchor-said { order: 3; flex-basis: 100%; }
/* ── end of anchors */
/* ── the date field (owner 2026-10-23, One's time report: "mach datumfeld plaitig", then "viel zu unplaitig", RULE-032):
   the browser draws nothing (U1): the field is a button naming the day in the reader's language (./render/when.ts), the
   calendar the carrier's glass dialog over the page (./render/date-picker.ts): the held day in the accent, today ringed,
   the days of the neighbouring months quiet. Only tokens (U4), the edge the suit's rim; focus is the global ring. Every target as large as a finger. */
.block-date-field[data-plait-date="picker"] { display: flex; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.block-date-field[data-plait-date="picker"][data-intrinsic="stacked"] { flex-wrap: wrap; }
.block-date-field > .invalid { order: 2; color: var(--plait-color-danger-text, var(--plait-color-danger)); font-size: var(--plait-type-caption-size); }
.block-date-field > .date-open {
  display: inline-flex; align-items: center; gap: var(--plait-space-sm); box-sizing: border-box;
  min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-md); margin: 0;
  border: var(--plait-material-rim-width) solid var(--plait-color-border); border-radius: var(--plait-control-radius);
  background: var(--plait-color-surface); color: var(--plait-color-text); font: inherit; font-variant-numeric: tabular-nums;
}
.block-date-field > .date-open .icon { display: inline-block; width: var(--plait-size-icon); height: var(--plait-size-icon); color: var(--plait-color-text-muted); }
.block-date-field > .date-open:hover, .block-date-field > .date-open[aria-expanded="true"] { border-color: var(--plait-color-accent); }
.block-date-field > .date-open:hover .icon, .block-date-field > .date-open[aria-expanded="true"] .icon { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.date-picker {
  box-sizing: border-box; width: min(calc(100% - 2 * var(--plait-space-md)), var(--plait-device-phone-short)); max-height: calc(100% - 2 * var(--plait-space-md));
  margin: auto; padding: var(--plait-space-md); display: grid; gap: var(--plait-space-sm); overflow-y: auto;
  border: var(--plait-material-rim-width) solid var(--plait-color-border); border-radius: var(--plait-radius-xl);
  background: var(--plait-foot-ground); backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass);
  color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised);
  font-family: var(--plait-type-ui-family); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
.date-picker:not([popover]) { margin: var(--plait-space-xs) 0 0; }
.date-picker:not([popover])[hidden] { display: none; }
.date-picker[popover]:not(:popover-open) { display: none; }
.date-picker::backdrop { background: var(--plait-decor-veil); }
.date-picker-head { display: flex; align-items: center; gap: var(--plait-space-xs); }
.date-picker-month { flex: 1 1 auto; text-align: center; text-transform: capitalize; }
.date-picker .date-picker-step.icon {
  box-sizing: border-box; flex: none; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size);
  padding: calc((var(--ergonomics-target-size) - var(--plait-size-icon)) / 2); margin: 0;
  background: transparent; border: 0; border-radius: var(--plait-radius-sm); color: var(--plait-color-text-muted);
}
.date-picker .date-picker-step.icon:hover { color: var(--plait-color-accent-text, var(--plait-color-accent)); background: var(--plait-hover-ground); }
.date-picker-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--plait-space-xs); }
.date-picker-weekday { display: grid; place-items: center; padding: var(--plait-space-xs) 0;
  color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); text-transform: capitalize; }
.date-picker-day {
  box-sizing: border-box; min-width: 0; height: var(--ergonomics-target-size); padding: 0; margin: 0;
  border: var(--plait-material-rim-width) solid transparent; border-radius: var(--plait-radius-md); background: transparent;
  color: var(--plait-color-text); font: inherit; font-variant-numeric: tabular-nums;
}
.date-picker-day[data-in-month="no"] { color: var(--plait-color-text-muted); }
.date-picker-day:hover { background: var(--plait-hover-ground); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.date-picker-day[data-today="yes"] { border-color: var(--plait-color-accent); }
.date-picker-day[aria-pressed="true"] { background: var(--plait-color-accent); border-color: var(--plait-color-accent); color: var(--plait-color-on-accent); }
.date-picker-foot { display: flex; justify-content: flex-end; }
.date-picker-today {
  min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-md); border: var(--plait-material-rim-width) solid var(--plait-color-border);
  border-radius: var(--plait-control-radius); background: transparent; color: var(--plait-color-text); font: inherit;
}
.date-picker-today:hover { color: var(--plait-color-accent-text, var(--plait-color-accent)); border-color: var(--plait-color-accent); background: var(--plait-hover-ground); }

/* ── flow (Planner Application 2026-10-16, PLAIT Workflow's overview): steps as a flow in lanes, down on a phone (narrow),
   across otherwise; each step a node (symbol, words, its stage as a SIGN beside its word, never the colour alone), a tap
   opens its panel as a glass dialog over the page (the carrier pairs `data-plait-menu`, as the menu of media-list).
   Sounds: good = a filled dot (ok, green: final, met), info = a ring with a dot (built), warning = a half dot (warn:
   bootstrap, missing), alarm = a dot in danger (broken), neutral = a dashed ring (planned, not measured). No violet. */
.block-flow { display: grid; gap: var(--plait-space-lg); min-width: 0; }
.block-flow.flow-empty { color: var(--plait-color-text-muted); }
.block-flow .flow-lane { display: grid; gap: var(--plait-space-xs); min-width: 0; }
.block-flow .flow-lane-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--plait-space-sm); }
.block-flow .flow-lane-tag { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-family: var(--plait-type-mono-family); }
.block-flow .flow-lane-title { margin: 0; font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); color: var(--plait-color-text); }
.block-flow .flow-lane-note { margin: 0 0 var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-flow .flow-steps { list-style: none; margin: 0; padding: 0; display: flex; min-width: 0; }
.block-flow[data-intrinsic="down"] .flow-steps { flex-direction: column; gap: var(--plait-space-sm); }
/* across only where the WHOLE lane fits: no scroll inside, so its measured need is every step side by side (E18 picks down otherwise) */
.block-flow[data-intrinsic="across"] .flow-steps { flex-direction: row; flex-wrap: nowrap; }
.block-flow .flow-step { position: relative; min-width: 0; }
.block-flow[data-intrinsic="across"] .flow-step { flex: 0 0 calc(var(--ergonomics-target-size) * 3); }
/* the line of the flow: from one dot to the next (down: below the dot; across: right of it) */
.block-flow .flow-step:not(:last-child)::after { content: ""; position: absolute; width: 0; height: 0; border: 0 solid var(--plait-color-border); pointer-events: none; }
.block-flow[data-intrinsic="down"] .flow-step:not(:last-child)::after {
  left: calc(var(--plait-space-xs) + var(--ergonomics-target-size) / 2); top: calc(var(--plait-space-xs) + var(--ergonomics-target-size)); bottom: calc(-1 * (var(--plait-space-sm) + var(--plait-space-xs))); height: auto; border-left-width: 2px;
}
.block-flow[data-intrinsic="across"] .flow-step:not(:last-child)::after {
  top: calc(var(--plait-space-xs) + var(--ergonomics-target-size) / 2); left: calc(50% + var(--ergonomics-target-size) / 2); width: calc(100% - var(--ergonomics-target-size)); border-top-width: 2px;
}
.block-flow .flow-node {
  box-sizing: border-box; display: flex; align-items: center; gap: var(--plait-space-sm); width: 100%; height: auto; min-height: var(--ergonomics-target-size);
  padding: var(--plait-space-xs); margin: 0; background: transparent; border: 0; border-radius: var(--plait-radius-md);
  color: var(--plait-color-text); font: inherit; text-align: start; cursor: pointer;
}
.block-flow[data-intrinsic="across"] .flow-node { flex-direction: column; text-align: center; }
.block-flow .flow-node:hover, .block-flow .flow-node[aria-expanded="true"] { background: var(--plait-hover-ground); }
.block-flow .flow-dot {
  box-sizing: border-box; position: relative; z-index: 1; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); border-radius: 50%;
  border: 2px solid var(--plait-color-border); background: var(--plait-color-bg); color: var(--plait-color-text);
}
.block-flow .flow-node[data-sound="good"] .flow-dot { border-color: var(--plait-color-ok); }
.block-flow .flow-node[data-sound="info"] .flow-dot { border-color: var(--plait-color-info); }
.block-flow .flow-node[data-sound="warning"] .flow-dot { border-color: var(--plait-color-warn); }
.block-flow .flow-node[data-sound="alarm"] .flow-dot { border-color: var(--plait-color-danger); }
.block-flow .flow-node[data-sound="neutral"] .flow-dot { border-style: dashed; }
.block-flow .flow-number { font-weight: var(--plait-type-label-weight); }
.block-flow .flow-label { display: grid; gap: 2px; min-width: 0; }
.block-flow .flow-title { overflow-wrap: anywhere; line-height: var(--plait-type-body-line-height); }
/* the sign of a mark, before its word */
.block-flow .flow-mark { display: inline-flex; align-items: center; gap: var(--plait-space-xs); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-flow[data-intrinsic="across"] .flow-mark { justify-content: center; }
.block-flow .flow-mark::before {
  content: ""; flex: none; box-sizing: border-box; width: 0.75em; height: 0.75em; border-radius: 50%; border: 2px solid var(--plait-color-border);
}
/* the signs are drawn with EDGES only (a full dot is a ring as thick as half the dot): a declared edge colour, no new ground */
.block-flow .flow-mark[data-sound="good"]::before { border-color: var(--plait-color-ok); border-width: 0.375em; }
.block-flow .flow-mark[data-sound="info"]::before { border-color: var(--plait-color-info); border-width: 0.2em; }
.block-flow .flow-mark[data-sound="warning"]::before { border-color: var(--plait-color-warn); border-left-width: 0.375em; }
.block-flow .flow-mark[data-sound="alarm"]::before { border-color: var(--plait-color-danger); border-width: 0.375em; border-radius: 0; }
.block-flow .flow-mark[data-sound="neutral"]::before { border-style: dashed; }
/* the panel: a glass dialog over the page (a popover, the top layer), in the middle of the screen over a veil */
.block-flow .flow-panel {
  box-sizing: border-box; width: min(calc(100% - 2 * var(--plait-space-md)), var(--plait-device-phone-short)); max-height: calc(100% - 2 * var(--plait-space-md));
  margin: auto; padding: var(--plait-space-md); display: grid; gap: var(--plait-space-sm); overflow-y: auto;
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-xl);
  background: var(--plait-foot-ground); backdrop-filter: var(--plait-glass); -webkit-backdrop-filter: var(--plait-glass);
  color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised);
  font-family: var(--plait-type-ui-family); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
.block-flow .flow-panel:not([popover])[hidden] { display: none; }
.block-flow .flow-panel[popover]:not(:popover-open) { display: none; }
.block-flow .flow-panel::backdrop { background: var(--plait-decor-veil); }
/* the CHAIN (owner 2026-10-26, „mach die pipeline grafisch plaitig“, the form of the pipeline diagram he took on 2026-10-22):
   numbered rings in the accent joined by arrows, read from left to right, `--flow-chain-row` steps to a row (all on a wide
   box, else rows); the subtitle and the mark below each ring; a step that works now breathes, one that stands still or
   failed changes its ring; how many things are in a step sits on its ring */
.block-flow[data-shape="chain"] { container-type: inline-size; }
.block-flow[data-shape="chain"] .flow-steps { display: grid; grid-template-columns: repeat(var(--flow-chain-all), minmax(0, 1fr)); row-gap: var(--plait-space-lg); column-gap: 0; }
/* below the width eight readable steps need, rows of `chain_row` (the arrow stops at each row's end, below) */
@container (max-width: 48em) { .block-flow[data-shape="chain"] .flow-steps { grid-template-columns: repeat(var(--flow-chain-row), minmax(0, 1fr)); } }
.block-flow[data-shape="chain"] .flow-step { min-width: 0; }
.block-flow[data-shape="chain"] .flow-node { flex-direction: column; align-items: center; text-align: center; gap: var(--plait-space-xs); padding: var(--plait-space-xs) 0; }
.block-flow[data-shape="chain"] .flow-dot { border-color: var(--plait-color-accent); border-width: calc(var(--plait-space-xs) / 2); font-size: var(--plait-type-title-size); }
.block-flow[data-shape="chain"] .flow-node[data-sound="good"] .flow-dot, .block-flow[data-shape="chain"] .flow-node[data-sound="info"] .flow-dot { border-color: var(--plait-color-accent); }
.block-flow[data-shape="chain"] .flow-node[data-sound="neutral"] .flow-dot { border-style: dashed; border-color: var(--plait-color-border); color: var(--plait-color-text-muted); }
.block-flow[data-shape="chain"] .flow-node[data-sound="info"] .flow-dot { animation: flow-chain-breathe var(--plait-motion-equalizer) ease-in-out infinite; }
@keyframes flow-chain-breathe { 0%, 100% { box-shadow: 0 0 0 0 var(--plait-color-accent-glow); } 50% { box-shadow: 0 0 0 0.5em var(--plait-color-accent-glow); } }
@media (prefers-reduced-motion: reduce) { .block-flow[data-shape="chain"] .flow-node[data-sound="info"] .flow-dot { animation: none; box-shadow: 0 0 0 0.25em var(--plait-color-accent-glow); } }
.block-flow[data-shape="chain"] .flow-count {
  position: absolute; top: -0.35em; right: -0.55em; min-width: 1.5em; padding: 0 0.3em; box-sizing: border-box; border-radius: 0.75em;
  background: var(--plait-color-accent); color: var(--plait-color-on-accent); font-size: var(--plait-type-caption-size); line-height: 1.5em; text-align: center;
}
.block-flow[data-shape="chain"] .flow-label { justify-items: center; }
.block-flow[data-shape="chain"] .flow-title { font-weight: var(--plait-type-label-weight); }
.block-flow[data-shape="chain"] .flow-subtitle { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); overflow-wrap: anywhere; }
/* in a chain the RING carries the state (as in the diagram): the mark's word below it is kept for a screen reader, the panel shows it */
.block-flow[data-shape="chain"] .flow-node .flow-mark { position: absolute; width: 0; height: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.block-flow[data-shape="chain"] .flow-node[data-sound="warning"] .flow-dot { border-color: var(--plait-color-warn); }
.block-flow[data-shape="chain"] .flow-node[data-sound="alarm"] .flow-dot { border-color: var(--plait-color-danger); }
/* the arrow from one ring to the next in the same row: a line in the accent and its head, never across a row's end */
.block-flow[data-shape="chain"] .flow-step:not(:last-child)::after {
  top: calc(var(--plait-space-xs) * 2 + var(--ergonomics-target-size) / 2); left: calc(50% + var(--ergonomics-target-size) / 2 + var(--plait-space-xs));
  width: calc(100% - var(--ergonomics-target-size) - var(--plait-space-xs) * 2 - 0.4em); height: 0; border: 0 solid var(--plait-color-accent); border-top-width: calc(var(--plait-space-xs) / 2);
}
.block-flow[data-shape="chain"] .flow-step:not(:last-child)::before {
  content: ""; position: absolute; pointer-events: none; width: 0; height: 0;
  top: calc(var(--plait-space-xs) * 2 + var(--ergonomics-target-size) / 2 - 0.3em); left: calc(150% - var(--ergonomics-target-size) / 2 - var(--plait-space-xs) - 0.45em);
  border-style: solid; border-color: transparent; border-left-color: var(--plait-color-accent); border-width: 0.3em 0 0.3em 0.45em;
}
@container (max-width: 48em) {
.block-flow[data-shape="chain"] .flow-steps[data-chain-row="2"] .flow-step:nth-child(2n)::after, .block-flow[data-shape="chain"] .flow-steps[data-chain-row="2"] .flow-step:nth-child(2n)::before,
.block-flow[data-shape="chain"] .flow-steps[data-chain-row="3"] .flow-step:nth-child(3n)::after, .block-flow[data-shape="chain"] .flow-steps[data-chain-row="3"] .flow-step:nth-child(3n)::before,
.block-flow[data-shape="chain"] .flow-steps[data-chain-row="4"] .flow-step:nth-child(4n)::after, .block-flow[data-shape="chain"] .flow-steps[data-chain-row="4"] .flow-step:nth-child(4n)::before,
.block-flow[data-shape="chain"] .flow-steps[data-chain-row="5"] .flow-step:nth-child(5n)::after, .block-flow[data-shape="chain"] .flow-steps[data-chain-row="5"] .flow-step:nth-child(5n)::before { display: none; }
}
.block-flow .flow-panel-title { display: flex; gap: var(--plait-space-sm); align-items: baseline; margin: 0; font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); }
.block-flow .flow-panel-number { color: var(--plait-color-text-muted); }
.block-flow .flow-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--plait-space-xs) var(--plait-space-md); margin: 0; }
.block-flow .flow-facts dt { color: var(--plait-color-text-muted); }
.block-flow .flow-facts dd { margin: 0; overflow-wrap: anywhere; }
.block-flow .flow-items { display: grid; gap: var(--plait-space-xs); }
.block-flow .flow-items h5 { margin: var(--plait-space-xs) 0 0; font-size: var(--plait-type-label-size); font-weight: var(--plait-type-label-weight); color: var(--plait-color-text-muted); }
.block-flow .flow-items > ul, .block-flow .flow-lines, .block-flow .flow-evidence ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--plait-space-xs); }
.block-flow .flow-item { display: grid; gap: var(--plait-space-xs); padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); }
.block-flow .flow-item-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--plait-space-xs); }
.block-flow .flow-item-name { font-family: var(--plait-type-mono-family); font-weight: var(--plait-type-label-weight); }
.block-flow .flow-item-note { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-flow .flow-lines li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--plait-space-xs); font-size: var(--plait-type-caption-size); }
.block-flow details > summary { cursor: pointer; min-height: var(--ergonomics-target-size); display: flex; align-items: center; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-flow .flow-evidence li, .block-flow .flow-evidence p, .block-flow .flow-technical dd { font-family: var(--plait-type-mono-family); font-size: var(--plait-type-caption-size); overflow-wrap: anywhere; }
.block-flow .flow-evidence p { margin: 0 0 var(--plait-space-xs); font-family: inherit; }
/* PLAIT Workflow, Maße prüfen (Planner Application 2026-10-16): a picture with its marked places (marked-picture.ts, shared
   by picture-viewer and value-check). The layer of boxes lies EXACTLY over the picture: the picture fills the width with its
   own proportion, the svg (viewBox in the picture's pixels, preserveAspectRatio none) covers the same box. A box is an
   outline in a token's colour, never a fill: the block names the level (high accent, medium warn, low muted); the place being
   checked is drawn in the signal blue (info, the own blue; never violet), and green only where the person CONFIRMED it. */
.marked-picture { position: relative; }
.marked-picture-image { width: 100%; height: auto; display: block; border-radius: var(--plait-radius-md); }
.marked-picture-boxes { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.marked-picture[data-picture="absent"] { min-height: var(--ergonomics-target-size); border: 1px dashed var(--plait-color-border); border-radius: var(--plait-radius-md); }
.marked-picture .marked-box { fill: none; }
.marked-picture .marked-box[data-chosen="yes"] { stroke: var(--plait-color-info); }
.value-check-card[data-confirmed="yes"] .marked-box[data-chosen="yes"] { stroke: var(--plait-color-ok); }
/* picture-viewer: one strip that scrolls inside its box and stops at every picture (scroll-snap); narrow one picture at a
   time, wide the next one shows at the edge so a reader sees there is more */
.block-picture-viewer { display: flex; gap: var(--plait-space-sm); overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: thin; }
.block-picture-viewer .picture-viewer-item { flex: 0 0 100%; margin: 0; scroll-snap-align: start; display: grid; gap: var(--plait-space-xs); min-width: 0; }
.block-picture-viewer[data-intrinsic="next_in_view"] .picture-viewer-item { flex-basis: 85%; }
/* in the strip a picture stands WHOLE in its box (one phone wide high, the surface's cell): the marked picture is as wide as
   its picture, so the layer of boxes still covers exactly the picture */
.block-picture-viewer { height: 100%; box-sizing: border-box; }
.block-picture-viewer .marked-picture { width: fit-content; max-width: 100%; margin-inline: auto; }
.block-picture-viewer .marked-picture-image { width: auto; max-width: 100%; max-height: calc(var(--plait-device-phone-short) - 8 * var(--plait-space-md)); }
.block-picture-viewer .picture-viewer-item:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-picture-viewer .picture-viewer-caption { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* value-check: one card per place; narrow the picture above the fields, wide the picture beside them */
.block-value-check { display: grid; gap: var(--plait-space-md); }
.block-value-check .value-check-card { display: grid; gap: var(--plait-space-sm); padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); min-width: 0; }
.block-value-check[data-intrinsic="two_column"] .value-check-card { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
.block-value-check[data-intrinsic="two_column"] .value-check-place { grid-column: 1 / -1; }
.block-value-check .value-check-card[data-confirmed="yes"] { border-color: var(--plait-color-ok); }
.block-value-check .value-check-place { margin: 0; font-weight: var(--plait-type-label-weight); }
.block-value-check .value-check-form { display: grid; gap: var(--plait-control-gap); min-width: 0; }
.block-value-check .field { display: flex; flex-direction: column; gap: var(--plait-space-xs); min-width: 0; }
.block-value-check .field_switch { flex-direction: row; align-items: center; justify-content: space-between; min-height: var(--ergonomics-target-size); }
.block-value-check .field_name { font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-value-check .field_value { min-width: 0; min-height: var(--ergonomics-target-size); }
.block-value-check .field_toggle { accent-color: var(--plait-color-ok); min-height: auto; }
.block-value-check .value-check-unit { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* Teil (Planner Application 2026-10-16): the unit of the field CHOSEN: mm while none or a length is chosen, ° for an angle, none for a text */
.block-value-check .value-check-unit[data-quantity="angle"] { display: none; }
.block-value-check .value-check-form:has(option[data-quantity="angle"]:checked) .value-check-unit[data-quantity="angle"] { display: inline; }
.block-value-check .value-check-form:has(option[data-quantity="angle"]:checked) .value-check-unit[data-quantity="length"],
.block-value-check .value-check-form:has(option[data-quantity="text"]:checked) .value-check-unit { display: none; }
.block-value-check .submit { justify-self: start; min-height: var(--ergonomics-target-size); }
.block-value-check .receipt { margin: 0; font-size: var(--plait-type-caption-size); }
.block-value-check .value-check-read { margin: 0; overflow-wrap: anywhere; }
/* file-download (K10): one button per format, a finger high; narrow one below another, wide in a row; the line of what
   happened below them, always in the tree (a live region that appears is not read out), empty and without height until it speaks */
.block-file-download { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
.block-file-download[data-intrinsic="one_below_another"] { flex-direction: column; align-items: stretch; }
.block-file-download .file-download { min-height: var(--ergonomics-target-size); }
.block-file-download[aria-busy="true"] .file-download { cursor: progress; }
.block-file-download .file-download[data-download-state="failed"] { border-color: var(--plait-color-danger); }
.block-file-download .file-download-said { flex-basis: 100%; margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-file-download .file-download[aria-disabled="true"] { cursor: not-allowed; color: var(--plait-color-text-muted); }
/* PLAIT Auth (render/copy.ts): what a tap on a code came to, said briefly by the carrier: the tile's edge and the line */
.block-code-tile .code-tile[data-copy-state="copied"] { border-color: var(--plait-color-ok); }
.block-code-tile .code-tile[data-copy-state="not-copied"] { border-color: var(--plait-color-danger); }
.block-code-tile .code-tile[data-copy-state="copying"] { cursor: progress; }
.block-code-tile .code-tile[aria-disabled="true"] { cursor: not-allowed; }
.block-code-tile .code-tile-said-line { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
/* qr-reading (owner 2026-10-24, QR aus Bilddatei): the codes of a picture, one card each, the text large and never cut (a
   web address wraps anywhere), copy and open a finger high; narrow the two buttons share the row; the picture below with
   every code outlined (marked-picture.ts) */
.block-qr-reading { display: flex; flex-direction: column; gap: var(--plait-space-sm); }
.block-qr-reading .qr-reading-empty, .block-qr-reading .qr-reading-none, .block-qr-reading .qr-reading-count { margin: 0; }
.block-qr-reading .qr-reading-unreadable, .block-qr-reading .qr-reading-more, .block-qr-reading .qr-reading-running, .block-qr-reading .qr-reading-failed { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-qr-reading .qr-reading-failed { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.block-qr-reading .qr-reading-codes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--plait-space-sm); }
.block-qr-reading .qr-reading-code { display: grid; grid-template-columns: auto 1fr; gap: var(--plait-space-xs) var(--plait-space-sm); padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface); }
.block-qr-reading .qr-reading-number { grid-row: span 3; align-self: start; min-width: var(--plait-size-icon); text-align: center; color: var(--plait-color-accent-text, var(--plait-color-accent)); font-weight: var(--plait-type-title-weight); }
.block-qr-reading .qr-reading-text { margin: 0; font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); line-height: var(--plait-type-body-line-height); overflow-wrap: anywhere; white-space: pre-wrap; user-select: text; }
.block-qr-reading .qr-reading-facts { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-qr-reading .qr-reading-actions { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); align-items: center; }
.block-qr-reading .qr-reading-actions .button { min-height: var(--ergonomics-target-size); }
.block-qr-reading[data-intrinsic="one_below_another"] .qr-reading-actions .button { flex: 1 1 0; }
.block-qr-reading .qr-reading-copy[data-copy-state="copied"] { border-color: var(--plait-color-ok); }
.block-qr-reading .qr-reading-copy[data-copy-state="not-copied"] { border-color: var(--plait-color-danger); }
.block-qr-reading .qr-reading-said { flex-basis: 100%; margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-qr-reading .marked-box { stroke-width: 3; }

/* ══ Owner 2026-10-17 (PLAIT Control, F4 to F8): THE WINDOW AND ITS COVERS, the Ship look's dialog (D9) of
   render/window-dialog.ts on the same veil and surface as the carrier's settings. Only tokens: a cover on the ground of a
   field, its presses as quiet buttons, the slider in the accent, a refusal in the danger tone. */
/* Owner 2026-10-22 (PLAIT Pixel): THE CARRIER'S CONFIRMATION of a destructive way back, render/confirm.ts, on the same veil
   and surface as the carrier's settings. Only tokens: the question in the text, how many more go with it muted, the two
   choices side by side, each at least the target size; the confirm button framed in the danger tone. */
.confirm-dialog-question { margin: 0; font-weight: var(--plait-type-label-weight); }
.confirm-dialog-detail { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.confirm-dialog-choices { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--plait-space-sm); }
.confirm-dialog-choices .button { min-height: var(--ergonomics-target-size); }
.confirm-dialog-yes { border-color: var(--plait-color-danger); color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.window-dialog-body { display: grid; gap: var(--plait-space-md); }
.window-dialog-reading, .window-dialog-choose, .window-dialog-note, .window-dialog-none-covers { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.window-dialog-none { margin: 0; font-weight: var(--plait-type-label-weight); }
.window-dialog-unreachable, .window-dialog-said { margin: 0; color: var(--plait-color-danger-text, var(--plait-color-danger)); font-size: var(--plait-type-caption-size); }
.window-dialog-device {
  display: grid; gap: var(--plait-space-sm); padding: var(--plait-space-sm); border: 1px solid var(--plait-color-border);
  border-radius: var(--plait-radius-lg); background: var(--plait-color-piece);
}
.window-dialog-name { overflow-wrap: anywhere; }
.window-dialog-position { margin: 0; font-variant-numeric: tabular-nums; }
.window-dialog-position:not([data-state="result"]) { color: var(--plait-color-text-muted); }
.window-dialog-moves { display: flex; flex-wrap: wrap; gap: var(--plait-space-sm); }
.window-dialog-covers { display: grid; gap: var(--plait-space-sm); }
.window-dialog-move, .window-dialog-cover {
  min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); padding-inline: var(--plait-space-md);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface-elevated);
  color: var(--plait-color-text); font: inherit; cursor: pointer; text-align: start;
}
.window-dialog-move:hover, .window-dialog-cover:hover { border-color: var(--plait-color-accent); }
.window-dialog-move:disabled { opacity: var(--plait-opacity-disabled); cursor: default; }
.window-dialog-move:focus-visible, .window-dialog-cover:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.window-dialog-quiet .window-dialog-move { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.window-dialog-add { justify-self: start; }
.window-dialog-scale { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size); }
.window-dialog-scale-name, .window-dialog-value { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
.window-dialog-range { width: 100%; min-height: var(--ergonomics-target-size); accent-color: var(--plait-color-accent); }

/* code-tile ring (PLAIT Auth): colours from tokens here, never a style attribute in the block (offline CSP style-src 'self') */
.block-code-tile .code-ring circle { fill: none; }
.block-code-tile .code-ring-track { stroke: var(--plait-color-border); }
.block-code-tile .code-ring-left { stroke: var(--plait-color-accent); }
.block-code-tile .code-tile[data-state="runs-out"] .code-ring-left { stroke: var(--plait-color-warn); }

/* ══ Owner 2026-10-19 (via Waterproofing: "Sehr geil die overlay-application-ansicht. Sowas sollten wir als fixen
   Bestandteil jeder application einführen … Die card hat eckenrundungen, der inhalt nicht."): AN APPLICATION OVER
   ANOTHER PAGE, render/overlay.ts. The Ship look's dialog (as the carrier's settings): a veil, a raised panel from the
   head's edge to the foot's, the application in a place of its own clipped to the panel's inner radius. Only tokens. */
.plait-overlay-veil {
  /* a row that centres the panel and stretches it over the whole height (a grid's one row would only be as high as the panel) */
  position: fixed; inset: 0; z-index: 40; display: flex; justify-content: center; align-items: stretch; padding: var(--plait-space-md);
  /* the page stays seen behind the glass (the owner's picture: the chat blurred behind the panel) */
  background: color-mix(in srgb, var(--plait-color-bg) 35%, transparent); backdrop-filter: blur(var(--plait-space-xs));
}
.plait-overlay {
  /* a column: the head, the state while it stands, and the place taking the rest (a grid's rows would shift once the state goes) */
  display: flex; flex-direction: column; gap: var(--plait-space-sm); width: min(100%, var(--plait-device-phone-short)); min-height: 0;
  padding: var(--plait-space-md); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-xl);
  background: var(--plait-color-surface-elevated); color: var(--plait-color-text); box-shadow: var(--plait-elevation-raised);
  font-family: var(--plait-type-ui-family); font-size: var(--plait-type-body-size); line-height: var(--plait-type-body-line-height);
}
.plait-overlay-head { display: flex; align-items: center; justify-content: space-between; gap: var(--plait-space-sm); }
.plait-overlay-title { margin: 0; font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); overflow-wrap: anywhere; }
/* a circle one finger's target wide and high: width AND height, no padding, and the ratio held even where the target size
   is not resolved (owner 2026-10-19: "das schließen icon oben rechts ist oval", measured 30.6 x 34) */
.plait-overlay-close {
  flex: none; display: grid; place-items: center; box-sizing: border-box; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size);
  aspect-ratio: 1; padding: 0; line-height: 1; border-radius: 50%;
  border: 1px solid var(--plait-color-border); background: var(--plait-color-surface-elevated); color: var(--plait-color-text); cursor: pointer; font: inherit;
}
.plait-overlay-close:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.plait-overlay-state { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.plait-overlay-state:empty { display: none; }
.plait-overlay-state[data-state="failed"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
/* the application lies in a place of its own, rounded like the panel's inside and clipped to it, scrolling in itself */
/* the frame stands for a page (`data-plait-page`, its tokens) and so CONTAINS its fixed parts (`contain`): it is made the
   size of the screen itself, so the veil inside it covers the screen and not a box as high as the panel */
.stage-frame.plait-overlay-frame { position: fixed; inset: 0; z-index: 40; height: auto; overflow: visible; background: transparent; }
.plait-overlay-frame[hidden] { display: none; }
/* plait-platform-0200 (owner 2026-10-26: "Die Galerie und auch Link soll sich in ganz main öffnen, so wie es vorher bei der
   Galerie war."): handed an area (a portal's main), the frame covers exactly that box: no veil, no narrow card, no second
   rim, the page's own ground; the head (title, close) stays and the application takes the rest */
/* plait-platform-0204: the box is the frame's own runtime measure (render/overlay-frame.ts), no suite token, so it carries no
   `--plait-` name: every `--plait-` value a page reads is declared at the root (35-A1) */
.stage-frame.plait-overlay-frame[data-fill="area"] {
  inset: auto; top: var(--overlay-area-top, 0px); left: var(--overlay-area-left, 0px);
  width: var(--overlay-area-width, 100vw); height: var(--overlay-area-height, 100dvh);
}
.plait-overlay-frame[data-fill="area"] .plait-overlay-veil { position: absolute; padding: 0; background: var(--plait-color-bg); backdrop-filter: none; }
.plait-overlay-frame[data-fill="area"] .plait-overlay {
  width: 100%; max-width: none; padding: var(--plait-space-xs) var(--plait-space-sm) 0; border: 0; border-radius: 0; box-shadow: none; background: var(--plait-color-bg);
}
.plait-overlay-frame[data-fill="area"] .plait-overlay-place { border-radius: 0; }
.plait-overlay-place {
  flex: 1 1 auto; min-height: 0; overflow: hidden auto; overscroll-behavior: contain; border-radius: var(--plait-radius-lg);
  /* plait-platform-0198b (coordinator 26.10.: "Kein Rahmen im Rahmen"): the application stands on the frame's own card, no
     second rim, no second ground; its corners still follow the card's (the owner's word of 2026-10-19) */
  border: 0; background: transparent;
}

/* Karte Stufe 4 (block map, ./render/map-frame.ts, ./render/map-view.ts): the free map as ONE card in the suit. The search
   field above the picture, the picture filling the card, the sources, the way back and the kind of map as bare icons in a
   plain bar on the picture's top edge (the 3D's form), PLAIT's pins in the accent (a saved place) and the signal (a hit),
   the places as words for a reader and for a carrier without WebGL, the ways a tap presses invisible to the eye. Every
   colour a token of the suit; MapLibre's own sheet is not loaded, the few rules its picture needs stand here. */
.block-places-map { position: relative; display: grid; gap: var(--plait-space-sm); width: 100%; min-width: 0; }
.block-places-map .map-search { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); margin: 0; }
.block-places-map .map-search-field { flex: 1 1 8rem; min-width: 0; min-height: var(--plait-control-height); box-sizing: border-box; padding: 0 var(--plait-space-md);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-control-radius); background: var(--plait-color-surface); color: var(--plait-color-text); font: inherit; }
.block-places-map .map-search-field:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-places-map .map-search-run { display: inline-grid; place-items: center; flex: 0 0 auto; width: var(--plait-control-height); height: var(--plait-control-height); margin: 0; padding: 0;
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 45%, transparent); border-radius: var(--plait-control-radius); background: transparent; color: var(--plait-color-accent-text, var(--plait-color-accent)); cursor: pointer; }
.block-places-map .map-search-run:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-places-map .map-search .delivery-result { flex: 1 0 100%; margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
/* 2026-10-19 (owner: the map in a box): the picture fills the screen below the title and the search */
.block-places-map .map-picture { position: relative; height: max(18rem, calc(100dvh - 12rem)); overflow: hidden; border-radius: var(--plait-radius-lg);
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 22%, transparent); background: var(--plait-color-surface); }
.block-places-map .map-sentence { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; padding: var(--plait-space-md); text-align: center;
  color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-places-map .map-sentence[hidden] { display: none; }
.block-places-map .map-canvas { position: absolute; inset: 0; }
.block-places-map .maplibregl-map { position: absolute; inset: 0; overflow: hidden; -webkit-tap-highlight-color: transparent; }
.block-places-map .maplibregl-canvas-container, .block-places-map .maplibregl-canvas { position: absolute; left: 0; top: 0; }
.block-places-map .maplibregl-canvas-container { touch-action: none; }
.block-places-map .maplibregl-canvas { display: block; outline: none; }
.block-places-map .maplibregl-marker { position: absolute; top: 0; left: 0; will-change: transform; }
.block-places-map .maplibregl-control-container { display: none; }
.block-places-map .map-tools { position: absolute; z-index: 2; right: var(--plait-space-xs); top: var(--plait-space-xs); display: flex; align-items: center; gap: 0;
  padding: 0 var(--plait-space-xs); border-radius: var(--plait-radius-md); background: color-mix(in srgb, var(--plait-color-surface) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--plait-color-accent) 18%, transparent); }
.block-places-map .map-tools .segments-menu { position: static; }
.block-places-map .map-tools .segments-menu > .segments-icon { height: calc(var(--plait-control-height) * 0.8); border-color: transparent; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
.block-places-map .map-tools .segments-menu[open] > .segments-icon { background: var(--plait-color-surface-elevated); }
.block-places-map .map-tools .segments-menu > .segments-options { left: auto; right: 0; min-width: min(16rem, 80vw); max-width: 80vw; }
.block-places-map .map-credits { display: grid; gap: var(--plait-space-xs); white-space: normal; }
.block-places-map .map-source { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text); overflow-wrap: anywhere; }
.block-places-map .map-reset { display: inline-grid; place-items: center; margin: 0; padding: 0; width: var(--plait-control-height); height: calc(var(--plait-control-height) * 0.8);
  border: 0; border-radius: 999px; background: transparent; cursor: pointer; color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-places-map .map-reset:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-places-map .map-pin { position: relative; display: grid; justify-items: center; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; color: var(--plait-color-text); }
.block-places-map .map-pin svg { display: block; width: 26px; height: 34px; }
.block-places-map .map-pin .map-pin-drop { fill: var(--plait-color-accent); stroke: var(--plait-color-surface); stroke-width: 1.5; }
.block-places-map .map-pin[data-kind="hit"] .map-pin-drop { fill: var(--plait-color-info); }
.block-places-map .map-pin-name { position: absolute; top: 100%; max-width: 9rem; padding: 0 var(--plait-space-xs); border-radius: var(--plait-radius-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--plait-type-caption-size); color: var(--plait-color-text); background: color-mix(in srgb, var(--plait-color-surface) 82%, transparent); }
.block-places-map .map-group { display: grid; place-items: center; min-width: 34px; height: 34px; padding: 0 var(--plait-space-xs); box-sizing: border-box; cursor: pointer;
  border-radius: var(--plait-radius-md); border: 2px solid var(--plait-color-accent); background: color-mix(in srgb, var(--plait-color-surface) 88%, transparent);
  color: var(--plait-color-text); font: inherit; font-weight: var(--plait-type-label-weight); font-variant-numeric: tabular-nums; }
.block-places-map .map-group[data-kind="hit"] { border-color: var(--plait-color-info); }
.block-places-map .map-pin:focus-visible, .block-places-map .map-group:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-places-map .map-places { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; padding: 0; }
.block-places-map:has(.map-sentence:not([hidden])) .map-places { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal;
  display: grid; gap: var(--plait-space-xs); list-style: none; color: var(--plait-color-text); }
.block-places-map .map-ways { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Karte Stufe 5: the marks (the PoC's drop in the symbol's tone, the glyph in the page's own colour on it), own images as they are, the sheet of a long press */
.block-places-map .map-mark { position: relative; display: grid; justify-items: center; cursor: pointer; touch-action: none; --map-mark-tone: var(--plait-color-ok); }
.block-places-map .map-mark svg { display: block; width: 36px; height: 43px; }
.block-places-map .map-mark .map-mark-drop { fill: var(--map-mark-tone); stroke: var(--plait-color-surface); stroke-width: 2; }
.block-places-map .map-mark .map-mark-glyph path { fill: none; stroke: var(--plait-color-on-accent); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.block-places-map .map-mark .map-mark-glyph path[data-fill="yes"] { fill: var(--plait-color-on-accent); stroke: none; }
.block-places-map .map-mark[data-own="yes"] img { display: block; width: 40px; height: 40px; object-fit: contain; }
.block-places-map .map-mark:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
.block-places-map .map-mark-form { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; margin: 0; }
.block-places-map .map-mark-form:has(.map-mark-receipt[data-receipt="no"]) { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; }
.block-places-map .map-mark-hint { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-places-map .map-mark-receipt { margin: 0; font-size: var(--plait-type-caption-size); color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.block-places-map .map-sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; max-height: 70%; overflow: auto; padding: var(--plait-space-sm) var(--plait-space-md) var(--plait-space-md);
  border-radius: var(--plait-radius-lg) var(--plait-radius-lg) 0 0; background: var(--plait-color-surface-elevated); border-top: 1px solid var(--plait-color-border); }
.block-places-map .map-sheet-title { margin: 0 0 var(--plait-space-sm); font-size: var(--plait-type-caption-size); color: var(--plait-color-text-muted); }
.block-places-map .map-sheet-choices { display: grid; grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr)); gap: var(--plait-space-sm); }
.block-places-map .map-sheet-choice { display: grid; justify-items: center; align-content: start; gap: var(--plait-space-xs); min-height: var(--plait-control-height); padding: var(--plait-space-sm) var(--plait-space-xs);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface); color: var(--plait-color-text); font: inherit; font-size: var(--plait-type-caption-size); cursor: pointer; }
.block-places-map .map-sheet-choice[data-danger="yes"] { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.block-places-map .map-sheet-choice .map-mark { pointer-events: none; }
.block-places-map .map-sheet-choice:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }

/* plait-platform-0198 (owner 2026-10-26, PLAIT Gallery as the Crew gallery: "Umschalter Raster/Vollbild"): ways that say
   which of them leads where the person already is (`aria-pressed`) are a SWITCH, not a list of ways: one rimmed row, the
   shown one on the elevated ground, no chevron. For every application, never named per block. */
.block-button:not(:has(> [data-acts])):has(> [data-plait-go-area][aria-pressed]) {
  display: inline-flex; justify-self: start; gap: var(--plait-space-xs); padding: var(--plait-space-xs);
  border: 1px solid var(--plait-material-control-rim, var(--plait-color-border)); border-radius: var(--plait-radius-xl);
}
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed] {
  width: auto; min-height: var(--plait-control-height); padding: 0 var(--plait-space-md); border: 0; border-radius: var(--plait-radius-xl);
  background: transparent; color: var(--plait-color-text-muted); justify-content: center;
}
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed] + [data-plait-go-area] { border-top: 0; }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed]::after { content: none; }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed="true"] { background: var(--plait-color-surface-elevated); color: var(--plait-color-text); }

/* plait-platform-0198: `look: tiles` (block button, block file-download) and a LABELLED entry menu: the options of a picture
   as the Crew gallery had them, each a rimmed tile with its icon above its word, side by side and equally wide */
.block-button[data-look="tiles"], .block-file-download[data-look="tiles"] { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--plait-space-xs); width: 100%; }
.block-button[data-look="tiles"] > button.button, .block-file-download[data-look="tiles"] > .file-download.button, .segments-menu > .segments-icon.entry-menu-labelled {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--plait-space-xs);
  width: 100%; min-width: 0; height: auto; min-height: calc(var(--plait-control-height) * 1.75); padding: var(--plait-space-xs);
  border: 1px solid var(--plait-material-control-rim, var(--plait-color-border)); border-radius: var(--plait-radius-md);
  background: var(--plait-material-control, transparent); color: var(--plait-material-control-mark, var(--plait-color-text));
  font-size: var(--plait-type-caption-size); line-height: 1.2; white-space: nowrap; overflow: visible; letter-spacing: 0;
}
.block-button[data-look="tiles"] > button.button .button-word, .block-file-download[data-look="tiles"] > .file-download.button .button-word { font-size: var(--plait-type-caption-size); }
.block-button[data-look="tiles"] > button.button.active { border-color: var(--plait-color-accent); color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-button[data-look="tiles"] > button.button .icon, .block-file-download[data-look="tiles"] > .file-download.button .icon { color: var(--plait-color-accent-text, var(--plait-color-accent)); }
.block-button[data-look="tiles"] > .delivery-result.accepted { display: none; }
.block-file-download[data-look="tiles"] .file-download-said:empty { display: none; }
.segments-menu:has(> .segments-icon.entry-menu-labelled) { display: block; width: 100%; }
.segments-menu > .segments-icon.entry-menu-labelled .entry-menu-word { line-height: 1.2; }
/* plait-platform-0198b (coordinator 26.10.: "das Mehr-Menü erscheint als Blatt"): a labelled entry menu opens as a SHEET over
   the row it stands in, one choice a line, its icon before its word, as wide as a phone allows */
.segments-menu:has(> .entry-menu-labelled) > .segments-options { left: auto; right: 0; top: auto; bottom: calc(100% + var(--plait-space-sm));
  width: min(calc(100vw - var(--plait-space-xl) * 2), calc(var(--ergonomics-target-size) * 8)); min-width: 0; padding: var(--plait-space-sm); border-radius: var(--plait-radius-lg);
  box-shadow: var(--plait-elevation-control, none); }
.entry-menu-options .block-button[data-look="tiles"] { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: 1fr; gap: 0; }
.entry-menu-options .block-button[data-look="tiles"] > button.button { flex-direction: row; justify-content: flex-start; gap: var(--plait-space-md);
  min-height: var(--ergonomics-target-size, var(--plait-control-height)); padding: 0 var(--plait-space-md); border: 0; border-radius: var(--plait-radius-md);
  background: transparent; font-size: var(--plait-type-body-size); }
.entry-menu-options .block-button[data-look="tiles"] > button.button + button.button { border-top: 1px solid var(--plait-color-divider); border-radius: 0; }
.entry-menu-options .block-button[data-look="tiles"] > button.button .button-word { font-size: var(--plait-type-body-size); }
/* owner 2026-11-09 (PLAIT Browser, "Neue Seite" eingeklappt): an entry menu `look: fold` (./render/entry-menu.ts) is a button,
   its icon before its word; opened, its drawing unfolds IN THE FLOW below it, as wide as the piece, never over what follows */
.segments-menu.entry-menu[data-look="fold"] { display: block; width: 100%; }
.segments-menu > .segments-icon.entry-menu-fold {
  display: inline-flex; align-items: center; gap: var(--plait-space-xs); width: auto; height: auto;
  min-height: var(--ergonomics-target-size, var(--plait-control-height)); padding: 0 var(--plait-space-md);
  border-radius: var(--plait-control-radius); font-weight: var(--plait-type-label-weight);
}
.piece[data-menu="yes"] > .entry-menu[data-look="fold"] > .entry-menu-options {
  position: static; min-width: 0; width: 100%; box-sizing: border-box; margin-top: var(--plait-space-sm); padding: 0;
  border: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
}
/* plait-platform-0198: an OPEN entry menu reaches out of its cell (a cell sized by the rule rolls and would clip its panel) */
.layout .cell:has(.entry-menu[open]) { overflow: visible; z-index: 4; }

/* plait-platform-0198b: segments `look: pager`: the held place `3 / 9` between a step back and a step on, each round */
.block-segments[data-look="pager"] { display: flex; align-items: center; justify-content: center; gap: var(--plait-space-md); }
.block-segments[data-look="pager"] .segments-place { min-width: var(--ergonomics-target-size); text-align: center; font-variant-numeric: tabular-nums; color: var(--plait-color-text); }
.block-segments[data-look="pager"] .segments-step { position: relative; display: inline-grid; place-items: center; width: var(--plait-control-height); height: var(--plait-control-height);
  border-radius: 999px; border: 1px solid var(--plait-material-control-rim, var(--plait-color-border)); color: var(--plait-color-text); cursor: pointer; }
.block-segments[data-look="pager"] .segments-step .segments-radio { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.block-segments[data-look="pager"] .segments-step[data-end="yes"] { opacity: var(--plait-opacity-disabled, 0.4); cursor: default; }
.area:has([data-plait-swipe]) img, #area:has([data-plait-swipe]) img { touch-action: pan-y; user-select: none; -webkit-user-drag: none; }
/* plait-platform-0198b: a round clip (`icon`), the gallery's "+" */
.block-paper-clip[data-look="round"] { display: inline-grid; place-items: center; width: var(--plait-control-height); height: var(--plait-control-height); padding: 0;
  border-radius: 999px; border: 1px solid var(--plait-material-control-rim, var(--plait-color-border)); background: var(--plait-material-control, transparent); color: var(--plait-color-text); }
/* plait-platform-0198b: chips stay on ONE line, the row rolls sideways inside its block where it must (never the page) */
.block-segments[data-look="chips"] { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.block-segments[data-look="chips"] .segments-choice { flex: none; }
/* plait-platform-0198b: the question's picture ticked stands alone over the width; a second tap gives the others back */
.block-question-card .question_zoom { position: relative; display: block; cursor: zoom-in; }
.block-question-card .question_zoom_box { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: inherit; }
.block-question-card .question_pictures:has(.question_zoom_box:checked) { grid-template-columns: 1fr; }
.block-question-card .question_pictures:has(.question_zoom_box:checked) .question_zoom:not(:has(.question_zoom_box:checked)) { display: none; }
.block-question-card .question_zoom:has(.question_zoom_box:checked) { cursor: zoom-out; }
.block-question-card .question_zoom:has(.question_zoom_box:checked) .question_picture { aspect-ratio: auto; object-fit: contain; max-height: 70vh; }
.block-question-card .question_zoom:has(.question_zoom_box:focus-visible) { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; border-radius: var(--plait-radius-md); }
/* plait-platform-0198b (coordinator 26.10.: "Der Platz gehört den Bildern"): on a phone the overlay frame keeps a thin edge to the
   page and to its own card, so what it holds has the width a page of its own would have. plait-platform-0204: no window step
   of its own (A57): the edge is the room a phone-wide card leaves beside it, at least the thin edge, at most the full one */
.plait-overlay-veil { padding: min(var(--plait-space-md), max(var(--plait-space-xs), calc((100vw - var(--plait-device-phone-short)) / 2))); }
.plait-overlay { padding: min(var(--plait-space-md), max(var(--plait-space-sm), calc((100vw - var(--plait-device-phone-short)) / 2))); }
/* plait-platform-0198b: a host drawn into a frame (the overlay) stands on the frame's card: its area keeps no edge of its own */
[data-framed="yes"] .area { padding: 0; }
/* chips stay on one line in a narrow box too (the coordinator's "Die Chips stehen in einer Zeile") */
.block-segments[data-look="chips"][data-intrinsic="wrapped"] { flex-wrap: nowrap; }
/* the switch beside the count: compact ways, as the Crew gallery's */
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed] { padding: 0 var(--plait-space-sm); }
/* plait-platform-0198b (coordinator 26.10.: "Das Bild füllt die Breite"): ONE picture fills the viewer's width, as tall as its
   proportion asks and never taller than most of the window (contain), so the rows below it stay in sight */
.block-picture-viewer .picture-viewer-item:only-child .marked-picture { width: 100%; }
.block-picture-viewer .picture-viewer-item:only-child .marked-picture-image { width: 100%; height: auto; max-height: 55vh; object-fit: contain; }
.block-picture-viewer .picture-viewer-item:only-child .picture-viewer-caption:empty { display: none; }
/* plait-platform-0198b: in a frame the drawing stands on the frame's card, no ground of its own (no frame in the frame) */
.stage-frame[data-framed="yes"], [data-framed="yes"] .area { background: transparent; border: 0; }
/* plait-platform-0198b: on the frame's card (which wears the elevated ground) the switch's held way stands on the page's ground */
.block-button:not(:has(> [data-acts])):has(> [data-plait-go-area][aria-pressed]) { border-color: var(--plait-color-border); }
.block-button:not(:has(> [data-acts])) > [data-plait-go-area][aria-pressed="true"] { background: var(--plait-color-bg); box-shadow: inset 0 0 0 var(--plait-material-rim-width) var(--plait-color-border); }
/* plait-platform-0198c: a text in a row beside controls stands in the middle of the row's height (the gallery's count beside its switch) */
.layout .box[data-cut="side_by_side"] > .cell > .piece:has(> .block-text) { display: flex; align-items: center; }
/* plait-platform-0198c: a picture that glides to the side under a finger stays inside its own box */
.area:has([data-plait-swipe]) .marked-picture, #area:has([data-plait-swipe]) .marked-picture { overflow: hidden; border-radius: var(--plait-radius-md); }
/* plait-platform-0198c: the details drawn into the sheet under Mehr (`offers`): below the actions, a hairline between */
.block-button .button-slot:not(:empty) { display: grid; gap: var(--plait-space-sm); margin-top: var(--plait-space-sm); padding-top: var(--plait-space-sm); border-top: 1px solid var(--plait-color-divider); }
.block-button[data-look="tiles"] > .button-slot { grid-column: 1 / -1; }
.block-button[data-look="tiles"]:not(:has(.button-slot:not(:empty))) > .button-slot { display: none; }
/* plait-platform-0198c: the sheet under Mehr rolls in itself when its details are long (the surface never rolls) */
.segments-menu:has(> .entry-menu-labelled) > .segments-options { max-height: 62vh; overflow-y: auto; overscroll-behavior: contain; }

/* owner 2026-10-31 (PLAIT Browser Analysen: "machs geil und plaitig", then "Das muss viel sauberer strukturiert werden"):
   the HEAD of an area (block media-list `look: head`): one card, the picture large, the title large, its press a round button
   in the accent of the suit, never the whole row and never a box with corners. Tokens only. */
.block-media-list[data-look="head"] { gap: var(--plait-space-sm); }
.block-media-list[data-look="head"] .media-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-md);
  padding: var(--plait-space-md); border-radius: var(--plait-radius-xl); border: var(--plait-material-rim-width, 1px) solid var(--plait-material-control-rim, var(--plait-color-border));
  background: var(--plait-material-control, var(--plait-color-surface)); box-shadow: var(--plait-elevation-control, none); }
.block-media-list[data-look="head"] .media-handle { flex: 1 1 12rem; min-width: 0; padding: 0; }
.block-media-list[data-look="head"][data-picture="icon"] .media-icon { width: calc(var(--plait-size-icon) * 2.6); border-radius: var(--plait-radius-lg); }
.block-media-list[data-look="head"][data-picture="icon"] .media-icon svg, .block-media-list[data-look="head"][data-picture="icon"] .media-icon .icon { transform: none; width: calc(var(--plait-size-icon) * 1.3); height: calc(var(--plait-size-icon) * 1.3); }
.block-media-list[data-look="head"] .media-title { font-size: var(--plait-type-title-size); font-weight: var(--plait-type-title-weight); }
.block-media-list[data-look="head"] .media-head-press { flex: none; margin-inline-start: auto; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-lg);
  border: 0; border-radius: 999px; background: var(--plait-color-accent); color: var(--plait-color-on-accent); font: inherit;
  font-weight: var(--plait-type-label-weight); cursor: pointer; box-shadow: 0 0 var(--plait-space-sm) var(--plait-decor-glow, transparent); }
.block-media-list[data-look="head"] .media-head-press:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
@media (hover: hover) { .block-media-list[data-look="head"] .media-head-press:hover { filter: brightness(1.08); } }
.block-media-list[data-look="head"] .media-outcome { padding-inline-start: var(--plait-space-md); }

/* owner 2026-10-31: figures as CHIPS (block key-figure `look: chips`): the value strong, what it counts quiet, side by side and wrapping */
.block-key-figure[data-look="chips"] { display: flex; flex-wrap: wrap; gap: var(--plait-space-xs); }
.block-key-figure[data-look="chips"] .key_figure { align-items: center; gap: var(--plait-space-xs); min-height: var(--plait-control-height); padding: 0 var(--plait-space-md);
  border-radius: 999px; border: 1px solid var(--plait-color-border); background: var(--plait-material-control, transparent); }
.block-key-figure[data-look="chips"] .number { min-width: 0; text-align: start; font-variant-numeric: tabular-nums; }
.block-key-figure[data-look="chips"] .what_for { color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.block-key-figure[data-look="chips"] .key_figure[data-sound="warning"], .block-key-figure[data-look="chips"] .key_figure[data-sound="alarm"] { border-color: var(--plait-color-warn); }
.block-key-figure[data-look="chips"] .key_figure[data-sound="good"] { border-color: var(--plait-color-ok); }

/* owner 2026-10-31: a FOLDED timeline (block timeline `fold_word`): one line, the word and the count, a chevron that turns;
   opened, the points under their group headings, the time in one narrow column */
.block-timeline-fold { border-radius: var(--plait-radius-lg); border: 1px solid var(--plait-color-border); background: var(--plait-material-control, transparent); }
.block-timeline-fold > .timeline-summary { display: flex; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size);
  padding: 0 var(--plait-space-md); cursor: pointer; list-style: none; color: var(--plait-color-text); }
.block-timeline-fold > .timeline-summary::-webkit-details-marker { display: none; }
.block-timeline-fold > .timeline-summary::after { content: ""; margin-inline-start: auto; width: var(--plait-space-sm); height: var(--plait-space-sm); border-right: 2px solid var(--plait-color-text-muted);
  border-bottom: 2px solid var(--plait-color-text-muted); transform: rotate(45deg); transition: transform var(--plait-motion-fast, 150ms) ease; }
.block-timeline-fold[open] > .timeline-summary::after { transform: rotate(225deg); }
.block-timeline-fold .timeline-summary-count { padding: 0 var(--plait-space-xs); border-radius: 999px; text-align: center;
  background: var(--plait-color-surface); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); font-variant-numeric: tabular-nums; }
.block-timeline-fold > .block-timeline { padding: 0 var(--plait-space-md) var(--plait-space-md); }
.block-timeline .group { margin-top: var(--plait-space-sm); color: var(--plait-color-accent-text, var(--plait-color-accent)); font-size: var(--plait-type-caption-size); letter-spacing: .15em; text-transform: uppercase; }
.block-timeline[data-when-as="clock"] .point { flex-wrap: nowrap; }
.block-timeline[data-when-as="clock"] .when { flex: none; font-variant-numeric: tabular-nums; }

/* owner 2026-11-01 ("1: ja" to the website's own icon): a picture over a row's icon, filling its rounded field; while it has no
   address or failed it takes no room, the icon below stays */
.block-media-list[data-picture="icon"] .media-icon { position: relative; overflow: hidden; }
.block-media-list[data-picture="icon"] .media-icon-image { position: absolute; inset: 12%; width: 76%; height: 76%; object-fit: contain; border-radius: var(--plait-radius-sm); }
.block-media-list[data-picture="icon"] .media-icon-image:not([src]), .block-media-list[data-picture="icon"] .media-icon-image[data-image-state="failed"] { display: none; }
.block-media-list[data-picture="icon"] .media-icon:has(.media-icon-image[src]:not([data-image-state="failed"])) > .icon { visibility: hidden; }
/* Service Pixel (owner 2026-11-02: „wenn eine ebene ausgewählt ist, dann soll ein footer erscheinen. da drin sollen dann
   alle befehle und eingaben passieren“): the plane footer the carrier lays into the application's foot
   (./render/viewer-perspective.ts), above the device's system bar (safe area), the same on the phone and the desktop; since
   owner 2026-11-05 21:00 also the row of tools (./render/foot-tools.ts), so the foot never makes the page taller than the window */
.foot:has(> .perspective-foot), .foot:has(> .adjust-foot), .foot:has(> .selection-foot),
.foot:has(> .foot-tools) {
  position: fixed; z-index: 4; margin: 0; max-height: 50dvh; overflow: auto;
  /* owner 2026-11-06 („Der footer soll keine Card sein sondern bis ganz nach links und rechts vom bildschirm ragen.“): edge
     to edge and down to the window's bottom, no rounded card; the device's safe area stays inside it as padding */
  left: 0; right: 0; bottom: 0; border-radius: 0; border-width: 1px 0 0;
  padding-left: calc(var(--plait-space-md) + env(safe-area-inset-left, 0px)); padding-right: calc(var(--plait-space-md) + env(safe-area-inset-right, 0px));
  /* the bottom as .viewer-over keeps it: a WebView often says 0 for the safe area, the PLAIT App hands the bars itself */
  padding-bottom: calc(var(--plait-space-sm) + max(env(safe-area-inset-bottom, 0px), var(--plait-bar-bottom, 0px), var(--plait-inset-bottom, 0px)));
}
/* owner 2026-11-06 („Der schachbretthintergrund geht nicht bis ganz nach unten.“, his phone in the PLAIT App: below the stage
   the page's ground stood under the foot): what holds the viewer's stage carries the same checkerboard, so whatever room is
   left below the stage (under the foot, above the system bar) is the work area, never the page's ground */
.area:has(.block-viewer), .pages > .page:has(.block-viewer) {
  background: repeating-conic-gradient(var(--plait-color-checker-a) 0% 25%, var(--plait-color-checker-b) 0% 50%) 50% / 12px 12px; }
.perspective-foot { display: grid; gap: var(--plait-space-sm); min-width: 0; }
.perspective-foot-choices, .perspective-foot-lines, .perspective-foot-orientation { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.perspective-foot-fields { display: grid; gap: var(--plait-space-sm); min-width: 0; }
.perspective-foot-choice, .perspective-foot-line {
  min-height: var(--ergonomics-target-size); min-width: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: transparent; color: var(--plait-color-text);
  font: inherit; cursor: pointer;
}
/* owner 2026-11-04 (the footer of X, Y, Z: „footer, da soll man sperren können“): the name of the lines held, in its axis tone, beside the lock */
.perspective-foot-axis { display: inline-flex; align-items: center; cursor: default; }
.perspective-foot-axis.perspective-tone-axis-x { border-left: 3px solid var(--plait-color-draw-axis-x); }
.perspective-foot-axis.perspective-tone-axis-y { border-left: 3px solid var(--plait-color-draw-axis-y); }
.perspective-foot-axis.perspective-tone-axis-z { border-left: 3px solid var(--plait-color-draw-axis-z); }
.perspective-foot-choice[aria-checked="true"], .perspective-foot-line[aria-pressed="true"] { border-color: var(--plait-color-accent); background: var(--plait-color-accent-ground, transparent); }
/* owner 2026-11-04 („1: ja“): Sichtbar or Verdeckt in the footer of X, Y, Z and Frei, one holds, each with its line drawn as an icon */
.perspective-foot-edges { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.perspective-foot-edge { display: inline-flex; align-items: center; gap: var(--plait-space-xs); }
.perspective-foot-edge-icon { width: var(--plait-size-icon); height: var(--plait-size-icon); flex: 0 0 auto; }
.perspective-foot-line.perspective-tone-axis-x { border-left: 3px solid var(--plait-color-draw-axis-x); }
.perspective-foot-line.perspective-tone-axis-y { border-left: 3px solid var(--plait-color-draw-axis-y); }
.perspective-foot-line.perspective-tone-axis-z { border-left: 3px solid var(--plait-color-draw-axis-z); }
.perspective-field { display: flex; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.perspective-field-word { color: var(--plait-color-text-muted); white-space: nowrap; }
.perspective-field-input { flex: 1 1 auto; min-width: 0; min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface); color: var(--plait-color-text); font: inherit; }
.perspective-field-input[aria-invalid="true"] { border-color: var(--plait-color-danger); }
/* owner 02.11. ~18:55 („Soll einzeln definiert werden können und einen slidebutton wo man das Verhältnis sperren kann …
   zwischenlinien … halbieren, vierteln“): the grid of a plane, a spacing per direction, the slide switch, the divisions */
.perspective-foot-grid { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs) var(--plait-space-sm); min-width: 0; }
.perspective-foot-grid > .perspective-field { flex: 1 1 9rem; }
.perspective-foot-grid > .perspective-foot-row { flex: 1 1 100%; }
.perspective-foot-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs); min-width: 0; }
.perspective-foot-switch { display: inline-flex; align-items: center; gap: var(--plait-space-xs); min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-xs);
  border: 0; background: transparent; color: var(--plait-color-text); font: inherit; cursor: pointer; }
.perspective-foot-switch-track { position: relative; flex: none; width: 2.5rem; height: 1.4rem; border-radius: 999px; border: 1px solid var(--plait-color-border); background: var(--plait-color-surface); }
.perspective-foot-switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: calc(1.4rem - 6px); height: calc(1.4rem - 6px); border-radius: 50%;
  background: var(--plait-color-text-muted); transition: transform var(--plait-motion-quick) var(--plait-motion-ease); }
.perspective-foot-switch[aria-checked="true"] .perspective-foot-switch-track { border-color: var(--plait-color-accent); background: var(--plait-color-accent-ground, var(--plait-color-surface)); }
.perspective-foot-switch[aria-checked="true"] .perspective-foot-switch-track::after { transform: translateX(1.1rem); background: var(--plait-color-accent); }
.perspective-foot-switch:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* owner 2026-11-04 (the lock of a placed thing, ./render/lock.ts, global): the padlock and its word; locked in the accent */
/* a locked thing a hand tried to move shakes once, its padlock blinks (owner 2026-11-07 „2: ja“, ./render/lock.ts nudge) */
@keyframes lock-nudge { 0%, 100% { transform: translate(0, 0); } 20% { transform: translate(-4px, 0); } 40% { transform: translate(4px, 0); } 60% { transform: translate(-3px, 0); } 80% { transform: translate(2px, 0); } }
@keyframes lock-blink { 0%, 50%, 100% { opacity: 1; } 25%, 75% { opacity: .25; } }
[data-lock-nudge] { animation: lock-nudge .45s ease-in-out; transform-box: fill-box; }
.lock-switch[data-lock-nudge] { animation: lock-blink .45s linear; outline: 2px solid var(--plait-color-accent); }
.lock-switch { display: inline-flex; align-items: center; gap: var(--plait-space-xs); min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm);
  border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: transparent; color: var(--plait-color-text); font: inherit; cursor: pointer; }
.lock-switch[aria-checked="true"] { border-color: var(--plait-color-accent); background: var(--plait-color-accent-ground, transparent); color: var(--plait-color-accent); }
.lock-switch:focus-visible { outline: 2px solid var(--plait-color-focus); outline-offset: 2px; }
/* owner 02.11. „5: ja“: deleting an own plane, locked while another plane refers to it */
.perspective-foot-delete-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--plait-space-xs) var(--plait-space-sm); min-width: 0; }
.perspective-foot-delete { color: var(--plait-color-danger-text, var(--plait-color-danger)); }
.perspective-foot-delete[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.perspective-foot-note { margin: 0; color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); min-width: 0; overflow-wrap: anywhere; }
/* owner 02.11. ~18:55 („rechts klick auf linie soll rechtsklickmenü der linie öffnen … beim touchscreen ist es langes
   drauftippen statt rechts klick.“): THE context menu of any stage or block (./render/context-menu.ts), over the page,
   inside the window */
.context-menu { position: fixed; z-index: 30; display: grid; gap: 2px; min-width: 12rem; max-width: calc(100vw - 16px); max-height: calc(100dvh - 16px); overflow: auto;
  padding: var(--plait-space-xs); border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); background: var(--plait-color-surface-elevated);
  color: var(--plait-color-text); }
.context-menu-title { margin: 0; padding: var(--plait-space-xs) var(--plait-space-sm); color: var(--plait-color-text-muted); font-size: var(--plait-type-caption-size); }
.context-menu-entry { display: flex; align-items: center; gap: var(--plait-space-sm); min-height: var(--ergonomics-target-size); padding: 0 var(--plait-space-sm); text-align: start;
  border: 1px solid transparent; border-radius: var(--plait-radius-sm); background: transparent; color: inherit; font: inherit; cursor: pointer; }
.context-menu-entry::before { content: ""; flex: none; width: 1rem; height: 1rem; border-radius: var(--plait-radius-sm); border: 1px solid transparent; }
.context-menu-entry[role="menuitemcheckbox"]::before { border-color: var(--plait-color-border); }
.context-menu-entry[aria-checked="true"]::before { border-color: var(--plait-color-accent); background: var(--plait-color-accent); }
.context-menu-entry:hover, .context-menu-entry:focus-visible { border-color: var(--plait-color-accent); outline: none; }
.context-menu-entry[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }

/* Owner 2026-11-04 (PLAIT Pixel, ./render/viewer-adjust.ts and ./render/adjust-dial.ts: „In der Pixelmatrix sollen im footer
   standardfunktionen sein … mit so einem plus/minus/regler wie in samsung“): the view tools in the application's foot, over
   the stage as the perspective's footer (its rule above places both), one row that scrolls sideways on a phone; a tool tapped opens its dial above the
   row: the value circle with its gold segment, the ruler of fine marks under a fixed gold middle mark, its ends fading */
.adjust-foot { display: grid; gap: var(--plait-space-sm); min-width: 0; }
.adjust-tools { display: flex; gap: var(--plait-space-xs); overflow-x: auto; scrollbar-width: none; min-width: 0; }
.adjust-tools::-webkit-scrollbar { display: none; }
.adjust-tool { position: relative; flex: 1 0 auto; min-width: 4.25rem; min-height: var(--ergonomics-target-size); display: grid; justify-items: center; align-content: center; gap: 2px;
  padding: var(--plait-space-xs); border: 1px solid transparent; border-radius: var(--plait-radius-md); background: transparent; color: var(--plait-color-text-muted); cursor: pointer; font: inherit; }
.adjust-tool .icon { width: 1.4rem; height: 1.4rem; display: block; }
.adjust-tool .icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
.adjust-tool-word { font-size: var(--plait-type-caption-size); white-space: nowrap; }
.adjust-tool[aria-pressed="true"] { color: var(--plait-color-accent); border-color: var(--plait-color-accent); }
.adjust-tool:hover, .adjust-tool:focus-visible { color: var(--plait-color-text); outline: none; border-color: var(--plait-color-border); }
/* a tool whose value is not 0: a small gold point at its top right, nothing louder */
.adjust-tool[data-adjust-changed="yes"]::after { content: ""; position: absolute; top: 4px; right: 6px; width: 5px; height: 5px; border-radius: 50%; background: var(--plait-color-accent); }
/* owner 2026-11-05 21:00 („1: ja wenn es nicht viel Aufwand ist“, ./render/foot-tools.ts): the tools of the row under the header
   as ONE row in the application's foot, first in it, icons only (the word is the label); a phone too narrow scrolls the row
   sideways, never the page; on in the accent, as the view tools above */
.foot-tools { display: flex; gap: var(--plait-space-xs); overflow-x: auto; scrollbar-width: none; min-width: 0; max-width: 100%; }
.foot-tools::-webkit-scrollbar { display: none; }
.foot-tools__tool { flex: 1 0 auto; min-width: var(--ergonomics-target-size); min-height: var(--ergonomics-target-size); display: inline-flex; align-items: center; justify-content: center;
  padding: var(--plait-space-xs); border: 1px solid transparent; border-radius: var(--plait-radius-md); background: transparent; color: var(--plait-color-text-muted); cursor: pointer; font: inherit; }
.foot-tools__tool .icon { width: 1.4rem; height: 1.4rem; display: block; }
.foot-tools__tool .icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
.foot-tools__tool[aria-pressed="true"] { color: var(--plait-color-accent); border-color: var(--plait-color-accent); }
.foot-tools__tool:hover, .foot-tools__tool:focus-visible { color: var(--plait-color-text); outline: none; border-color: var(--plait-color-border); }
.adjust-dial { display: grid; justify-items: center; gap: var(--plait-space-xs); }
.adjust-dial-circle { width: 4rem; height: 4rem; padding: 0; position: relative; border: 0; background: transparent; color: var(--plait-color-text); cursor: pointer; font: inherit; }
.adjust-dial-circle svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.adjust-dial-track { fill: none; stroke: var(--plait-color-border); stroke-width: 2.5; }
.adjust-dial-arc { fill: none; stroke: var(--plait-color-accent); stroke-width: 2.5; stroke-linecap: butt; }
.adjust-dial-number { position: relative; font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.adjust-dial-row { display: flex; align-items: center; gap: var(--plait-space-xs); width: 100%; max-width: 32rem; }
.adjust-dial-step { flex: none; width: var(--ergonomics-target-size); height: var(--ergonomics-target-size); display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--plait-color-text); cursor: pointer; }
.adjust-dial-step .icon { width: 1.25rem; height: 1.25rem; display: block; }
.adjust-dial-step .icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
.adjust-dial-step:hover, .adjust-dial-step:focus-visible { color: var(--plait-color-accent); outline: none; }
.adjust-ruler { position: relative; flex: 1 1 auto; height: 2.25rem; overflow: hidden; touch-action: none; cursor: ew-resize; user-select: none; -webkit-user-select: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 22%, black 78%, transparent); mask-image: linear-gradient(90deg, transparent, black 22%, black 78%, transparent); }
.adjust-ruler:focus-visible { outline: none; }
.adjust-ruler-strip { position: absolute; top: 0; bottom: 0; left: 50%; width: 0; will-change: transform; }
.adjust-ruler-tick { position: absolute; top: 35%; bottom: 35%; width: 1px; margin-left: -0.5px; background: var(--plait-color-text-muted); opacity: 0.55; }
.adjust-ruler-long { top: 22%; bottom: 22%; opacity: 1; background: var(--plait-color-text); }
.adjust-ruler-mark { position: absolute; left: 50%; top: 10%; bottom: 10%; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--plait-color-accent); }

/* Owner 2026-11-04 (Grid Wave, ./render/grid-wave.ts: „Während die pixelmatrix etwas kalkuliert oder wenn man sie öffnet soll
   mit dem bild einmal Grid Wave CSS effekt ausgeführt werden.“), 05.11.: „er sollte nur überdem bild laufen und viel viel besser
   sein und nicht ständig laufen“. Laid ONLY over the picture's rectangle (the custom properties set by grid-wave.ts), fine lines
   of the grid in the suite's accent, seen inside a soft diagonal band that runs once; the picture stays visible under it.
   Only transform and opacity move: the band runs, the lines run against it (so they stand on the picture), the overlay fades. */
.grid-wave { position: absolute; left: 0; top: 0; z-index: 1; width: var(--grid-wave-w); height: var(--grid-wave-h); pointer-events: none;
  overflow: hidden; contain: strict; transform: translate(var(--grid-wave-x), var(--grid-wave-y));
  animation: grid-wave-fade calc(var(--plait-motion-rise) * 1.6) var(--plait-motion-ease) both; }
.grid-wave[hidden] { display: none; }
.grid-wave-band { position: absolute; left: 0; top: 0; width: var(--grid-wave-band); height: 100%; will-change: transform;
  background: linear-gradient(110deg, transparent 25%, color-mix(in srgb, var(--plait-color-accent) 9%, transparent) 50%, transparent 75%);
  -webkit-mask-image: linear-gradient(110deg, transparent 25%, black 50%, transparent 75%); mask-image: linear-gradient(110deg, transparent 25%, black 50%, transparent 75%);
  animation: grid-wave-band calc(var(--plait-motion-rise) * 1.6) cubic-bezier(0.4, 0, 0.2, 1) both; }
.grid-wave-lines { position: absolute; left: 0; top: 0; width: var(--grid-wave-w); height: 100%; will-change: transform;
  background-image: linear-gradient(to right, color-mix(in srgb, var(--plait-color-accent) 70%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--plait-color-accent) 70%, transparent) 1px, transparent 1px);
  background-size: var(--grid-wave-side) var(--grid-wave-side);
  animation: grid-wave-lines calc(var(--plait-motion-rise) * 1.6) cubic-bezier(0.4, 0, 0.2, 1) both; }
@keyframes grid-wave-fade { 0% { opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } }
@keyframes grid-wave-band { from { transform: translateX(calc(-1 * var(--grid-wave-band))); } to { transform: translateX(var(--grid-wave-w)); } }
@keyframes grid-wave-lines { from { transform: translateX(var(--grid-wave-band)); } to { transform: translateX(calc(-1 * var(--grid-wave-w))); } }
/* less motion: no band runs and nothing fades (the one rule for less motion below stills every animation); the lines alone
   stand faint over the picture for a moment and go (the sign stays, the motion goes) */
.grid-wave[data-grid-wave-calm="yes"] .grid-wave-band { width: 100%; animation: none; background: none; -webkit-mask-image: none; mask-image: none; }
.grid-wave[data-grid-wave-calm="yes"] .grid-wave-lines { animation: none; opacity: 0.45; }

/* Owner 2026-11-04 (PLAIT Pixel, ./render/viewer-selection.ts: „Lasso, Polylinie und Freihand“; „ausgeschlossene Flächen
   leicht abgedunkelt“) and 2026-11-05 („visuell ca. so wie auf dem video … von samsung“, „farblich transparent mit effekt
   ausgefüllt … bei allen, nicht nur beim lasso“, groups and Ein-/Ausschließen „visuell … erkenntlich“, ./render/selection-paint.ts):
   every part takes its colour from `--selection-tint`: an area alone the accent when included, the danger tone when excluded;
   a group one of five tints of the suit (never violet), the same for all its areas. Included: filled translucent, a crisp line
   with a soft halo. Excluded: the ground darkened, hatched in the tint, the line dashed. The hand drawing: a wide blurred glow
   with a band of the tint under a bright core. A new area: one sweep of light. Chosen: the line in the text tone, dashed, the fill stronger. The footer
   one row of tools, a second for the chosen areas, the same on the phone and the desktop */
.block-viewer .selection-layer { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 1; }
.selection-layer { --selection-tint: var(--plait-color-accent); }
.selection-layer [data-selection-mode="exclude"] { --selection-tint: var(--plait-color-danger); }
.selection-layer [data-selection-tint="1"] { --selection-tint: var(--plait-color-info); }
.selection-layer [data-selection-tint="2"] { --selection-tint: var(--plait-color-ok); }
.selection-layer [data-selection-tint="3"] { --selection-tint: var(--plait-color-icon-data); }
.selection-layer [data-selection-tint="4"] { --selection-tint: var(--plait-color-warning-orange); }
.selection-layer [data-selection-tint="5"] { --selection-tint: var(--plait-color-icon-code); }
.selection-layer .selection-shade { fill: var(--plait-color-bg); fill-opacity: 0.45; stroke: none; }
.selection-layer .selection-fill { stroke: none; fill: none; transition: fill-opacity var(--plait-motion-quick) var(--plait-motion-ease); }
.selection-layer .selection-fill[data-selection-mode="include"] { fill: var(--selection-tint); fill-opacity: 0.24; }
.selection-layer .selection-fill[data-selection-mode="include"][data-selection-chosen="yes"] { fill-opacity: 0.38; }
.selection-layer .selection-fill[data-selection-fresh="yes"] { fill-opacity: 0.34; }
.selection-layer .selection-hatch-line { fill: var(--selection-tint); }
.selection-layer .selection-hatch-fill { stroke: none; opacity: 0.5; }
.selection-layer .selection-hatch-fill[data-selection-chosen="yes"] { opacity: 0.75; }
.selection-layer .selection-sweep { pointer-events: none; }
.selection-layer .selection-sweep-stop { stop-color: var(--plait-color-text); stop-opacity: 0; }
.selection-layer .selection-sweep-stop[data-at="middle"] { stop-opacity: 0.7; }
.selection-layer .selection-outline-glow { fill: none; stroke: var(--selection-tint); stroke-width: 7px; stroke-opacity: 0.32; stroke-linejoin: round; filter: blur(2.5px); }
.selection-layer .selection-outline-glow[data-selection-fresh="yes"] { stroke-width: 11px; stroke-opacity: 0.6; }
.selection-layer .selection-outline { fill: none; stroke: var(--selection-tint); stroke-width: 2px; stroke-linejoin: round; }
.selection-layer .selection-outline[data-selection-mode="exclude"] { stroke-dasharray: 7 5; }
.selection-layer .selection-outline[data-selection-chosen="yes"] { stroke-width: 2.5px; stroke-dasharray: 6 4; stroke: var(--plait-color-text); }
.selection-layer .selection-mark circle { fill: var(--selection-tint); stroke: var(--plait-color-bg); stroke-width: 2px; }
.selection-layer .selection-mark text { fill: var(--plait-color-on-accent); font-size: var(--plait-type-caption-size); font-weight: 700; text-anchor: middle; dominant-baseline: central; }
.selection-layer .selection-live-glow { fill: none; stroke: var(--selection-tint); stroke-width: 16px; stroke-opacity: 0.55; stroke-linecap: round; stroke-linejoin: round; filter: blur(5px); }
.selection-layer .selection-live-edge { fill: none; stroke: var(--selection-tint); stroke-width: 6px; stroke-opacity: 0.9; stroke-linecap: round; stroke-linejoin: round; }
.selection-layer .selection-live { fill: none; stroke: var(--plait-color-text); stroke-width: 2.5px; stroke-linecap: round; stroke-linejoin: round; }
.selection-layer .selection-live[data-selection-pending="yes"] { stroke: color-mix(in srgb, var(--plait-color-text) 70%, var(--selection-tint)); }
.selection-layer .selection-corner { fill: var(--plait-color-text); stroke: var(--selection-tint); stroke-width: 2px; }
.selection-layer .selection-corner[data-selection-first="yes"] { fill: var(--selection-tint); stroke: var(--plait-color-text); }
@media (prefers-reduced-motion: reduce) { .selection-layer .selection-fill { transition: none; } }
.selection-foot { display: grid; gap: var(--plait-space-xs); min-width: 0; }
.selection-tools { display: flex; gap: var(--plait-space-xs); overflow-x: auto; scrollbar-width: none; min-width: 0; align-items: center; }
.selection-tools::-webkit-scrollbar { display: none; }
.selection-tool { flex: 1 0 auto; min-width: 4.25rem; min-height: var(--ergonomics-target-size); display: grid; justify-items: center; align-content: center; gap: 2px;
  padding: var(--plait-space-xs); border: 1px solid transparent; border-radius: var(--plait-radius-md); background: transparent; color: var(--plait-color-text-muted); cursor: pointer; font: inherit; }
.selection-tool .icon { width: 1.4rem; height: 1.4rem; display: block; }
.selection-tool .icon svg { width: 100%; height: 100%; display: block; fill: currentColor; }
.selection-tool-word { font-size: var(--plait-type-caption-size); white-space: nowrap; }
.selection-tool[aria-checked="true"] { color: var(--plait-color-accent); border-color: var(--plait-color-accent); }
.selection-tool:hover, .selection-tool:focus-visible { color: var(--plait-color-text); outline: none; border-color: var(--plait-color-border); }
.selection-mode[data-selection-mode="exclude"] { color: var(--plait-color-text); }
.selection-chosen .lock-switch { flex: 1 0 auto; }

/* owner 2026-11-07 (PLAIT Browser, the tab Fernseher: "Die Fernbedienung ist extrem scheiße", then "eine richtige
   Fernbedienung"): the button block in the look `remote` is ONE remote control, never a column of loose buttons. Each key
   stands at the place its action names (`data-pad`, button REMOTE_PADS): back and home on top, the pad with OK in its
   middle, volume down, mute and volume up, play and pause. Every key is 1.4 times the person's target size, the block is
   one card of the suit, and the outcome of a press stands ONCE under it, an accepted one not at all. A key whose place
   the layout does not name (menu, previous, next) flows after the pad. */
.block-button[data-look="remote"] {
  --remote-key: calc(var(--ergonomics-target-size) * 1.4);
  display: grid; grid-template-columns: repeat(3, var(--remote-key)); justify-content: center; align-items: center;
  grid-template-areas: "back . home" ". up ." "left ok right" ". down ." "vdown mute vup" "play . pause";
  gap: var(--plait-space-sm) var(--plait-space-md); width: fit-content; margin: var(--plait-space-sm) auto;
  padding: var(--plait-space-lg) var(--plait-space-xl); border-radius: calc(var(--remote-key) * 0.6);
  background: var(--plait-material-card, var(--plait-color-surface)); border: 1px solid var(--plait-material-card-rim, var(--plait-color-border));
}
.block-button[data-look="remote"] > button[data-pad] {
  width: var(--remote-key); height: var(--remote-key); padding: 0; margin: 0 auto; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--plait-color-surface-elevated); border: 1px solid var(--plait-color-border); color: var(--plait-color-text);
  font-size: var(--plait-type-label-size); font-weight: 600; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: transform var(--plait-motion-quick) var(--plait-motion-ease);
}
.block-button[data-look="remote"] > button[data-pad] .icon { width: calc(var(--plait-size-icon) * 1.3); height: calc(var(--plait-size-icon) * 1.3); }
.block-button[data-look="remote"] > button[data-pad]:active { transform: scale(0.94); }
.block-button[data-look="remote"] > button[data-pad="ok"] {
  width: calc(var(--remote-key) * 1.15); height: calc(var(--remote-key) * 1.15);
  background: var(--plait-color-accent); border-color: var(--plait-color-accent); color: var(--plait-color-on-accent);
}
/* the pad stands a breath apart from the keys around it */
.block-button[data-look="remote"] > button[data-pad="up"] { margin-top: var(--plait-space-md); }
.block-button[data-look="remote"] > button[data-pad="down"] { margin-bottom: var(--plait-space-md); }
.block-button[data-look="remote"] > button[data-pad="play"], .block-button[data-look="remote"] > button[data-pad="pause"] { margin-top: var(--plait-space-sm); }
.block-button[data-look="remote"] > [data-pad="up"] { grid-area: up; }
.block-button[data-look="remote"] > [data-pad="left"] { grid-area: left; }
.block-button[data-look="remote"] > [data-pad="ok"] { grid-area: ok; }
.block-button[data-look="remote"] > [data-pad="right"] { grid-area: right; }
.block-button[data-look="remote"] > [data-pad="down"] { grid-area: down; }
.block-button[data-look="remote"] > [data-pad="back"] { grid-area: back; }
.block-button[data-look="remote"] > [data-pad="home"] { grid-area: home; }
.block-button[data-look="remote"] > [data-pad="volume-down"] { grid-area: vdown; }
.block-button[data-look="remote"] > [data-pad="mute"] { grid-area: mute; }
.block-button[data-look="remote"] > [data-pad="volume-up"] { grid-area: vup; }
.block-button[data-look="remote"] > [data-pad="play"] { grid-area: play; }
.block-button[data-look="remote"] > [data-pad="pause"] { grid-area: pause; }
.block-button[data-look="remote"] > .delivery-result { grid-column: 1 / -1; margin: 0; text-align: center; }
.block-button[data-look="remote"] > .delivery-result.accepted { display: none; }

/* PLAIT Connect (owner 2026-11-07, qr-camera.ts): the browser's camera in one layer over the page while a QR is read */
.qr-camera { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--plait-space-md); padding: var(--plait-space-md); background: var(--plait-color-bg); }
.qr-camera-picture { width: 100%; max-width: 32rem; aspect-ratio: 1; object-fit: cover; border: 1px solid var(--plait-color-border); border-radius: var(--plait-radius-md); }
.qr-camera-hint { margin: 0; color: var(--plait-color-text-muted); text-align: center; }
