/* Virtual desktop — everything the retro skin does NOT give us.
 *
 * The vendored 98/XP/7 stylesheets are scoped to .dsk-scope (see
 * scripts/scope_css.py) and only dress the *windows*. The desktop surface,
 * the icons, the taskbar and the menus are ours, and are deliberately kept
 * OUTSIDE that scope — as is the chat panel, which must keep the site's own
 * styling when it is moved into the desktop.
 */

#dsk-root {
  /* The air above the first line of the list and details views — see
   * .dsk-view-list / .dsk-view-table, and the sticky header that has to know
   * the same number to park flush once the list is scrolled. */
  --dsk-view-pad: 8px;
  position: fixed;
  inset: 0;
  z-index: 900;
  display: none;
  background: #008080;                    /* the teal, obviously */
  font-family: "Pixelated MS Sans Serif", Tahoma, "Segoe UI", sans-serif;
  font-size: 11px;
  -webkit-font-smoothing: none;
  overflow: hidden;
  touch-action: none;
}
body.dsk-on #dsk-root { display: block; }
/* The chat card is MOVED into the desktop, so hiding the page layout does not
 * hide it — and moving (not cloning) is what keeps its listeners and state. */
body.dsk-on .layout,
body.dsk-on .topbar { display: none !important; }
body.dsk-on { overflow: hidden; }

#dsk-root[data-theme="xp"] { background: #3a6ea5; }
#dsk-root[data-theme="7"] { background: #1f3b57; }

/* The surface says WHICH desktop you are on, before you read anything on it.
 * Green is the personal one, blue is the shared one, for everybody and under
 * every skin — so these come after the theme rules and win by source order.
 * Deliberately not a setting: the whole value of the colour is that it means
 * the same thing on every screen in the company. Both are dark enough for the
 * white icon labels to stay readable.
 *
 * Both are the shades the desktop already had, back when the background
 * followed the skin: the teal of Windows 95 and the blue of XP. They were
 * drawn for this grey window chrome, and colours picked from scratch were not
 * — that is the whole reason these two won. */
#dsk-root[data-scope="personal"] { background: #008080; }
#dsk-root[data-scope="shared"] { background: #3a6ea5; }

/* --- layers ---------------------------------------------------------------
 * Three sibling layers, none of them a stacking context of its own, so one
 * z-index counter orders windows across all of them.
 */
#dsk-root .dsk-surface {
  position: absolute;
  inset: 0 0 34px 0;
  overflow: hidden;
}
#dsk-root .dsk-layer {
  position: absolute;
  inset: 0 0 34px 0;
  pointer-events: none;
}
#dsk-root .dsk-layer > * { pointer-events: auto; }

/* --- icons --------------------------------------------------------------- */
#dsk-root .dsk-icon {
  position: absolute;
  width: 76px;
  padding: 3px 2px 4px;
  text-align: center;
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
}
#dsk-root .dsk-icon-img {
  width: 32px;
  height: 32px;
  margin: 0 auto;
  display: block;
  image-rendering: pixelated;
  pointer-events: none;
}
/* Two lines, then «…». A cell is 88px tall and holds a 32px glyph, so a name
 * left to wrap freely — «Измерение опор мачты №14 итог.xlsx» — grew down over
 * the icon below it and no arrangement could look tidy. Windows solved this
 * the same way: clamp the label, and give the whole name back when the icon is
 * selected (below) or hovered, where the tooltip carries it too. */
#dsk-root .dsk-icon-label {
  display: inline-block;
  display: -webkit-inline-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 72px;
  margin-top: 2px;
  padding: 1px 2px;
  color: #fff;
  line-height: 1.2;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, .8);
  overflow-wrap: anywhere;
  pointer-events: none;
}
/* The selected icon shows its whole name, and rises above its neighbours so
 * the extra lines cover them rather than being covered. */
#dsk-root .dsk-icon.is-selected {
  z-index: 4;
}
#dsk-root .dsk-icon.is-selected .dsk-icon-label {
  -webkit-line-clamp: unset;
  overflow: visible;
}
#dsk-root .dsk-icon.is-selected .dsk-icon-label {
  background: #000080;
  outline: 1px dotted #fff;
  text-shadow: none;
}
/* An image or video icon shows the file itself. Bigger than the 32px pixel
 * glyph and smoothly scaled — a thumbnail rendered `pixelated` is mush — with
 * a sunken frame so it still reads as an icon and not as loose content. */
#dsk-root .dsk-icon-img.is-thumb {
  width: 48px;
  height: 40px;
  object-fit: cover;
  background: #000;
  image-rendering: auto;
  box-shadow: 0 0 0 1px #000, 0 0 0 2px #dfdfdf;
}
#dsk-root .dsk-icon.is-missing .dsk-icon-img { opacity: .45; }
#dsk-root .dsk-icon.is-dragging { opacity: .55; }

/* Rubber-band selection box. Lives inside the surface it is sweeping, so it
 * scrolls with a folder window's contents. */
#dsk-root .dsk-marquee {
  position: absolute;
  z-index: 5;
  border: 1px dotted #fff;
  background: rgba(255, 255, 255, .16);
  pointer-events: none;
}
#dsk-root .dsk-win .dsk-marquee { border-color: #000080; background: rgba(0, 0, 128, .12); }
/* Inside a window the surface is grey, so icon labels flip to black-on-grey. */
#dsk-root .dsk-win .dsk-icon-label { color: #222; text-shadow: none; }
#dsk-root .dsk-win .dsk-icon.is-selected .dsk-icon-label { color: #fff; }

#dsk-root .dsk-drop-hint { outline: 2px dotted #fff; outline-offset: -6px; }
#dsk-root .dsk-win .dsk-drop-hint { outline-color: #000080; }

/* --- windows -------------------------------------------------------------
 * Chrome comes from the vendored skin (.window / .title-bar / .window-body);
 * geometry, dragging and the resize grip are ours.
 */
