/* Rama okna (stagewright): obszary, menu, obszar roboczy i treść strony. Kolory i kształt (zaokrąglenia, cień) ze
   zmiennych motywu themewright `--thw-*` (D34) – strona ładuje motyw (domyślny: `themes/default.css` themewright,
   z parą dzień/noc według `color-scheme`); rama nie ma własnych wartości kolorów ani mechanizmu motywu. Własne tokeny
   `--stw-*` to układ, odstępy i ruch, z wartościami domyślnymi; deklaracje aplikacji bez warstwy wygrywają z warstwą
   `stagewright`. Motywy aplikacji stylują stałe klasy stw-… (lista w README). */
@layer stagewright {
  :root {
    --stw-motion-duration: .28s;
    --stw-bar-height: 3rem;
    --stw-gap: 1rem;
    --stw-panel-padding: 1rem .75rem;
    --stw-item-padding-block: .45rem;
    --stw-item-gap: .25rem;
    --stw-side-icons-width: 2.7rem;
    --stw-toasts-bottom: .5rem;
  }
  .stw-frame {
    display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto 1fr; min-height: 100vh;
    grid-template-areas: "top top top" "side work right";
    background: var(--thw-page); color: var(--thw-ink);
  }
  /* Układy (D25, `data-stw-arrangement`, wybiera rama): „sidebar” – pasek nad panelem, „sidebar-full” – panel na całą
     wysokość, „drawer” – nawigacja w szufladzie (zob. niżej, `data-stw-panel="drawer"`). */
  .stw-frame[data-stw-arrangement="sidebar-full"] { grid-template-areas: "side top top" "side work right"; }
  .stw-top { grid-area: top; display: flex; flex-wrap: nowrap; align-items: center; gap: var(--stw-gap); min-height: var(--stw-bar-height); padding: 0 var(--stw-gap);
    border-bottom: 1px solid var(--thw-line); background: var(--thw-surface); }
  /* Pasek górny i panele boczne zostają na miejscu, przewija się tylko treść (jak w VS Code): pasek przyklejony do góry
     okna, panele pod nim na resztę wysokości okna, a dłuższe od niej przewijają się same. Wysokość paska i pionowe
     wcięcia paneli (z motywu aplikacji) mierzy rama: --stw-top-height, --stw-side-chrome, --stw-right-chrome. */
  .stw-top { position: sticky; top: 0; z-index: 10; }
  /* `z-index` 5: przyklejony panel ma własną warstwę – jego wysuwane listy są nad zwykłą treścią strony (D6), a pod
     paskiem górnym (10). */
  :is(.stw-side, .stw-right) { position: sticky; top: var(--stw-top-height, 0px); align-self: start; z-index: 5; }
  :is(.stw-side, .stw-right)[data-stw-scrolls] { overflow-y: auto; }
  .stw-side { height: calc(100vh - var(--stw-top-height, 0px) - var(--stw-side-chrome, 0px)); }
  .stw-right { height: calc(100vh - var(--stw-top-height, 0px) - var(--stw-right-chrome, 0px)); }
  .stw-frame[data-stw-arrangement="sidebar-full"] .stw-side { top: 0; height: calc(100vh - var(--stw-side-chrome, 0px)); }
  .stw-side { grid-area: side; display: flex; flex-direction: column; gap: var(--stw-gap);
    width: var(--stw-side-width, 15rem); padding: var(--stw-panel-padding); background: var(--thw-menu); border-right: 1px solid var(--thw-line); }
  /* Jawnie: zdjęcie `data-stw-<obszar>-moving` przerywa trwający ruch (sam czas 0s by go nie przerwał). */
  :is(.stw-side, .stw-right) { transition: none; }
  /* Ruch tylko przy zmianie stanu: rama ustawia `data-stw-side-moving` (`data-stw-right-moving`) w tej samej zmianie co
     `data-stw-side` (`data-stw-right`) i zdejmuje go po końcu przejść, więc szerokość z uchwytu i z okna (także przez
     próg wąskiego okna) zmienia się bez ruchu, a zmiana okna w trakcie ruchu go nie przerywa. W trakcie ruchu treść nie
     wychodzi poza panel na obszar pracy; poza krawędź od strony obszaru pracy wystaje tylko uchwyt (4px). Poza ruchem
     panel nie przycina: wysuwane listy, dymki, cienie i `position: fixed` elementów aplikacji wychodzą poza panel. */
  .stw-frame[data-stw-side-moving] .stw-side { clip-path: inset(0 -4px 0 0); }
  .stw-frame[data-stw-right-moving] .stw-right { clip-path: inset(0 0 0 -4px); }
  .stw-frame[data-stw-side-moving] .stw-side, .stw-frame[data-stw-right-moving] .stw-right {
    transition: width var(--stw-motion-duration) ease, padding var(--stw-motion-duration) ease, border-width var(--stw-motion-duration) ease,
      opacity var(--stw-motion-duration) ease, translate var(--stw-motion-duration) ease, visibility var(--stw-motion-duration) ease; }
  /* Panel boczny: same ikony, ukryty; uchwyt szerokości tylko rozwinięty. Części elementów (także pozycji menu) poza
     stanem rozwiniętym: `stw-label` schowana wzrokowo (zostaje dla czytników ekranu i w podpowiedzi), `stw-expanded-only`
     znika. Ukryty panel ma wygląd samych ikon, więc chowanie z samych ikon nie pokazuje podpisów. */
  /* Same ikony: stała, wąska szerokość (#9; z `max-content` pozycje bez ikony z pełnym podpisem robiły panel szerszy
     niż rozwinięty). */
  .stw-frame[data-stw-side="icons"] .stw-side { width: var(--stw-side-icons-width); padding-inline: .4rem; }
  /* Umowa z `!important`, jak zero ukrytego panelu: aplikacja styluje swoje elementy regułami bez warstwy (np.
     `display: flex`), które inaczej wygrałyby z warstwą ramy – nie musi pilnować, czego nie stylować. */
  .stw-frame:not([data-stw-side="expanded"]) .stw-side :is(.stw-label, .stw-menu-label) {
    position: absolute !important; width: 1px !important; height: 1px !important; overflow: hidden !important;
    clip-path: inset(50%) !important; white-space: nowrap !important; }
  .stw-frame:not([data-stw-side="expanded"]) .stw-side .stw-expanded-only { display: none !important; }
  /* Pozycja menu bez ikony: podpis (`stw-menu-label`, schowany wyżej jak `stw-label`) zastępuje pierwsza litera
     (`stw-menu-initial`, #9) – z CSS, więc nie wchodzi do tekstu pozycji, a pusty tekst zastępczy trzyma ją poza nazwą
     dostępną (przeglądarka bez tej składni bierze pierwszą deklarację); grupy bez wcięcia – w wąskim panelu nie ma na
     nie miejsca. */
  .stw-menu-initial { display: none; }
  .stw-frame:not([data-stw-side="expanded"]) .stw-side .stw-menu-initial { display: inline; }
  .stw-menu-initial::before { content: attr(data-stw-initial); content: attr(data-stw-initial) / ""; }
  .stw-frame:not([data-stw-side="expanded"]) .stw-side .stw-menu-group-items { margin-left: 0; }
  /* Ukryty: kolumna do zera, wysunięcie w lewo i zanik; `visibility` zmienia się na końcu ruchu, a `inert` (rama) od razu.
     Zero szerokości, wcięć i ramki z `!important`: wygrywa z regułą motywu bez warstwy (np. `.stw-side { padding }`),
     która inaczej zostawiłaby pustą kolumnę; przejścia CSS i tak mają pierwszeństwo, więc ruch zostaje. */
  .stw-frame[data-stw-side="hidden"] .stw-side { width: 0 !important; padding-inline: 0 !important; border-right-width: 0 !important;
    opacity: 0; translate: -100% 0; visibility: hidden; }
  /* Prawy panel (część `aside`): kolumna jak boczny, rozwinięty albo ukryty – ukryty jak boczny, ale bez wysunięcia. */
  .stw-right { grid-area: right; display: flex; flex-direction: column; gap: var(--stw-gap); width: var(--stw-right-width, 15rem); padding: var(--stw-panel-padding);
    border-left: 1px solid var(--thw-line); }
  .stw-frame[data-stw-right="hidden"] .stw-right { width: 0 !important; padding-inline: 0 !important; border-left-width: 0 !important;
    opacity: 0; visibility: hidden; }
  /* Prawy panel stoi przy prawej krawędzi okna: panel wysuwany w prawo i treść zwężanego albo ukrytego panelu
     (szersza od niego) wychodziłyby poza okno i dawały poziome przewijanie strony. Dlatego bez wysunięcia, a treść
     w ruchu i w stanie ukrytym przycięta do panelu przez `contain: paint` – przycięta treść nie poszerza strony,
     a panel zostaje kontenerem przewijania (pozycja przewinięcia długiego panelu nie skacze). Poza tym panel nie
     przycina (D6). Boczny tego nie potrzebuje: jego ruch i treść wychodzą w lewo albo na obszar pracy. */
  .stw-frame[data-stw-right-moving] .stw-right, .stw-frame[data-stw-right="hidden"] .stw-right { contain: paint; }
  /* Uchwyt w siatce ramy, przy krawędzi panelu od strony obszaru pracy (nie w panelu: przewijany panel przesuwałby go
     z treścią); tylko przy panelu rozwiniętym. */
  :is(.stw-side-resizer, .stw-right-resizer) { align-self: start; position: sticky; top: var(--stw-top-height, 0px); z-index: 6;
    width: 8px; height: calc(100vh - var(--stw-top-height, 0px)); cursor: col-resize; touch-action: none; }
  .stw-side-resizer { grid-area: side; justify-self: end; margin-right: -4px; }
  .stw-right-resizer { grid-area: right; justify-self: start; margin-left: -4px; }
  .stw-frame[data-stw-arrangement="sidebar-full"] .stw-side-resizer { top: 0; height: 100vh; }
  .stw-side[hidden] ~ .stw-side-resizer, .stw-frame:has(> .stw-side[hidden]) > .stw-side-resizer,
  .stw-frame:has(> .stw-right[hidden]) > .stw-right-resizer { display: none; }
  :is(.stw-side-resizer, .stw-right-resizer):is(:hover, :focus-visible) { background: color-mix(in srgb, var(--thw-tone-accent) 35%, transparent); outline: none; }
  .stw-frame:not([data-stw-side="expanded"]) .stw-side-resizer, .stw-frame:not([data-stw-right="expanded"]) .stw-right-resizer { display: none; }
  .stw-frame[data-stw-resizing] { cursor: col-resize; user-select: none; }
  @media (prefers-reduced-motion: reduce) {
    .stw-frame[data-stw-side-moving] .stw-side, .stw-frame[data-stw-right-moving] .stw-right { transition: none; }
  }
  /* Przełączniki paneli (rama stawia je przy częściach `navigation` i `aside`): znak bieżącego stanu. */
  :is(.stw-side-toggle, .stw-right-toggle) { padding: .3rem .5rem; border: 0; border-radius: var(--thw-radius-small); background: none; color: var(--thw-ink);
    font: inherit; font-size: 1.15em; line-height: 1; cursor: pointer; }
  :is(.stw-side-toggle, .stw-right-toggle):hover { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); }
  .stw-work { grid-area: work; min-width: 0; }
  :is(.stw-top, .stw-side, .stw-right, .stw-workspace, .stw-part)[hidden] { display: none; }
  /* Części (D25, `data-stw-part`): w pasku elementy w rzędzie, w panelach w kolumnie, z odstępem miejsca. */
  .stw-part { display: flex; flex-wrap: wrap; align-items: center; gap: inherit; min-width: 0; }
  :is(.stw-side, .stw-right) .stw-part { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .stw-overflow:not(:popover-open) { display: none; }
  :is(.stw-search-toggle, .stw-overflow-toggle) { padding: .3rem .5rem; border: 0; border-radius: var(--thw-radius-small); background: none;
    color: var(--thw-ink); font: inherit; font-size: 1.15em; line-height: 1; cursor: pointer; }
  :is(.stw-search-toggle, .stw-overflow-toggle):hover { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); }
  .stw-spacer { flex: 1; }
  /* Dół panelu (elementy za ostatnim odstępem w `side` i `right`): gdy panel się przewija, przyklejony do jego dołu
     (z tłem panelu), a gdy nie – stoi na dole dzięki odstępowi; najwyżej połowa panelu – wyższy przewija się sam
     (`data-stw-scrolls`, jak panel) i nie zjada menu. Przyklejony tylko w przewijanym panelu: inaczej trzymałby się
     dołu okna (np. w wąskim oknie). */
  .stw-region-end { display: flex; flex-direction: column; gap: inherit; flex-shrink: 0; max-height: 50%; background: inherit; }
  [data-stw-scrolls] > .stw-region-end { position: sticky; bottom: calc(-1 * var(--stw-end-gap, 0px)); z-index: 1;
    padding-bottom: var(--stw-end-gap, 0px); margin-bottom: calc(-1 * var(--stw-end-gap, 0px)); }
  .stw-region-end > * { flex-shrink: 0; }  /* wysoki dół przewija się, a nie ściska swoich elementów */
  .stw-region-end[data-stw-scrolls] { overflow-y: auto; }
  /* Dół panelu oddzielony od nawigacji nad nim odstępem, a gdy pod nim jest jeszcze przewijana treść – cieniem nad nim
     (#22, `data-stw-more` panelu); linię aplikacja daje separatorem, jeśli ją chce. */
  .stw-region-end { padding-top: .5rem; }
  :is(.stw-side, .stw-right)[data-stw-more~="after"] > .stw-region-end { box-shadow: 0 -.5rem .5rem -.5rem light-dark(rgb(0 0 0 / .3), rgb(0 0 0 / .7)); }
  .stw-content { padding: 1.5rem 2rem; max-width: 70rem; }
  /* Karty otwartych stron (`start({ tabs: true })`): pasek nad treścią, przyklejony pod paskiem górnym, przewijany
     w poziomie; karta bieżąca z kreską akcentu, × albo kropka (niezapisane zmiany) zamyka. */
  .stw-page-tabs { position: sticky; top: var(--stw-top-height, 0px); z-index: 4; display: flex; overflow-x: auto; scrollbar-width: thin;
    background: var(--thw-menu); border-bottom: 1px solid var(--thw-line); }
  .stw-page-tabs[hidden] { display: none; }
  .stw-page-tab { display: flex; flex: 0 0 auto; align-items: center; gap: .15rem; max-width: 16rem; padding-inline: .7rem .3rem;
    border-right: 1px solid var(--thw-line); color: var(--thw-muted); }
  .stw-page-tab.stw-current { background: var(--thw-page); color: var(--thw-ink); box-shadow: inset 0 2px 0 var(--thw-tone-accent); }
  .stw-page-tab-label { display: flex; align-items: center; gap: .4rem; min-width: 0; padding-block: .5rem; cursor: pointer; white-space: nowrap; }
  .stw-page-tab-label > span { overflow: hidden; text-overflow: ellipsis; }
  .stw-page-tab-label:focus-visible { outline: 2px solid var(--thw-tone-accent); outline-offset: -2px; border-radius: var(--thw-radius-small); }
  .stw-page-tab-close { flex: 0 0 auto; width: 1.4rem; height: 1.4rem; padding: 0; border: 0; border-radius: var(--thw-radius-small);
    background: none; color: inherit; font: inherit; line-height: 1; cursor: pointer; }
  .stw-page-tab-close:hover { background: color-mix(in srgb, var(--thw-ink) 10%, transparent); color: var(--thw-ink); }

  /* Menu: pionowe w obszarach bocznych, poziome w pasku górnym (tam grupa to wysuwana lista). */
  .stw-menu { display: flex; flex-direction: column; gap: var(--stw-item-gap); }
  /* Wyszukiwanie w menu (`menu(name, { search: true })`): pole nad pozycjami, trafienie zaznaczone, pozycje bez trafienia
     schowane (także te, które aplikacja styluje własnym `display`). */
  .stw-menu-search { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
  .stw-menu-search-field { box-sizing: border-box; width: 100%; padding: .35rem .5rem; border: 1px solid var(--thw-line);
    border-radius: var(--thw-radius-small); background: var(--thw-surface); color: var(--thw-ink); font: inherit; }
  .stw-menu :is(.stw-menu-item, .stw-menu-row, .stw-menu-group, .stw-separator)[hidden] { display: none !important; }
  .stw-mark { background: color-mix(in srgb, var(--thw-tone-accent) 25%, transparent); color: inherit; border-radius: 2px; }
  .stw-menu-search-empty { margin: 0; color: var(--thw-muted); }
  .stw-menu-item, .stw-menu-group > summary { display: flex; align-items: center; gap: .55rem; }
  .stw-menu .stw-menu-item { padding: var(--stw-item-padding-block) .6rem; border: 0; border-radius: var(--thw-radius-small); background: none;
    color: var(--thw-ink); font: inherit; text-decoration: none; text-align: left; cursor: pointer; }
  .stw-menu .stw-menu-item:hover { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); }
  /* Akcje pozycji (#12): „…” w wierszu pozycji, widoczne przy najechaniu, fokusie w wierszu i otwartym menu (na dotyku
     zawsze); menu akcji – lista w warstwie górnej, akcja „danger” w kolorze błędu. */
  .stw-menu-row { display: flex; align-items: center; min-width: 0; }
  .stw-menu-row > .stw-menu-item { flex: 1; min-width: 0; }
  .stw-menu-actions { flex: 0 0 auto; padding: .2rem .45rem; border: 0; border-radius: var(--thw-radius-small); background: none;
    color: var(--thw-muted); font: inherit; line-height: 1; cursor: pointer; opacity: 0; }
  .stw-menu-row:is(:hover, :focus-within) > .stw-menu-actions, .stw-menu-actions[aria-expanded="true"] { opacity: 1; }
  @media (hover: none) { .stw-menu-actions { opacity: 1; } }
  .stw-menu-actions:hover { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); color: var(--thw-ink); }
  .stw-menu-actions-list:popover-open { position: fixed; inset: auto; margin: 0; box-sizing: border-box; padding: .3rem; display: flex; flex-direction: column;
    border: 1px solid var(--thw-line); border-radius: var(--thw-radius); background: var(--thw-surface); color: var(--thw-ink);
    box-shadow: var(--thw-shadow); overflow-y: auto; }
  .stw-menu-actions-item { display: flex; align-items: center; gap: .5rem; padding: .4rem .6rem; border: 0; border-radius: var(--thw-radius-small);
    background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; white-space: nowrap; }
  .stw-menu-actions-item:is(:hover, :focus-visible) { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); outline: none; }
  .stw-menu-actions-item.stw-danger { color: var(--thw-tone-danger); }
  /* Bieżąca pozycja: lekkie tło akcentu, a w panelach pasek akcentu z lewej (#9; pełne wypełnienie było cięższe niż reszta
     interfejsu). */
  .stw-menu a.stw-current { background: color-mix(in srgb, var(--thw-tone-accent) 14%, transparent); color: var(--thw-ink); }
  :is(.stw-side, .stw-right) .stw-menu a.stw-current { box-shadow: inset 3px 0 0 var(--thw-tone-accent); }
  /* Długi podpis pozycji kończy się wielokropkiem (pełny w podpowiedzi), a nie krawędzią panelu. */
  .stw-menu .stw-menu-item { min-width: 0; }
  .stw-menu-label { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  /* Fokus z klawiatury: pierścień akcentu na pozycjach menu i przyciskach ramy (#9). */
  :is(.stw-menu-item, .stw-menu-group > summary, .stw-menu-actions, .stw-side-toggle, .stw-right-toggle, .stw-search-toggle,
    .stw-overflow-toggle, .stw-work-maximize, .stw-work-restore, .stw-messages-button, .stw-page-tab-close):focus-visible {
    outline: 2px solid var(--thw-tone-accent); outline-offset: -2px; }
  /* Licznik pozycji (`count`): po prawej stronie pozycji, przygaszony. */
  .stw-count { margin-left: auto; padding: 0 .45rem; border-radius: 999px; font-size: .8em; font-variant-numeric: tabular-nums;
    background: color-mix(in srgb, var(--thw-ink) 8%, transparent); }
  .stw-menu-group { display: flex; flex-direction: column; }
  .stw-menu-group > summary { padding: var(--stw-item-padding-block) .6rem; color: var(--thw-muted); font-size: .85em; font-weight: 600;
    text-transform: uppercase; letter-spacing: .04em; cursor: pointer; }
  .stw-menu-group-items { display: flex; flex-direction: column; gap: var(--stw-item-gap); margin-left: .6rem; }
  /* Separator pozycji menu i elementów obszaru: poziomy w kolumnie (także w wysuwanej liście paska górnego), pionowy
     w pasku górnym i dolnym. */
  .stw-separator { width: 100%; margin: .4rem 0; border: 0; border-top: 1px solid var(--thw-line); }
  :is(.stw-top .stw-part > .stw-separator, .stw-top .stw-menu > .stw-separator) { width: auto; height: 1.2em; margin: 0 .3rem;
    border-top: 0; border-left: 1px solid var(--thw-line); }
  /* W „⋯” (w pasku, ale lista pionowa) separator części i menu znów poziomy. */
  :is(.stw-overflow .stw-part > .stw-separator, .stw-overflow .stw-menu > .stw-separator) { width: 100%; height: auto; margin: .4rem 0;
    border-left: 0; border-top: 1px solid var(--thw-line); }
  .stw-top .stw-menu { flex-direction: row; }
  .stw-top .stw-menu-group { position: relative; }
  .stw-top .stw-menu-group > summary { text-transform: none; letter-spacing: 0; font-size: 1em; color: var(--thw-ink); font-weight: 500;
    border-radius: var(--thw-radius-small); }
  .stw-top .stw-menu-group > summary.stw-current { color: var(--thw-tone-accent); }
  .stw-top .stw-menu-group-items { position: absolute; top: calc(100% + .3rem); left: 0; z-index: 20; min-width: 14rem; margin: 0;
    padding: .4rem; border: 1px solid var(--thw-line); border-radius: var(--thw-radius); background: var(--thw-surface); box-shadow: var(--thw-shadow); }
  /* Grupa w częściach na końcu paska (za odstępem): lista od prawej krawędzi grupy, w stronę środka okna (#47). */
  .stw-top :is([data-stw-part="tools"], [data-stw-part="preferences"], [data-stw-part="account"]) .stw-menu-group-items { left: auto; right: 0; }

  /* Pasek w jednym rzędzie w każdym układzie (D25, #38); nie przewija się (wysuwane listy zostają widoczne). Gdzie jestem
     skraca się pierwsze (do 6rem); co się dalej nie mieści, przenosi do „⋯” rama (fitBar: ustawienia, potem narzędzia
     od ostatniego, na końcu konto – #45), a znak i wyszukiwanie skracają się dopiero, gdy wszystko jest w „⋯”
     (`data-stw-squeeze`, np. długa nazwa aplikacji). Pozostałe części i przyciski ramy się nie kurczą (skurczona część nachodziłaby na
     sąsiednią, a pomiar paska by tego nie widział). Części z podpisami schowanymi wzrokowo mają
     `position: relative` – schowany podpis nie poszerza strony. */
  .stw-top :is(.stw-part, .stw-menu) { flex-wrap: nowrap; }
  .stw-top > button { flex-shrink: 0; }
  .stw-top :is([data-stw-part="identity"], [data-stw-part="search"], [data-stw-part="tools"], [data-stw-part="preferences"], [data-stw-part="account"]) {
    flex-shrink: 0; position: relative; }
  .stw-top[data-stw-squeeze] :is([data-stw-part="identity"], [data-stw-part="search"]) { flex-shrink: 1; overflow: hidden; }
  .stw-top [data-stw-part="search"] > * { max-width: 100%; }
  .stw-top[data-stw-squeeze] [data-stw-part="identity"] :is(a, summary, span) {
    min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  /* Gdzie jestem nie schodzi poniżej 6rem (także przy skracaniu znaku): dalej rusza „⋯”. Krótsza treść
     zostawia wolne miejsce przed odstępem paska. */
  /* Ostatni człon zostaje (#42): człony – dzieci części, a w elemencie z co najmniej dwoma dziećmi-elementami (np.
     `<span>Gra /</span><span>Drzewa</span>`) jego dzieci, w rzędzie jak część – przed ostatnim skracają się (razem,
     do zera), a ostatni dopiero, gdy sam się nie mieści (najwyżej szerokość rodzica). Wielokropek ma każdy z nich
     (`text-overflow` działa w bloku, a nie w kontenerze flex). Odstęp członów to wcięcie w ich szerokości, a nie `gap`
     – odstęp skróconego do zera członu wypychałby ostatni poza część. */
  .stw-top [data-stw-part="location"] { gap: 0; min-width: 6rem; overflow: hidden; white-space: nowrap; }
  .stw-top [data-stw-part="location"] > :has(> * + *) { display: flex; }
  :is(.stw-top [data-stw-part="location"] > *, .stw-top [data-stw-part="location"] > * > *) {
    box-sizing: border-box; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  :is(.stw-top [data-stw-part="location"] > *, .stw-top [data-stw-part="location"] > * > *):not(:first-child) { padding-inline-start: .3em; }
  :is(.stw-top [data-stw-part="location"] > *, .stw-top [data-stw-part="location"] > * > *):last-child { flex-shrink: 0; max-width: 100%; }
  /* Przy skracaniu znaku i wyszukiwania okruszek zostaje przy 6rem: bez tego dostałby z powrotem część miejsca
     (przeglądarka dzieli brak proporcjonalnie do szerokości treści). */
  .stw-top[data-stw-squeeze] [data-stw-part="location"] { flex: 0 0 6rem; }
  /* Separator na granicy paska i „⋯” nie ma czego oddzielać; w „⋯” (narzędzia, separator, ustawienia, separator, konto)
     z dwóch separatorów bez treści między nimi zostaje jeden. */
  :is(.stw-top [data-stw-part="tools"] > .stw-separator:last-child, .stw-overflow-tools > .stw-separator:first-child,
    .stw-overflow-tools:empty + .stw-separator, .stw-overflow > .stw-separator:last-child, .stw-overflow > .stw-separator:has(+ [hidden]),
    .stw-overflow > .stw-separator + .stw-separator, .stw-overflow > .stw-separator:has(+ .stw-separator:last-child)) { display: none; }
  /* „⋯”: lista pionowa (narzędzia z widocznymi podpisami, separator, ustawienia, separator, konto); grupa narzędzia
     i konta rozwija się w liście. */
  .stw-overflow:popover-open { display: flex; flex-direction: column; align-items: stretch; gap: .5rem;
    inset: auto .5rem auto auto; top: var(--stw-top-height, 3rem); max-width: calc(100vw - 1rem); max-height: calc(100vh - var(--stw-top-height, 3rem) - 1rem);
    overflow-y: auto; box-sizing: border-box; margin: 0; padding: .5rem; border: 1px solid var(--thw-line);
    border-radius: var(--thw-radius); background: var(--thw-surface); color: var(--thw-ink); box-shadow: var(--thw-shadow); }
  .stw-overflow :is(.stw-overflow-tools, [data-stw-part="preferences"], [data-stw-part="account"], .stw-menu) { display: flex; flex-direction: column;
    flex-wrap: nowrap; align-items: stretch; gap: .25rem; }
  .stw-overflow :is([data-stw-part="preferences"], [data-stw-part="account"])[hidden] { display: none; }
  .stw-overflow-tools > * { align-self: flex-start; }
  .stw-overflow .stw-menu-group-items { position: static; min-width: 0; margin-left: .6rem; padding: 0;
    border: 0; box-shadow: none; }

  /* Obszar roboczy: lokalna nawigacja grupy – zakładki nad treścią albo panel z prawej. */
  .stw-workspace-nav { display: flex; align-items: center; gap: var(--stw-item-gap); }
  .stw-workspace-nav .stw-menu-item { padding: var(--stw-item-padding-block) .8rem; border: 0; border-radius: var(--thw-radius-small); background: none;
    color: var(--thw-ink); font: inherit; text-decoration: none; cursor: pointer; }
  .stw-workspace-nav .stw-menu-item:hover { background: color-mix(in srgb, var(--thw-ink) 8%, transparent); }
  .stw-workspace-nav a.stw-current { color: var(--thw-tone-accent); box-shadow: inset 0 -2px 0 var(--thw-tone-accent); }
  .stw-workspace-title { display: flex; align-items: center; gap: .45rem; margin-right: .8rem; color: var(--thw-muted); font-weight: 600; }
  .stw-workspace-tabs { padding: .5rem 2rem 0; border-bottom: 1px solid var(--thw-line); flex-wrap: wrap; }
  .stw-work[data-stw-workspace="panel"] { display: grid; grid-template-columns: minmax(0, 1fr) 14rem; grid-template-rows: auto auto 1fr;
    grid-template-areas: "banner banner" "tabs panel" "content panel"; }
  .stw-work[data-stw-workspace="panel"] > .stw-banner { grid-area: banner; }
  .stw-work[data-stw-workspace="panel"] > .stw-page-tabs { grid-area: tabs; }
  .stw-work[data-stw-workspace="panel"] > .stw-content { grid-area: content; }
  .stw-work[data-stw-workspace="panel"] > .stw-workspace { grid-area: panel; padding: 1.5rem .75rem; border-left: 1px solid var(--thw-line); }
  .stw-workspace-panel { flex-direction: column; align-items: stretch; }
  .stw-workspace-panel a.stw-current { box-shadow: inset 2px 0 0 var(--thw-tone-accent); }

  /* Wąskie okno: obszary jeden pod drugim, menu zawijane. */
  /* Układ z szufladą (D25, `data-stw-panel="drawer"`, np. wąskie okno): pasek w jednym rzędzie (bez przewijania; co się
     nie mieści, jest pod „⋯”), pod nim treść. Nawigacja w szufladzie z lewej (otwiera ją przełącznik, zamyka Escape, klik obok
     i przejście; reszta ramy jest wtedy `inert`), panel prawy jako arkusz od dołu, wyszukiwanie pod lupą (pole na
     szerokość paska), ustawienia w menu „⋯”; podpisy narzędzi i konta schowane wzrokowo (zostają dla czytników). */
  .stw-frame[data-stw-panel="drawer"] { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; grid-template-areas: "top" "work"; }
  .stw-frame[data-stw-panel="drawer"] .stw-top { gap: .5rem; padding: 0 .5rem; }
  /* Wysuwane listy paska w szufladzie: przy krawędziach okna pod paskiem (części paska bywają skrócone i przycięte). */
  .stw-frame[data-stw-panel="drawer"] .stw-top .stw-menu-group-items:not(.stw-overflow *) { position: fixed; top: var(--stw-top-height, 3rem); left: .5rem;
    right: .5rem; min-width: 0; }
  .stw-frame[data-stw-panel="drawer"] :is([data-stw-part="tools"], [data-stw-part="account"]) .stw-label:not(.stw-menu-group-items *, .stw-overflow *) {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .stw-frame[data-stw-panel="drawer"]:not([data-stw-search]) [data-stw-part="search"] { display: none; }
  .stw-frame[data-stw-panel="drawer"][data-stw-search] [data-stw-part="search"] { position: absolute; inset: 0; z-index: 1;
    padding: 0 .5rem; background: var(--thw-surface); }
  .stw-frame[data-stw-panel="drawer"] :is(.stw-side, .stw-right) { position: fixed; z-index: 15; transition: none !important; }
  /* `align-self: stretch` zdejmuje `start` z układu kolumnowego: w elemencie z `position: fixed` wyrównanie inne niż
     `stretch` daje wysokość z treści zamiast z `inset` (CSS Box Alignment), więc długie menu wychodziło poza okno bez
     przewijania (#55). */
  .stw-frame[data-stw-panel="drawer"] .stw-side { inset: 0 auto 0 0; align-self: stretch; width: min(20rem, 85vw); height: auto;
    overflow-y: auto; box-shadow: var(--thw-shadow); }
  .stw-frame[data-stw-panel="drawer"]:not([data-stw-drawer]) .stw-side { display: none; }
  .stw-frame[data-stw-panel="drawer"][data-stw-drawer]::after { content: ""; position: fixed; inset: 0; z-index: 14;
    background: color-mix(in srgb, var(--thw-ink) 35%, transparent); }
  .stw-frame[data-stw-panel="drawer"] .stw-right { inset: auto 0 0 0; width: auto; height: auto; max-height: 60vh; overflow-y: auto;
    border-left: 0; border-top: 1px solid var(--thw-line); background: var(--thw-surface); box-shadow: var(--thw-shadow); }
  .stw-frame[data-stw-panel="drawer"]:not([data-stw-sheet]) .stw-right { display: none; }
  .stw-frame[data-stw-panel="drawer"] :is(.stw-side-resizer, .stw-right-resizer) { display: none; }
  .stw-frame[data-stw-panel="drawer"] .stw-content { padding: 1rem; }
  .stw-frame[data-stw-panel="drawer"] .stw-work[data-stw-workspace="panel"] { grid-template-columns: 1fr; grid-template-rows: none;
    grid-template-areas: "banner" "panel" "tabs" "content"; }

  /* Wiadomości: toasty w prawym dolnym rogu (warstwa górna) i karta wiadomości (toast i lista). Kolory poziomów
     z tokenów --thw-tone-info, --thw-tone-success, --thw-tone-warning, --thw-tone-danger. */
  /* Odstęp wewnątrz regionu: cień toastu mieści się w przewijanym regionie. */
  /* Odstęp od dołu okna to token (#52): aplikacja z przyklejonym paskiem na dole (np. pasek zapisu formularza) podnosi
     region nad niego. */
  .stw-toasts { inset: auto .5rem var(--stw-toasts-bottom) auto; margin: 0; padding: .5rem; border: 0; background: none;
    box-sizing: border-box; width: min(25rem, calc(100vw - 1rem));
    /* Najwyżej 60% okna i nie wyżej niż 5rem od góry: pasek górny (np. ✉, ⤢) i przycisk przywracania ⤡ zostają wolne. */
    max-height: min(60vh, calc(100vh - 4.5rem - var(--stw-toasts-bottom))); }
  /* Wiele toastów: region się przewija (najstarsze u góry), a pierwszy dosuwa resztę do dołu. */
  .stw-toasts:popover-open { display: flex; flex-direction: column; gap: .5rem; overflow-y: auto; overscroll-behavior: contain; }
  .stw-toast:first-child { margin-top: auto; }
  /* Region przepuszcza kliknięcia poza kartami (wcięcie, odstępy między toastami, wolne miejsce nad nimi): toast zasłania
     treść pod sobą, a nie cały prostokąt regionu (#28). Kółko nad kartą dalej przewija region. */
  .stw-toasts { pointer-events: none; }
  .stw-toast { pointer-events: auto; }
  .stw-toast { border: 1px solid var(--thw-line); border-radius: var(--thw-radius); background: var(--thw-surface);
    color: var(--thw-ink); box-shadow: var(--thw-shadow); }
  .stw-message { display: grid; gap: .35rem; padding: .6rem .75rem; border-left: 4px solid var(--stw-message-color, var(--thw-tone-info));
    border-radius: inherit; }
  .stw-message-info { --stw-message-color: var(--thw-tone-info); }
  .stw-message-success { --stw-message-color: var(--thw-tone-success); }
  .stw-message-warning { --stw-message-color: var(--thw-tone-warning); }
  .stw-message-danger { --stw-message-color: var(--thw-tone-danger); }
  .stw-message-head { display: flex; align-items: baseline; gap: .5rem; }
  .stw-message-glyph { color: var(--stw-message-color); font-weight: 700; }
  .stw-message-title { flex: 1; min-width: 0; overflow-wrap: anywhere; }
  .stw-message-close { border: 0; background: none; color: var(--thw-muted); font: inherit; cursor: pointer; padding: 0 .2rem; }
  .stw-message-body { margin: 0; white-space: pre-line; overflow-wrap: anywhere; color: var(--thw-ink); }
  .stw-message-progress { display: flex; align-items: center; gap: .5rem; color: var(--thw-muted); font-size: .85em;
    font-variant-numeric: tabular-nums; }
  .stw-message-progress progress { flex: 1; accent-color: var(--thw-tone-accent); }
  .stw-message-log summary { cursor: pointer; color: var(--thw-muted); font-size: .9em; }
  .stw-message-log pre { margin: .3rem 0 0; max-height: 12rem; overflow: auto; padding: .4rem .5rem; border-radius: var(--thw-radius-small);
    background: var(--thw-menu); font-size: .85em; white-space: pre-wrap; overflow-wrap: anywhere; }
  .stw-log-warning { color: var(--thw-tone-warning); }
  .stw-log-danger { color: var(--thw-tone-danger); }
  .stw-message-actions { display: flex; gap: .75rem; align-items: center; }
  .stw-message-open { color: var(--thw-tone-accent); }
  .stw-message-action { padding: .2rem .6rem; border: 1px solid var(--thw-line); border-radius: var(--thw-radius-small);
    background: var(--thw-surface); color: var(--thw-ink); font: inherit; cursor: pointer; }
  /* Lista wiadomości (element `messages`): przycisk jak przełącznik panelu, znaczek nieprzeczytanych, panel pod nim. */
  .stw-messages-button { display: inline-flex; align-items: center; gap: .3rem; padding: .3rem .5rem; border: 0;
    border-radius: var(--thw-radius-small); background: none; color: var(--thw-ink); font: inherit; font-size: 1.15em; line-height: 1; cursor: pointer; }
  .stw-messages-button .stw-count { margin: 0; font-size: .65em; background: var(--thw-tone-accent); color: var(--thw-accent-ink); }
  /* Miejsce panelu przy przycisku ustawia popoverAt (placePanel – jedno źródło dla list ramy); szerokość z tej reguły,
     w oknie węższym – do okna (`max-width` z placePanel). */
  .stw-messages-panel { position: fixed; inset: auto; margin: 0; box-sizing: border-box; width: 26rem;
    overflow: auto; padding: .75rem; border: 1px solid var(--thw-line); border-radius: var(--thw-radius); background: var(--thw-surface);
    color: var(--thw-ink); box-shadow: var(--thw-shadow); }
  .stw-messages-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; margin-bottom: .5rem; }
  .stw-messages-title { margin: 0; font-size: 1em; }
  .stw-messages-system { display: inline-flex; align-items: center; gap: .3rem; color: var(--thw-muted); font-size: .9em; }
  .stw-messages-list { display: grid; gap: .5rem; margin: 0; padding: 0; list-style: none; }
  .stw-messages-list > li { border: 1px solid var(--thw-line); border-radius: var(--thw-radius-small); }
  .stw-messages-empty { margin: 0; color: var(--thw-muted); }
  /* Tekst tylko dla czytników ekranu (np. poziom wiadomości przed tytułem). */
  .stw-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

  /* Podział obszaru pracy (`frame.split`): dwie części i uchwyt; udział pierwszej – --stw-split-ratio, najmniejszy
     rozmiar części – --stw-split-min; jedno pod drugim potrzebuje wysokości (--stw-split-height, domyślnie 70vh). */
  .stw-split { display: flex; min-width: 0; }
  .stw-split[data-stw-direction="column"] { flex-direction: column; height: var(--stw-split-height, 70vh); }
  .stw-split > .stw-split-pane { min-width: 0; min-height: 0; }
  /* Pierwsza część oddaje miejsce do granicy `min` drugiej (#46): udział z uchwytu to rozmiar, nie sztywna szerokość. */
  .stw-split > .stw-split-pane:first-child { flex: 0 1 calc(var(--stw-split-ratio, .5) * (100% - 8px)); }
  .stw-split > .stw-split-pane:last-child { flex: 1 1 0; }
  .stw-split[data-stw-direction="row"] > .stw-split-pane { min-width: var(--stw-split-min, 0px); }
  .stw-split[data-stw-direction="column"] > .stw-split-pane { min-height: var(--stw-split-min, 0px); overflow: auto; }
  /* Pierwsza część według treści (`fit: "content"`, jedno pod drugim): wysokość treści, najwyżej udział z uchwytu – pod
     krótką treścią nie zostaje pusty pas, a dłuższa przewija się w granicy. W trakcie przeciągania – sam udział, żeby
     uchwyt szedł za wskaźnikiem także poniżej krótkiej treści. */
  .stw-split[data-stw-direction="column"][data-stw-fit="content"]:not([data-stw-resizing]) > .stw-split-pane:first-child {
    flex: 0 1 auto; min-height: 0; max-height: calc(var(--stw-split-ratio, .5) * (100% - 8px)); }
  /* Część z treścią poza krawędzią (#21, `data-stw-more`): treść zanika przy tej krawędzi – wiadomo, że jest jej więcej;
     znak nie zmienia wysokości części i nie przyjmuje kliknięć (to maska, nie węzeł). */
  /* Pozycja z fokusem (Tab) zatrzymuje się poza strefą zanikania. */
  .stw-split-pane { scroll-padding-block: 1.5rem; }
  .stw-split-pane[data-stw-more="after"] { mask-image: linear-gradient(to bottom, #000 calc(100% - 1.5rem), transparent); }
  .stw-split-pane[data-stw-more="before"] { mask-image: linear-gradient(to top, #000 calc(100% - 1.5rem), transparent); }
  .stw-split-pane[data-stw-more="before after"] { mask-image: linear-gradient(to bottom, transparent, #000 1.5rem, #000 calc(100% - 1.5rem), transparent); }
  .stw-split-handle { flex: 0 0 8px; position: relative; touch-action: none; cursor: col-resize; }
  .stw-split[data-stw-direction="column"] > .stw-split-handle { cursor: row-resize; }
  .stw-split-handle::before { content: ""; position: absolute; inset: 0 3px; background: var(--thw-line); }
  .stw-split[data-stw-direction="column"] > .stw-split-handle::before { inset: 3px 0; }
  .stw-split-handle:is(:hover, :focus-visible)::before { inset: 0; background: color-mix(in srgb, var(--thw-tone-accent) 35%, transparent); }
  .stw-split-handle:focus-visible { outline: none; }
  .stw-split[data-stw-resizing] { user-select: none; cursor: col-resize; }
  .stw-split[data-stw-direction="column"][data-stw-resizing] { cursor: row-resize; }
  /* Część przyklejona (np. podgląd obok edytora): zostaje w oknie przy przewijaniu. */
  .stw-split[data-stw-direction="row"] > .stw-split-sticky { position: sticky; top: calc(var(--stw-top-height, 0px) + .5rem); align-self: flex-start;
    max-height: calc(100vh - var(--stw-top-height, 0px) - 1rem); overflow: auto; }
  /* Układ z szufladą (wąskie okno) i podział węższy niż dwa `min` z uchwytem (`data-stw-stacked`, #46): obok siebie
     staje się jedno pod drugim, bez uchwytu. */
  :is(.stw-frame[data-stw-panel="drawer"] .stw-split, .stw-split[data-stw-stacked])[data-stw-direction="row"] { flex-direction: column; }
  :is(.stw-frame[data-stw-panel="drawer"] .stw-split, .stw-split[data-stw-stacked])[data-stw-direction="row"] > .stw-split-pane { flex: none; min-width: 0; }
  :is(.stw-frame[data-stw-panel="drawer"] .stw-split, .stw-split[data-stw-stacked])[data-stw-direction="row"] > .stw-split-handle { display: none; }
  :is(.stw-frame[data-stw-panel="drawer"] .stw-split, .stw-split[data-stw-stacked])[data-stw-direction="row"] > .stw-split-sticky { position: static; max-height: none; }

  /* Wskaźnik wczytywania (`data-stw-loading`): cienki pasek przy górnej krawędzi okna (poza siatką ramy, nad paskiem
     górnym); przy `prefers-reduced-motion` stoi w miejscu. */
  .stw-frame[data-stw-loading]::before { content: ""; position: fixed; top: 0; left: 0; right: 0; z-index: 20;
    height: 3px; background: linear-gradient(90deg, transparent, var(--thw-tone-accent) 40%, var(--thw-tone-accent) 60%, transparent) 0 0 / 40% 100% no-repeat;
    animation: stw-loading 1.1s linear infinite; }
  @keyframes stw-loading { from { background-position: -40% 0; } to { background-position: 140% 0; } }
  @media (prefers-reduced-motion: reduce) {
    .stw-frame[data-stw-loading]::before { animation: none; background: var(--thw-tone-accent); opacity: .6; }
  }

  /* Po regułach wąskiego okna: maksymalizacja wygrywa z układem obszarów każdego ułożenia i szerokości okna (ta sama
     specyficzność, więc decyduje kolejność). */
  /* Obszar pracy zmaksymalizowany (setWorkMaximized): na całe okno bez obszarów ramy, okno się nie przewija. */
  .stw-frame[data-stw-work="maximized"] { grid-template: "work" 100vh / 1fr; height: 100vh; overflow: hidden; }
  .stw-frame[data-stw-work="maximized"] :is(.stw-top, .stw-side, .stw-side-resizer, .stw-right, .stw-right-resizer, .stw-workspace) { display: none; }
  .stw-frame[data-stw-work="maximized"] .stw-work { display: flex; flex-direction: column; min-height: 0; }
  .stw-frame[data-stw-work="maximized"] .stw-content { flex: 1; min-height: 0; box-sizing: border-box; max-width: none; overflow: auto; }
  /* Przycisk przywracania: tylko w zmaksymalizowanym obszarze, w jego prawym górnym rogu (nad treścią). */
  .stw-work-restore { display: none; }
  .stw-frame[data-stw-work="maximized"] .stw-work-restore { display: block; position: fixed; top: .5rem; right: .5rem; z-index: 30;
    padding: .3rem .5rem; border: 1px solid var(--thw-line); border-radius: var(--thw-radius-small); background: var(--thw-surface);
    color: var(--thw-ink); font: inherit; font-size: 1.15em; line-height: 1; cursor: pointer; box-shadow: var(--thw-shadow); }
  /* Ruch maksymalizacji: przejście widoku przeglądarki tylko w trakcie zmiany (`data-stw-work-moving` na <html>),
     więc przejścia widoku samej aplikacji nie dostają czasu ramy; obszar pracy (nazwa przejścia `stw-work-<n>` z ramy)
     przechodzi z miejsca na miejsce. */
  :root[data-stw-work-moving]::view-transition-group(*), :root[data-stw-work-moving]::view-transition-old(*),
  :root[data-stw-work-moving]::view-transition-new(*) { animation-duration: var(--stw-motion-duration); }
  /* Przycisk maksymalizacji (element `work-maximize`), wyglądem jak przełącznik panelu. */
  .stw-work-maximize { display: inline-flex; align-items: center; gap: .3rem; padding: .3rem .5rem; border: 0; border-radius: var(--thw-radius-small); background: none; color: var(--thw-ink);
    font: inherit; font-size: 1.15em; line-height: 1; cursor: pointer; }
  /* Część elementu widoczna tylko w menu „⋯” (`stw-overflow-label`, #43; np. podpis przycisku, który w pasku jest samym
     znakiem z nazwą w `aria-label`); `!important` jak w umowie stanu paneli – działa też na częściach stylowanych przez
     aplikację. Wbudowane (maksymalizacja, wiadomości, #36) mają podpis w rozmiarze tekstu listy. */
  .stw-overflow-label:not(.stw-overflow *) { display: none !important; }
  .stw-overflow :is(.stw-work-maximize, .stw-messages-button) > .stw-overflow-label { font-size: calc(1em / 1.15); }
  .stw-frame :is(.stw-work-maximize, .stw-work-restore):hover { background: color-mix(in srgb, var(--thw-ink) 8%, var(--thw-surface)); }

  /* Druk: pasek i panele nie są przyklejone (tło panelu sięga do końca treści, jak przed przyklejeniem). */
  @media print {
    /* Ta sama siła co reguły układów (`data-stw-panel`), później – wygrywa także w szufladzie. */
    .stw-frame[data-stw-panel] :is(.stw-top, .stw-side, .stw-right) { position: static; height: auto; overflow: visible; }
    /* Otwarta szuflada i arkusz to stan chwilowy ekranu – na wydruku ich nie ma. */
    .stw-frame[data-stw-panel="drawer"]::after, .stw-frame[data-stw-panel="drawer"] :is(.stw-side, .stw-right) { display: none; }
    :is(.stw-side-resizer, .stw-right-resizer) { display: none; }
    .stw-split-pane[data-stw-more] { mask-image: none; }
  }
}