/* ---------------------------------------------------------------------------
 * WHY THESE SELECTORS START AT #dsk-root
 *
 * The skin is a stylesheet appended to <head> at runtime, so it is always
 * LATER than this file, and its rules are one class deeper than ours
 * (`.dsk-scope .window` beats `.dsk-win`). Anywhere both files speak about the
 * same property, the skin wins — including properties it has no business
 * setting on a window that is not its own.
 *
 * `7.css` sets `position: relative` on `.window`. That put every window back
 * into normal flow: they stacked vertically instead of cascading, `top`/`left`
 * became offsets from the flow position rather than from the desktop, and a
 * window could therefore never be dragged ABOVE the window it opened under —
 * until that one was closed and the flow moved up.
 *
 * The `#dsk-root` prefix outranks any `.dsk-scope …` rule by an id, without
 * !important and without having to guess what the next vendored skin will
 * decide to set.
 * ------------------------------------------------------------------------- */
#dsk-root .dsk-win {
  position: absolute;
  display: flex;
  flex-direction: column;
  min-width: 200px;
  min-height: 120px;
  box-sizing: border-box;
}
#dsk-root .dsk-win .title-bar { cursor: move; flex: 0 0 auto; }
#dsk-root .dsk-win .window-body {
  flex: 1 1 auto;
  position: relative;
  overflow: auto;
  margin: 3px;
  background: #fff;
  box-shadow: inset -1px -1px #dfdfdf, inset 1px 1px grey,
              inset -2px -2px #fff, inset 2px 2px #0a0a0a;
}
#dsk-root .dsk-win .window-body.dsk-body-plain {
  background: silver;
  box-shadow: none;
}
/* Above the display:flex the id-prefixed rules set. */
#dsk-root .dsk-win.is-minimized { display: none; }
/* Eight resize handles: four edge strips and four corners on top of them.
 * Deliberately reaching a little OUTSIDE the window — a 6px strip that starts
 * at the border is a strip you keep missing. */
#dsk-root .dsk-resize { position: absolute; z-index: 2; }
#dsk-root .dsk-resize-n { top: -3px; left: 8px; right: 8px; height: 6px; cursor: ns-resize; }
#dsk-root .dsk-resize-s { bottom: -3px; left: 8px; right: 8px; height: 6px; cursor: ns-resize; }
#dsk-root .dsk-resize-e { right: -3px; top: 8px; bottom: 8px; width: 6px; cursor: ew-resize; }
#dsk-root .dsk-resize-w { left: -3px; top: 8px; bottom: 8px; width: 6px; cursor: ew-resize; }
#dsk-root .dsk-resize-nw { top: -3px; left: -3px; width: 12px; height: 12px; cursor: nwse-resize; }
#dsk-root .dsk-resize-ne { top: -3px; right: -3px; width: 12px; height: 12px; cursor: nesw-resize; }
#dsk-root .dsk-resize-sw { bottom: -3px; left: -3px; width: 12px; height: 12px; cursor: nesw-resize; }
#dsk-root .dsk-resize-se { bottom: -3px; right: -3px; width: 14px; height: 14px; cursor: nwse-resize; }
#dsk-root .dsk-win-content { position: relative; min-height: 100%; }

/* --- the notepad ---------------------------------------------------------
 * A toolbar that stays put, and one of the editor / preview pair filling the
 * rest of the window.
 */
/* The rendered half of a Markdown document: an opaque sheet over the editor,
 * so «Просмотр» is one class toggle and the editor keeps its scroll position
 * underneath.
 *
 * The z-index is not decoration. `ace.edit(el)` turns the host ITSELF into the
 * editor container, so this sheet is a child of Ace's own layout — where the
 * gutter sits at z-index 4 and the scrollbars at 6. Anything lower and the
 * line numbers show through the rendered document and clip its first
 * characters. */
#dsk-root .dsk-edit-host .dsk-md-preview {
  position: absolute;
  inset: 0;
  z-index: 20;
  overflow: auto;
}
#dsk-root .dsk-md-preview {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 10px 14px;
  background: #fff;
  color: #1a1a1a;
  font-family: Tahoma, "Segoe UI", system-ui, sans-serif;
  font-size: 13px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
#dsk-root .dsk-md-preview[hidden] { display: none; }
#dsk-root .dsk-md-preview h1, #dsk-root .dsk-md-preview h2, #dsk-root .dsk-md-preview h3,
#dsk-root .dsk-md-preview h4, #dsk-root .dsk-md-preview h5, #dsk-root .dsk-md-preview h6 {
  margin: 1em 0 .4em;
  line-height: 1.25;
}
#dsk-root .dsk-md-preview h1 { font-size: 1.6em; }
#dsk-root .dsk-md-preview h2 { font-size: 1.35em; }
#dsk-root .dsk-md-preview h3 { font-size: 1.15em; }
#dsk-root .dsk-md-preview p { margin: 0 0 .8em; }
#dsk-root .dsk-md-preview ul, #dsk-root .dsk-md-preview ol { margin: 0 0 .8em; padding-left: 1.6em; }
#dsk-root .dsk-md-preview li { margin: .2em 0; }
#dsk-root .dsk-md-preview .dsk-task-item { list-style: none; margin-left: -1.4em; }
/* All three skins HIDE the native checkbox — `opacity: 0; position: fixed` —
 * and draw the box through an adjacent <label>, which a Markdown task item
 * does not have. Inside a skinned window that left a checklist with nothing to
 * click. The preview is deliberately not the pixel look anyway, so the box is
 * handed back to the browser; the extra class beats `.dsk-scope input[…]` on
 * specificity, which is what this rule needs to win. */
#dsk-root .dsk-md-preview .dsk-task-item input[type="checkbox"] {
  -webkit-appearance: checkbox;
  -moz-appearance: checkbox;
  appearance: auto;
  position: static;
  opacity: 1;
  width: 13px;
  height: 13px;
  margin: 0 6px 0 0;
  vertical-align: -2px;
  background: initial;
  border: initial;
  cursor: pointer;
}
#dsk-root .dsk-md-preview a { color: #0645ad; }
#dsk-root .dsk-md-preview code {
  padding: 1px 4px;
  background: #f0f0f0;
  border: 1px solid #ddd;
  font-family: Consolas, "Courier New", monospace;
  font-size: .92em;
}
#dsk-root .dsk-md-preview pre {
  margin: 0 0 .8em;
  padding: 8px 10px;
  overflow-x: auto;
  background: #f6f6f6;
  border: 1px solid #ddd;
}
#dsk-root .dsk-md-preview pre code { padding: 0; background: none; border: 0; }
#dsk-root .dsk-md-preview blockquote {
  margin: 0 0 .8em;
  padding: .1em 0 .1em .9em;
  border-left: 3px solid #c0c7c8;
  color: #555;
}
#dsk-root .dsk-md-preview hr { border: 0; border-top: 1px solid #ccc; margin: 1.2em 0; }
#dsk-root .dsk-md-preview img { max-width: 100%; }
#dsk-root .dsk-md-preview table { border-collapse: collapse; margin: 0 0 .8em; }
#dsk-root .dsk-md-preview th, #dsk-root .dsk-md-preview td {
  border: 1px solid #c0c7c8;
  padding: 4px 8px;
  text-align: left;
}
#dsk-root .dsk-md-preview th { background: #efefef; }

/* --- the explorer --------------------------------------------------------
 * Icons / list / table, a filter box, and sortable column headers. The bar
 * stays while only the contents scroll.
 */
#dsk-root .dsk-win .window-body.dsk-explorer {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#dsk-root .dsk-explorer > .dsk-win-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}
/* Icons place themselves and already keep clear of the toolbar; the two flat
 * views start at y=0, so their first line — a row, or the header of the
 * details table — sat against the toolbar's border with nothing between them.
 * Air, and only at the top. The details view takes the same air as a margin on
 * the table itself (see .dsk-table) rather than as padding here: padding stays
 * put while the rows scroll, and a sticky header does not reliably cover it. */
#dsk-root .dsk-view-list { padding-top: var(--dsk-view-pad); }
/* One row, and it stays one row: the filter is the only thing that gives, so
 * a narrow window shrinks the text field instead of wrapping the buttons onto
 * a second line. */
#dsk-root .dsk-explorer-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 3px;
  padding: 3px;
  background: silver;
  border-bottom: 1px solid grey;
}
/* Every toolbar button, in both toolbars, is this square. Id-prefixed for the
 * reason above: `.dsk-scope button` is one element deeper than `.dsk-tool`, so
 * the skin's own min-width/min-height/padding decided the size of a button
 * that is supposed to be exactly 19×19. */
#dsk-root .dsk-tool {
  flex: 0 0 auto;
  width: 19px;
  height: 19px;
  min-width: 0;
  min-height: 0;
  padding: 0;
  font-size: 10px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
#dsk-root .dsk-tool:disabled { color: #808080; text-shadow: 1px 1px #fff; }
/* Unsaved work. The only stateful button on either toolbar, so it is allowed
 * to shout a little. */
#dsk-root .dsk-tool.is-dirty {
  color: #a00000;
  font-weight: 700;
}
#dsk-root .dsk-tool.is-dirty::after {
  content: "•";
  position: absolute;
  margin: -8px 0 0 9px;
  font-size: 12px;
  line-height: 1;
}
#dsk-root .dsk-edit-bar .dsk-tool { position: relative; }

#dsk-root .dsk-explorer-spacer { flex: 1 1 auto; min-width: 0; }
#dsk-root .dsk-explorer-filter {
  flex: 1 1 40px;
  min-width: 0;
  height: 19px;
  box-sizing: border-box;
  border: 0;
  padding: 0 4px;
  background: #fff;
  color: #222;
  font-family: inherit;
  font-size: 11px;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}

#dsk-root .dsk-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 6px;
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
}
/* Nudged one pixel up, and only in a row: centring the BOXES leaves the two
 * inks off by that pixel. A name with no descenders — «SAT», «TS59» — puts its
 * ink entirely above the baseline, high in a line box sized for descenders,
 * while the glyph fills its box evenly; the eye reads the difference as the
 * icon hanging low. `position` rather than a margin, so the row keeps its
 * height and the list its rhythm. */
#dsk-root .dsk-row-glyph {
  flex: 0 0 auto;
  position: relative;
  top: -1px;
  vertical-align: middle;
  width: 16px !important;
  height: 16px !important;
  margin: 0;
  object-fit: cover;
}
#dsk-root .dsk-row-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#dsk-root .dsk-row.is-selected, #dsk-root .dsk-trow.is-selected > td { background: #000080; color: #fff; }
#dsk-root .dsk-row.is-missing, #dsk-root .dsk-trow.is-missing { opacity: .55; }
#dsk-root .dsk-row.is-dragging, #dsk-root .dsk-trow.is-dragging { opacity: .55; }

/* `background: transparent`, not `silver`: the vendored skins paint every
 * `table` white (a 98.css rule), and the details view came out as a white
 * sheet inside a grey window — the one view in the explorer that did not look
 * like the desktop it belongs to. Transparent lets the window body show
 * through, so the view is the right colour under 98, XP and 7 alike instead of
 * being pinned to one skin's grey. */
/* `table-layout: fixed`, and that is what makes a wider window show more of a
 * name. With the automatic layout the columns sized themselves to their
 * content and every cell was capped at 260px, so the name was cut at the same
 * place no matter how much room the window had — the one thing widening it is
 * for. Fixed layout hands the fixed columns their pixels (see COLUMNS) and
 * gives everything left over to the name, so the ellipsis appears only when
 * the column is genuinely too narrow. */
#dsk-root .dsk-table {
  margin-top: var(--dsk-view-pad);
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 11px;
  background: transparent;
}
#dsk-root .dsk-table th, #dsk-root .dsk-table td {
  padding: 2px 6px;
  vertical-align: middle;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* `top: 0`, and the air above the header is the table's own top margin, which
 * scrolls away with it. Padding on the scroll container instead looked right
 * standing still and wrong in motion: where a sticky offset is measured from
 * is not settled between browsers — one parks the header a padding below the
 * toolbar, and rows then slid through the strip ABOVE the header, a cut-off
 * sliver over the column names; the other parks it flush. With the air in the
 * margin the header is flush against the toolbar either way once you scroll,
 * and nothing can pass above it. */
#dsk-root .dsk-th {
  position: sticky;
  top: 0;
  z-index: 1;
  cursor: default;
  user-select: none;
  background: silver;
  box-shadow: inset -1px -1px grey, inset 1px 1px #fff;
}
/* No width at all: under the fixed layout the column without one is handed
 * everything the others did not take, which is what «the name gets the rest of
 * the window» means. The 55% it used to have was a share of the table, so a
 * wide window still cut the name while leaving empty space to its right. */
#dsk-root .dsk-th.is-grow { width: auto; }
#dsk-root .dsk-table td.is-num, #dsk-root .dsk-th.is-num { text-align: right; }
/* The grab strip on a column's right edge. Six pixels wide, the way every
 * file manager has done it since the nineties — wide enough to hit, narrow
 * enough not to steal the click that sorts the column. */
#dsk-root .dsk-col-grip {
  position: absolute;
  top: 0;
  bottom: 0;
  right: -3px;
  width: 6px;
  cursor: col-resize;
  z-index: 2;
}
/* The empty column at the end. It is zero-wide until the name column has been
 * given a width of its own; from then on it is what soaks up the space the
 * fixed columns do not use, so a dragged width stays the width it was dragged
 * to. */
#dsk-root .dsk-th-pad { padding: 0; }
#dsk-root .dsk-table td.is-pad { padding: 0; }
#dsk-root .dsk-trow { cursor: default; user-select: none; -webkit-user-select: none; }
/* The glyph and the name sit in a box INSIDE the cell, not in the cell itself.
 * `display: flex` on a `td` is a corner engines disagree about, and where it
 * is quietly ignored the cell falls back to inline layout: the icon lands on
 * the text's baseline, so the folder sits low and its name rides above it —
 * exactly what a details view must not do. A `div` is a flex container in
 * every browser there is. */
#dsk-root .dsk-name {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
/* The ellipsis cannot live on the box — it belongs to the text INSIDE it, and
 * a flex item has to be told it may shrink below its content before it will
 * clip at all. */
#dsk-root .dsk-name > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#dsk-root .dsk-empty { padding: 12px; color: #555; }

/* The second or two a first conversion takes, made visible. An empty white
 * frame looks exactly like a broken one. */
#dsk-root .dsk-converting {
  padding: 16px;
  color: #222;
  font-size: 11px;
}

/* --- shared icons ----------------------------------------------------------
 * A share is a live window onto a folder or file on somebody's personal
 * desktop. It has to be recognisable at a glance — what you may change and
 * what you may only read is the whole difference — without a second icon set:
 * a small badge in the corner of the glyph, the way a shortcut arrow has
 * always been drawn.
 */
#dsk-root .dsk-icon.is-shared { position: absolute; }
#dsk-root .dsk-icon.is-shared .dsk-icon-img { position: relative; }
#dsk-root .dsk-icon.is-shared::before {
  content: "⇗";
  position: absolute;
  left: 50%;
  margin-left: 2px;
  top: 20px;
  width: 13px;
  height: 13px;
  line-height: 12px;
  text-align: center;
  font-size: 10px;
  color: #000080;
  background: #fff;
  box-shadow: inset -1px -1px grey, inset 1px 1px #fff, 0 0 0 1px #000;
}

/* The green corner dot: this object stands on the desktops of other topics
 * too. Drawn on BOTH sides of that relationship — on the original and on
 * every window onto it — because the question it answers is «is this thing
 * shared», and the answer is the same wherever you are looking from.
 *
 * A dot rather than another badge: the ⇗ above already says «это окно на
 * чужой объект», and the two facts are different. The white ring is what
 * keeps it visible on a dark wallpaper and on a light one.
 */
#dsk-root .dsk-icon.is-shared-out { position: absolute; }
#dsk-root .dsk-icon.is-shared-out::after {
  content: "";
  position: absolute;
  left: 50%;
  margin-left: 10px;
  top: 2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #17a34a;
  box-shadow: 0 0 0 1px #0b5c29, 0 0 0 2px #fff;
}
/* The same fact in the list and table views, where an icon is a small glyph
 * in a row rather than a tile. */
#dsk-root .dsk-row.is-shared-out .dsk-row-glyph { position: relative; }
#dsk-root .dsk-row.is-shared-out .dsk-row-glyph::after {
  content: "";
  position: absolute;
  right: -2px;
  top: -1px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #17a34a;
  box-shadow: 0 0 0 1px #0b5c29, 0 0 0 1px #fff;
}

/* «Сделать общим»: one row per topic of the chat, each with what this object
 * may be there. A list of rows rather than a grid — the name is the long part
 * and the access is the short one, and the eye reads down the left edge. */
/* `.dsk-link` (borrowed for the window shell) centres its text, and this is
 * a form: two classes so it wins on specificity rather than on the order two
 * blocks happen to sit in the file. */
#dsk-root .dsk-link.dsk-topics { text-align: left; }
#dsk-root .dsk-topics-list {
  margin: 0 0 10px;
  max-height: 150px;
  overflow-y: auto;
  border: 1px solid #808080;
  background: #fff;
  padding: 4px;
}
#dsk-root .dsk-topics-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 2px;
}
#dsk-root .dsk-topics-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#dsk-root .dsk-topics-here { color: #555; flex: 0 0 auto; }
#dsk-root .dsk-topics-access { flex: 0 0 auto; }

/* --- the recycle bin ------------------------------------------------------
 * The bin icon is drawn by the client, not stored as a node, and its position
 * is computed at paint time (see trashSlot) — so there is nothing here about
 * where it sits. What it needs is to look like every other icon and to light
 * up the same way a folder does when something is dragged onto it.
 */
#dsk-root .dsk-trash { cursor: default; }
#dsk-root .dsk-trash.dsk-drop-hint .dsk-icon-label {
  background: #000080;
  color: #fff;
}
/* The bin's toolbar is the explorer's row with two wider buttons on it: the
 * squares say ↩ and ✕, but «Очистить корзину» is a sentence and has to read
 * as one. */
#dsk-root .dsk-trash-empty {
  flex: 0 0 auto;
  height: 19px;
  min-height: 0;
  min-width: 0;
  padding: 0 8px;
  font-size: 11px;
  line-height: 1;
}
#dsk-root .dsk-trash-note {
  margin-left: auto;
  padding: 0 4px;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* File-info rows inside a properties window. */
#dsk-root .dsk-props { padding: 8px 10px; color: #222; line-height: 1.7; }
#dsk-root .dsk-props b { display: inline-block; min-width: 92px; }
/* «Общий доступ»: a heading of its own and one topic per line under it. The
 * label column is 92px wide, which a list of topics does not fit into and
 * should not try to. */
#dsk-root .dsk-props-head { display: block !important; margin-top: 4px; }
#dsk-root .dsk-props-list {
  margin: 2px 0 2px 12px;
  border-left: 1px solid #b0b0b0;
  padding-left: 8px;
}
#dsk-root .dsk-props-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  line-height: 1.5;
}
#dsk-root .dsk-props-topic {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* The access is the short half and never wraps: «чтение» under «запись» in a
 * straight column is what makes the list scannable. */
#dsk-root .dsk-props-access { flex: 0 0 auto; color: #555; }

/* --- the chat window -----------------------------------------------------
 * Structurally identical to every other window — same element, same classes,
 * same depths — so the skin's own rules land where they were written to land.
 * It differs in one token: `.dsk-chrome` instead of `.dsk-scope` carries the
 * skin, because the skins style bare `button` / `input` / `label` and the chat
 * is full of those. The frame gets the skin; the chat inside it does not.
 */
#dsk-root .dsk-chrome .dsk-chat-slot {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  margin: 0;
  background: #fff;
  overflow: hidden;
  /* #dsk-root sets the pixel font for the whole desktop; the chat must not
   * inherit it. Restated here to match html/body in style.css so the chat
   * looks exactly as it does outside the desktop. */
  font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI",
    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  color: var(--text);
}
/* 98.css sets `box-sizing: border-box` on a bare `*`; the frame-only filter
 * drops that, so it is restated for the chrome — and NOT for the chat inside
 * it, which keeps whatever the site's stylesheet gives it. */
#dsk-root .dsk-chrome,
#dsk-root .dsk-chrome .title-bar,
#dsk-root .dsk-chrome .title-bar * { box-sizing: border-box; }
/* The 7 skin rounds its window; square the chat off inside it. */
#dsk-root[data-theme="7"] .dsk-chat-slot { border-radius: 0 0 5px 5px; }
#dsk-root .dsk-chat-slot > .feed-card {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  height: 100%;
  margin: 0;
  border-radius: 0;
  box-shadow: none;
}

/* --- XP: room for the controls -------------------------------------------
 * XP's own buttons are 21×21 (`min-width/min-height` in the skin) inside a
 * title bar with 3px of padding and no height of its own, which leaves them
 * touching the frame above and the window body below. The bar is given a
 * height derived from that button — 21 plus 4px of air each side — and the
 * controls are pinned so a narrow window squashes the title TEXT rather than
 * the buttons.
 */
#dsk-root[data-theme="xp"] .dsk-win .title-bar {
  min-height: 29px;
  padding-top: 4px;
  padding-bottom: 4px;
  align-items: center;
}
#dsk-root[data-theme="xp"] .dsk-win .title-bar-controls {
  flex: 0 0 auto;
  align-items: center;
}
#dsk-root[data-theme="xp"] .dsk-win .title-bar-controls button { flex: 0 0 auto; }
#dsk-root[data-theme="xp"] .dsk-win .title-bar-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- buttons / taskbar / menus (98 bevel, hand-rolled) ------------------- */
#dsk-root .dsk-btn {
  min-width: 16px;
  min-height: 14px;
  padding: 0 6px;
  border: 0;
  border-radius: 0;
  background: silver;
  color: #222;
  font-family: inherit;
  font-size: 11px;
  line-height: 14px;
  cursor: default;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff,
              inset -2px -2px grey, inset 2px 2px #dfdfdf;
}
#dsk-root .dsk-btn:active,
#dsk-root .dsk-btn.is-active {
  box-shadow: inset -1px -1px #fff, inset 1px 1px #0a0a0a,
              inset -2px -2px #dfdfdf, inset 2px 2px grey;
}
#dsk-root .dsk-taskbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 34px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px;
  box-sizing: border-box;
  background: silver;
  box-shadow: inset 0 1px #fff, inset 0 2px #dfdfdf;
  z-index: 10000;
}
#dsk-root .dsk-start { font-weight: 700; padding: 0 8px; height: 24px; display: flex; align-items: center; gap: 5px; }
#dsk-root .dsk-start-logo { width: 15px; height: 15px; }
#dsk-root .dsk-tasks { flex: 1 1 auto; display: flex; gap: 3px; overflow: hidden; }
#dsk-root .dsk-task {
  height: 24px;
  max-width: 160px;
  flex: 0 1 160px;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Desktop mode, immediately left of the clock. Sunken like the tray so the
 * two read as one status area rather than as a stray button. */
#dsk-root .dsk-mode {
  height: 24px;
  line-height: 24px;               /* as the clock and the countdown; see below */
  padding: 0 8px;
  border: 0;
  background: silver;
  font-family: inherit;
  font-size: 11px;
  cursor: default;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
/* Shared is red, personal is green — the chip says at a glance whether what
 * you are looking at is visible to the whole topic. Both bold: at 11px on
 * silver, colour alone is not a strong enough signal. */
#dsk-root .dsk-mode { color: #b00000; font-weight: 700; }
#dsk-root .dsk-mode.is-personal { color: #0a7a28; }

/* How much of this session is left, in the same sunken box as the clock it
 * stands next to — the tray is where a machine puts the things it is counting.
 * Unlike the clock it is a command: one press buys another 24 hours, and the
 * bevel flips while it is held, because a box that does something has to look
 * like it can be pressed. */
#dsk-root .dsk-expiry {
  height: 24px;
  line-height: 24px;
  padding: 0 8px;
  border: 0;
  background: silver;
  font-family: inherit;
  font-size: 11px;
  color: #222;
  cursor: default;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
#dsk-root .dsk-expiry:active {
  box-shadow: inset -1px -1px grey, inset 1px 1px #fff,
              inset -2px -2px #0a0a0a, inset 2px 2px #dfdfdf;
}
/* The last ten minutes, the moment the chat also starts saying «Скоро
 * истекает». Bold as well as red: at 11px on silver, colour alone is not a
 * strong enough signal. */
#dsk-root .dsk-expiry.is-soon { color: #b00000; font-weight: 700; }

/* --- the Telegram-linking window ---------------------------------------- */
#dsk-root .dsk-link { padding: 10px 12px; text-align: center; color: #222; }
/* The QR is the instrument, so it gets the room: white quiet zone, sunken
 * frame, and the whole thing clickable for the case where the machine in
 * front of you IS yours. */
#dsk-root .dsk-link-qr {
  position: relative;
  width: 200px;
  height: 200px;
  margin: 0 auto 10px;
  padding: 6px;
  box-sizing: border-box;
  background: #fff;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}
#dsk-root .dsk-link-qr svg { width: 100%; height: 100%; display: block; }
#dsk-root .dsk-link-qr-hit { position: absolute; inset: 0; }
#dsk-root .dsk-link-text { margin: 0 0 10px; line-height: 1.45; }
#dsk-root .dsk-link-alt { margin: 0; color: #555; line-height: 1.6; }
#dsk-root .dsk-link-code {
  font-size: 17px;
  letter-spacing: 2px;
  color: #000080;
}
/* The two pair codes, side by side and big enough to read off a screen from
 * across a desk — that is how they are actually used. */
#dsk-root .dsk-join-codes {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin: 0 0 10px;
}
#dsk-root .dsk-join-codes b {
  font-size: 19px;
  letter-spacing: 3px;
  color: #000080;
}
/* «Поделиться ссылкой». The address is an input rather than text on purpose:
 * it is selectable and it scrolls, so a browser that refuses the clipboard
 * still leaves something a person can select and copy by hand. The skin
 * (98.css / xp.css, scoped to #dsk-root) draws the field itself — only the
 * width and the spacing are ours. */
/* Left-aligned, unlike the QR window it borrows `.dsk-link` from: that one is
 * a picture in the middle of a card, this one is a label, a value and two
 * buttons — a form, and a form reads down the left edge. */
#dsk-root .dsk-share { text-align: left; }
#dsk-root .dsk-share-url {
  width: 100%;
  box-sizing: border-box;
  margin: 0 0 10px;
  font-family: inherit;
  font-size: inherit;
  /* readonly, not disabled — the skin greys a field it thinks is switched
   * off, and this one is very much live: it is meant to be selected. */
  background: #fff;
  color: #000;
}
#dsk-root .dsk-share-row {
  display: flex;
  gap: 8px;
  margin: 0 0 12px;
  flex-wrap: wrap;
}
#dsk-root .dsk-share-row .dsk-btn { margin-top: 0; }
/* The expiry line is the small print, and it reads like it. */
#dsk-root .dsk-share-note { margin: 0; color: #555; line-height: 1.5; }

#dsk-root .dsk-settings-head-gap { margin-top: 12px; }
#dsk-root .dsk-settings-btn { margin-top: 4px; padding: 2px 10px; height: 20px; }

/* `line-height` equal to the height, not flex centring — and the countdown
 * beside it is pinned the same way, because the two have to agree.
 *
 * Centring the line BOX is not centring the text: at 11px the pixel font's ink
 * sits high inside a line sized for descenders, so the flex-centred clock read
 * four pixels above the countdown next to it, which a browser lays out by its
 * own rules for a button. One explicit line-height on both leaves neither to
 * an engine's idea of what a box's contents deserve. */
#dsk-root .dsk-tray {
  height: 24px;
  line-height: 24px;
  padding: 0 8px;
  color: #222;
  box-shadow: inset -1px -1px #fff, inset 1px 1px grey,
              inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;
}

#dsk-root .dsk-menu {
  position: absolute;
  min-width: 150px;
  max-height: calc(100% - 44px);
  overflow-y: auto;
  padding: 2px;
  background: silver;
  color: #222;
  z-index: 20000;
  box-shadow: inset -1px -1px #0a0a0a, inset 1px 1px #fff,
              inset -2px -2px grey, inset 2px 2px #dfdfdf;
}
#dsk-root .dsk-menu button {
  display: block;
  width: 100%;
  padding: 4px 18px 4px 10px;
  border: 0;
  background: none;
  color: #222;
  font-family: inherit;
  font-size: 11px;
  text-align: left;
  cursor: default;
}
#dsk-root .dsk-menu button:hover:not(:disabled) { background: #000080; color: #fff; }
#dsk-root .dsk-menu button:disabled { color: grey; text-shadow: 1px 1px #fff; }
#dsk-root .dsk-menu hr { margin: 3px 1px; border: 0; border-top: 1px solid grey; border-bottom: 1px solid #fff; }
#dsk-root .dsk-menu-title {
  padding: 4px 10px;
  color: grey;
  text-shadow: 1px 1px #fff;
  cursor: default;
}

/* --- the media viewer ----------------------------------------------------
 * A picture or a video fills its window and is bounded by it, so resizing the
 * window is the zoom control.
 */
#dsk-root .dsk-media {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 8px;
  background: #000;
  overflow: hidden;
}
#dsk-root .dsk-media-el {
  max-width: 100%;
  max-height: 100%;
  display: block;
}
audio.dsk-media-el { width: 92%; }
#dsk-root .dsk-media-error { color: #fff; padding: 0 12px; text-align: center; }

/* --- viewers: pdf, text, and a zoom bar ---------------------------------- */
#dsk-root .dsk-win .window-body.dsk-view-body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}
#dsk-root .dsk-view-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  background: silver;
  border-bottom: 1px solid grey;
}
#dsk-root .dsk-view-scale { margin-left: 4px; color: #222; min-width: 40px; }
#dsk-root .dsk-frame {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: #fff;
}
/* --- the text editor ------------------------------------------------------
 * A toolbar, the editor, a status line. Ace measures its container ONCE and
 * lays itself out absolutely inside it, so the host has to be a real box:
 * `min-height: 0` is what keeps a flex child from refusing to shrink, and
 * without it the editor is born the height of the whole window and the status
 * line is pushed out of sight.
 */
#dsk-root .dsk-win .window-body.dsk-edit-body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}
#dsk-root .dsk-edit-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  background: silver;
  border-bottom: 1px solid grey;
  /* A Markdown document brings nine more buttons. A narrow window scrolls the
   * bar sideways rather than wrapping it into a second row that would eat the
   * document's height. */
  overflow-x: auto;
  scrollbar-width: none;
}
#dsk-root .dsk-edit-bar::-webkit-scrollbar { height: 0; }
/* Bold and italic look like what they do, the way every editor draws them. */
#dsk-root .dsk-edit-bar .dsk-md-bold { font-weight: 700; }
#dsk-root .dsk-edit-bar .dsk-md-italic { font-style: italic; }
/* The zoom control is shared with the viewers, which have it in a bar of its
 * own; here it rides at the right-hand end of ours. */
#dsk-root .dsk-edit-bar .dsk-view-bar {
  margin-left: auto;
  padding: 0;
  background: transparent;
  border: 0;
}
#dsk-root .dsk-edit-host {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  background: #fff;
}
#dsk-root .dsk-edit-host .ace_editor {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  font-family: Consolas, "Courier New", monospace;
  line-height: 1.45;
}
/* Ace positions its own hidden input by the pixel, and the retro skin styles
 * bare `textarea` — border, padding, background. Left alone, the skin moves
 * that input, and the caret and the IME box go with it. */
#dsk-root .dsk-edit-host textarea.ace_text-input {
  border: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
/* The fallback when Ace could not be fetched: still an editor, still saves. */
#dsk-root .dsk-edit-area {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border: 0;
  resize: none;
  padding: 6px 8px;
  background: #fff;
  color: #1a1a1a;
  font-family: Consolas, "Courier New", monospace;
  line-height: 1.5;
  tab-size: 4;
}
#dsk-root .dsk-edit-status {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 5px;
  background: silver;
  border-top: 1px solid #fff;
  font-size: 11px;
  color: #222;
}
#dsk-root .dsk-edit-caret { min-width: 108px; }
#dsk-root .dsk-edit-note {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: #7a2a2a;
}
#dsk-root .dsk-edit-sel { font-size: 11px; max-width: 130px; }
/* The media box under a toolbar: a flex child filling what is left of the
 * window, instead of the absolutely-positioned sheet it is without one. */
#dsk-root .dsk-media.dsk-media-flow {
  position: static;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
/* «3 / 12» — which picture of the folder is on screen. */
#dsk-root .dsk-view-count {
  margin: 0 6px 0 4px;
  color: #222;
  min-width: 46px;
  text-align: center;
}
/* The skin styles bare `button` and sets `display` on the toolbars, and either
 * one outranks the browser's own rule for [hidden]. Without this, hiding the
 * gallery arrows on a folder holding a single photo would not hide anything. */
#dsk-root [hidden] { display: none !important; }

/* A zoomed picture scrolls inside its box instead of stretching the window. */
#dsk-root .dsk-media.dsk-media-zoom {
  position: static;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  justify-content: flex-start;
}

/* Rendered Word / Excel. A reading font on white, not the pixel one: these are
 * documents, and the retro skin has no business inside them. */
/* A grid manages its own scrolling and must not be given a second one by the
 * box around it, or the sheet tabs scroll away with the rows. */
#dsk-root .dsk-doc:has(.dsk-sheet) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#dsk-root .dsk-doc {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 14px 18px;
  background: #fff;
  color: #1a1a1a;
  font-family: Tahoma, "Segoe UI", system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
#dsk-root .dsk-doc h1 { font-size: 1.6em; margin: 1em 0 .4em; }
#dsk-root .dsk-doc h2 { font-size: 1.35em; margin: 1em 0 .4em; }
#dsk-root .dsk-doc h3 { font-size: 1.15em; margin: 1em 0 .4em; }
#dsk-root .dsk-doc p { margin: 0 0 .7em; }
#dsk-root .dsk-doc ul, #dsk-root .dsk-doc ol { margin: 0 0 .7em; padding-left: 1.7em; }
#dsk-root .dsk-doc img { max-width: 100%; height: auto; }
#dsk-root .dsk-doc a { color: #0645ad; }
#dsk-root .dsk-doc table { border-collapse: collapse; margin: 0 0 .8em; }
#dsk-root .dsk-doc th, #dsk-root .dsk-doc td {
  border: 1px solid #c0c7c8;
  padding: 3px 7px;
  text-align: left;
  vertical-align: top;
}
#dsk-root .dsk-doc th { background: #efefef; }

/* A workbook: tabs above, the sheet scrolling sideways below. */
#dsk-root .dsk-sheet-tabs {
  display: flex;
  gap: 2px;
  margin: -6px -10px 8px;
  padding: 0 0 6px;
  overflow-x: auto;
  border-bottom: 1px solid #c0c7c8;
}
#dsk-root .dsk-sheet-tab {
  flex: 0 0 auto;
  height: 19px;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The grid a book opens in. It scrolls in BOTH directions and fills what is
 * left of the window: a spreadsheet has no page to fit into, and the whole
 * point of showing it here rather than as a converted PDF is that nothing gets
 * cut at a page edge. */
#dsk-root .dsk-sheet {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  background: #fff;
}
#dsk-root .dsk-sheet table { border-collapse: collapse; font-size: .95em; }

/* --- the converted book: the sheet's own look ----------------------------
 * Everything that makes it look like itself — fills, fonts, borders, merges,
 * column widths — arrives INLINE on the cells, so the rules here are only the
 * ones the export leaves to the browser. Faint gridlines under (never over)
 * the sheet's own borders, because a cell's own `style="border..."` outranks a
 * stylesheet and shows through wherever the sheet drew one; that is exactly
 * Excel's normal view, where the grey grid is what you see until the book says
 * otherwise. */
#dsk-root .dsk-sheet-doc {
  font-family: Tahoma, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
#dsk-root .dsk-sheet-doc table {
  /* The export writes a <colgroup> per column, and fixed layout is what makes
   * a cell keep the width the book gave it instead of stretching to its
   * longest line — again, what Excel does. */
  table-layout: fixed;
  font-size: 12px;
}
#dsk-root .dsk-sheet-doc td {
  border: 1px solid #e2e2e2;
  padding: 1px 4px;
  white-space: nowrap;
  overflow: hidden;
  vertical-align: bottom;
}
/* A picture the sheet holds keeps the size the sheet gave it — the converter
 * writes width and height on the tag — and sits at the top of its cell, which
 * is where it was anchored. */
#dsk-root .dsk-sheet-doc img { vertical-align: top; max-width: none; }
#dsk-root .dsk-sheet-doc h1, #dsk-root .dsk-sheet-doc h2 { display: none; }
#dsk-root .dsk-sheet-doc hr { display: none; }

/* --- the plain grid: the fallback reader ---------------------------------
 * No formatting comes with it, so it supplies its own: banding to follow a
 * row across, and a frozen top row, which is the one thing every spreadsheet
 * does. `box-shadow` and not `border` under the sticky row — a collapsed
 * border does not travel with a sticky cell and simply disappears. */
#dsk-root .dsk-sheet-plain table.has-cols { table-layout: fixed; }
#dsk-root .dsk-sheet-plain td, #dsk-root .dsk-sheet-plain th {
  border: 1px solid #d4d4d4;
  padding: 2px 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 600px;
}
#dsk-root .dsk-sheet-plain tr:nth-child(even) td { background: #f7f7f7; }
#dsk-root .dsk-sheet-plain tr:first-child td {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #e9edee;
  box-shadow: inset 0 -1px #9a9a9a, inset -1px 0 #d4d4d4;
}
#dsk-root .dsk-sheet-note {
  flex: 0 0 auto;
  margin: -2px 0 4px;
  color: #7a2a2a;
}

/* --- settings ------------------------------------------------------------ */
#dsk-root .dsk-settings { padding: 10px 12px; color: #222; }
#dsk-root .dsk-settings-head { margin-bottom: 6px; color: grey; text-shadow: 1px 1px #fff; }
/* `input` + `label` as SIBLINGS, which is the shape every skin draws its radio
 * through. Nested inside the label, the way it was, the skin has nothing to
 * hang the button on and the row renders as bare text. */
#dsk-root .dsk-settings-row { display: block; padding: 3px 0; cursor: default; }
#dsk-root .dsk-settings-row label { cursor: default; }

/* --- page overlays over the desktop --------------------------------------
 * The chat is MOVED into a window, but the overlays it opens are body-level
 * elements that stay where they are — and every one of them sits below
 * #dsk-root's z-index of 900, so inside the desktop a tapped photo opened the
 * viewer *underneath* the teal. They are already `position: fixed` and already
 * meant to cover everything; while the desktop is on they are simply lifted
 * over it. Above .dsk-menu (20000) so a menu never covers a dialog.
 */
body.dsk-on .img-modal,
body.dsk-on .app-modal,
body.dsk-on .qr-modal,
body.dsk-on .mention-popup,
body.dsk-on .toast { z-index: 30000; }

/* --- Windows 7: the glyphs on an unfocused window ---------------------------
 * 7.css paints the ⌄ □ ✕ of a window that HAS focus onto the button itself,
 * and leaves the copy on `::before` — the one an unfocused window has — at
 * `opacity: 0` until the pointer hovers it. So the chat window, the moment it
 * was not the front window, showed three blank buttons.
 *
 * The glyph is brought back rather than the focus rule being fought: `::before`
 * already carries the right icon per aria-label, and it paints above the
 * button's own background even at `z-index: -1`. Real Windows 7 dims those
 * buttons; it never empties them.
 */
#dsk-root[data-theme="7"] .title-bar:not(.active) .title-bar-controls button:not(:hover)::before,
#dsk-root[data-theme="7"] .window:not(.active) .title-bar .title-bar-controls button:not(:hover)::before {
  opacity: .75;
}
