/* --- THE APP WINDOW — the chrome an app body wears on the One and Pro faces,
 * at every width.
 *
 * Two files share the windowed-mode directory's old job since 2026-09-04:
 *
 *   app-window.css (this file)      One + Pro, every width. Everything keyed
 *                                   on html.kik-one alone: the sidebar column,
 *                                   the slots the bars keep for the window's
 *                                   controls, the three toggles' display and
 *                                   travel, the editor and dock cases, the
 *                                   drag state. Loaded without a media gate,
 *                                   because a phone needs most of it.
 *   windowed-mode/windowed-mode.css One + Pro, behind media="(min-width:
 *                                   681px)". Only what needs html.kik-windowed:
 *                                   the stage, window geometry, the peek, the
 *                                   settling, floating 28px controls, touch
 *                                   surfaces, the resize handles, covered
 *                                   windows, the second trailing slot.
 *
 * What is every FACE's — the flush fixed main bar and its tokens, the sidebar
 * handle, the app body's containment — lives in libraries/kikaron/main-toolbar,
 * libraries/kikaron/sidebar-handle and libraries/quaive/application-body.
 *
 * A rule written for One OUTSIDE windowed mode says so with
 * `html.kik-one:not(.kik-windowed)` and lives here: this is the file that
 * knows both modes. The windows file never carries a `:not(.kik-windowed)`.
 */

/* --- TWO BOUNDARIES, ASKED OF THE WINDOW ----------------------------------
   680 is "a phone-sized box": the inset, the bar's slide, the corner slots.
   768 is "the sidebar is a drawer over the document, not a column beside it"
   (quaive/sidebar, libraries/kikaron/sidebar). Both are asked of `main` as a
   SIZE query — the app body is a size container (libraries/quaive/
   application-body), so inside a window they answer for the window and on a
   full stage for the stage — never of the --screen-* style flags, which a
   body cannot derive for itself (a container query never matches the element
   that establishes it; the flags on the app body are #main's). These re-state
   the document body's inset per band of the WINDOW's width (top-level
   @container blocks on purpose: bare declarations inside an @container
   nested in a style rule are dropped by older parsers). */

/* ≤768: phone — the document body fills the window under the overlay
   sidebar. */
@container main (width <= 768px) {
  .application-body.state-on .document-body {
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
  }
}

/* The inset the bar, the window's controls and a modal's bar are seated on
   (--kik-win-inset), the height the content keeps clear under the bar
   (--kik-win-toolbar-height) and the insets the fixed bar spans between
   (--kik-win-db-left/right) are every face's now — declared in
   libraries/kikaron/main-toolbar. What follows is the One/Pro column. */

/* --- THE TRAILING SLOT ---------------------------------------------------
   What the main bar's trailing end keeps clear for the window's own controls
   (--kik-win-slot is the unit, libraries/kikaron/main-toolbar): the CLOSE
   alone above the phone boundary — it outlives windowed mode, a desktop that
   has not filled the screen still has it — and close + maximise in windowed
   mode (windowed-mode.css says two). Nothing on a phone, where the close is
   hidden too (the carousel shell closes an app) and a slot kept for nothing
   is exactly the room the bar's last controls need. Every reservation further
   down reads this. With the #app-space id, because the default (0px) is
   declared with it in main-toolbar.css and a class-only selector here would
   lose to it. */
@media (min-width: 681px) {
  html.kik-one #app-space .application-body.state-on {
    --kik-win-trailing-slot: var(--kik-win-slot);
  }
}

/* --- Sidebar: one look for maximised AND floating windows ---------------
   The same structure in both states — flush top, the column's own inset
   around its toolbar row, no extra toolbar padding, a tail of white below —
   sized by the one inset token: roomier when maximised, the window-toggle
   inset when floating. */
html.kik-one .application-body.state-on aside.sidebar {
  --sidebar-margin-top: 0px;
  /* Collapse must park the column by its ACTUAL width: the :root token
     resolves against the default 400px, so a user-resized (percentage)
     sidebar was left half on-screen. Re-declared here, var(--sidebar-width)
     reads the live inline value. */
  --sidebar-margin-left-closed: calc(-1 * var(--sidebar-width));
  --sidebar-padding-left: var(--kik-win-inset);
  --sidebar-padding-right: var(--kik-win-inset);
  --pat-toolbar-top-distance: 0.0001px;
  /* The column's bar stands one line with the main bar, emptied or full:
     quaive/sidebar floors it at this, and reads the component's own height
     where a column is not flush (the hub's keeps its head padding). */
  --kik-sidebar-bar-floor: var(--kik-win-toolbar-height);

  /* The part vars above only help scopes that re-compose --sidebar-padding;
     the :root composite resolves with :root's 25px parts and inherits as
     resolved tokens, so the column's padding is stated directly too. The
     id is in the :is() purely to outrank the #sidebar-content base rule. */
  > :is(#sidebar-content, .sidebar-content) {
    /* The toolbar below brings its own head padding, so the column reserves
       none of its own. Through the var rather than a flat 0 because the case
       below has to be able to answer it, and this rule is far too specific to
       out-argue from the sidebar component. */
    --sidebar-padding-top: 0px;
    padding-top: var(--sidebar-padding-top);
    padding-left: var(--kik-win-inset);
    padding-right: var(--kik-win-inset);

    /* …UNLESS THERE IS NO BAR AT ALL to bring it (Demo, since its More menu
       went). The reservation is the bar's own measure: one control height, the
       15px general toolbar inset (--small-screen-padding) and the toolbar's OWN
       padding on top (Daniel, 2026-08-17) — a bar seats its controls inside
       that padding, so a column reserving only the control height started its
       first row a padding high. Stated as those tokens and not
       --kik-win-inset: the inset is itself composed FROM
       --sidebar-padding-top a few rules up (`var(--sidebar-padding-top, 25px)`
       on the app body), so feeding it back into the property it is made of
       reads as a loop even where the cascade resolves it — and on the
       maximised branch it is the 25px desk inset, not the 15px asked for.

       A column whose bar is merely EMPTY is handled the other way round, by
       the rule below: that bar keeps its box and IS the reservation. It cannot
       be done from here — "content whose toolbar holds no control" needs a
       :has() inside a :has(), which is invalid CSS (the whole selector is
       dropped, silently, which is exactly how the first two attempts at this
       came to do nothing at all). */
    /* Asked in BOTH shapes, the way quaive/sidebar.css asks it: a
       toolbar may sit inside a display:contents plumbing <form> (Tasks and
       People both wrap theirs in a `pat-form`), and `> .pat-toolbar` alone
       does not see it — so those columns reserved a bar's height ABOVE the
       bar they already draw, on every One/Pro width. */
    &:not(:has(> .pat-toolbar)):not(:has(> form > .pat-toolbar)) {
      --sidebar-padding-top: calc(var(--pat-toolbar-button-height) + var(--small-screen-padding) + var(--pat-toolbar-padding));
    }
  }

  /* The sidebar toolbar's own padding would push its icons below and
     inside that line — the column's padding already provides it. A tail
     of white below keeps the first well off the toolbar row. */
  .pat-toolbar:not(.well-title-group *) {
    --pat-toolbar-padding: 0px;
    /* The component pins height to button + 2 * padding on a border-box —
       with the padding var zeroed, the tail below would be carved OUT of
       the row instead of added under it. Let the content size the bar. */
    height: auto;
    /* One line with the main bar: --kik-win-toolbar-height resolved at
       the app body; --pat-toolbar-button-height here is the sidebar's
       own row, so the difference centres it. Carried as the BAR's own
       padding — a sticky offset equal to the column's padding displaced
       the rest position by itself in the field. */
    /* Published, not just applied: this bar is the one place where the
       padding var (zeroed above — the column supplies the inline inset)
       stops describing the BLOCK inset. The open search field's overlay
       positions its input, magnifier and erase x against the bar, and it
       reads this token for the bar's own top inset; left to the padding
       var it put the whole open field a control-row above the controls. */
    --pat-toolbar-inset-block: calc((var(--kik-win-toolbar-height) - var(--pat-toolbar-button-height)) / 2);
    padding-top: var(--pat-toolbar-inset-block);
    padding-bottom: var(--pat-toolbar-inset-block);
    margin-top: 0;
    margin-bottom: 0;
    position: sticky;
    top: 0;
    z-index: var(--pat-toolbar-z-index, 11);

    /* The stock backdrop goes: a 40px-rounded pill fading in over `all 1s`
       on the column's scroll classes. The layer behind the column's own bar
       — the One widget title's faded blur — is every face's, and lives in
       libraries/kikaron/sidebar. */
    &::before {
      opacity: 0;
    }
  }

  /* NORMAL mode: the sidebar bar auto-hides with its column's scroll,
     the same ride as the main bar. Windowed keeps it pinned. */
  html.kik-one:not(.kik-windowed) & .pat-toolbar:not(.well-title-group *) {
    transition: transform var(--pat-toolbar-auto-hide-speed, 0.5s) ease;
  }
  html.kik-one:not(.kik-windowed) & :is(#sidebar-content, .sidebar-content).kik-scroll-down .pat-toolbar:not(.well-title-group *) {
    transform: translateY(calc(-100% - 2px));
  }
}

/* The main bar's treatment — flush, fixed to the app body's top edge,
   spanning the document body, the plate on scroll, the clearance under it —
   is every face's since 2026-09-04 and lives in libraries/kikaron/main-toolbar.
   What this face adds to the document under it: */
html.kik-one .application-body.state-on {
  /* Equal content padding on every side of a windowed document — the
     percentage side gutters read as a different measure in a window. The
     top keeps its toolbar clearance separately (main-toolbar). */
  .document-body > .document-content {
    --document-content-padding-left: var(--document-content-padding-top, 50px);
    --document-content-padding-right: var(--document-content-padding-top, 50px);
    --document-content-padding-bottom: var(--document-content-padding-top, 50px);
  }
}

/* --- Window toggles -----------------------------------------------------
   Three overlay controls rendered into every app body by
   partials/app_body_frame.html: the maximise and the close at the top right
   of every window, and — when the app has a sidebar — the sidebar handle at
   the top left (libraries/kikaron/sidebar-handle, every face). They are
   position: fixed; the app body's layout containment pins them to the
   WINDOW, floating and maximised alike. The main toolbar reserves a slot on
   each occupied side so its own controls never underlap them. */

/* --- THE ROOM THE BAR KEEPS FOR THE WINDOW'S CONTROLS --------------------
   The close and the maximise overlay the main bar's trailing end, so the
   controls there stand off by --kik-win-trailing-slot. The reservation sits
   on the QUICK FUNCTIONS and NOT on the bar itself (Daniel, 2026-08-16): a
   padding on the bar shrinks the box everything else is measured against,
   so a centred item (an app's title, the Weather page's place picker) came
   out half a slot left of the window's middle. On the SECTION, not on the
   ``.toolbar-area`` around it: the areas are ``display: contents`` and a box
   that generates no box has no padding to give.

   When there is NO quick-functions section, the BAR takes the reservation
   itself: a toolbar whose trailing end is something other than a control
   cluster — News' category tabs run the full width of the bar — had nothing
   to put the padding on, and its last tabs disappeared under the toggles.
   The bar's own trailing inset PLUS the slot, so the two cases stop the
   content on exactly the same line. (The centring objection above does not
   apply: a bar with no quick functions has no centred item to shift.)

   …AND SYMMETRICALLY when the bar has no sections at either end — no quick
   functions, no micro-navigation. What is left is a single run of content
   (a tab strip, a title) with the whole bar to itself, and a reservation on
   one side only reads as content pushed off-centre. Only above the phone
   boundary of the WINDOW: below it the bar is edge-to-edge and the toggles
   are gone.

   The Calendar app (core/calendar) puts its create + and its More menu at
   the trailing end of a real .pat-toolbar and its bar's own padding is a
   compact-chrome 13px, not the inset — so its reservation REPLACES the
   trailing padding, measured from the window's edge like the toggles are
   (Daniel, 2026-08-20). The Events app's FullCalendar bar reserves the same
   corner through --kik-fc-bar-gutter-end (global-header-compact.css).

   One set of rules for both modes: the token is one slot outside windowed
   mode and two inside, and 0 on a phone, where these rules do not fire. */
@media (min-width: 681px) {
  html.kik-one .application-body.state-on .document-body .pat-toolbar.kik-win-main-toolbar:not(.well-title-group *) .toolbar-section.quick-functions {
    padding-right: var(--kik-win-trailing-slot);
  }
  html.kik-one .application-body.state-on .document-body .pat-toolbar.kik-win-main-toolbar:not(.well-title-group *):not(:has(.toolbar-section.quick-functions)) {
    padding-right: calc(var(--kik-win-inset) + var(--kik-win-trailing-slot));
  }
  @container main (width > 680px) {
    html.kik-one .application-body.state-on .document-body .pat-toolbar.kik-win-main-toolbar:not(.well-title-group *):not(:has(.toolbar-section.quick-functions)):not(:has(.toolbar-section.micro-navigation)) {
      padding-left: calc(var(--kik-win-inset) + var(--kik-win-trailing-slot));
    }
  }
  html.kik-one .application-body.application-calendar.state-on .document-body .pat-toolbar:not(.well-title-group *) {
    padding-inline-end: calc(var(--kik-win-inset) + var(--kik-win-trailing-slot));
  }
}

/* The room the main bar keeps at its LEADING end for the sidebar handle
   while the column is parked is the handle's own business on every face —
   libraries/kikaron/sidebar-handle (moved there on 2026-09-06). */

/* THE DRAWER STOPS CLEAR OF THE WINDOW'S CONTROLS (Daniel, 2026-09-04).
   In the drawer band the column is a drawer 85% of the app's width
   (libraries/kikaron/sidebar) — and in a narrow window that 85% ran straight
   under the maximise and close buttons parked at the window's top-right
   corner. Here the drawer's trailing edge is set by those controls instead:
   one --kik-win-inset clear of the leftmost of them — the close alone outside
   windowed mode (the maximise is hidden there), and the maximise in windowed
   mode, where windowed-mode.css restates the reserve for two controls. The
   scrim that puts the drawer away is full-pane and under it (sidebar-handle),
   so it needs no width of its own.

   Declared on the ASIDE, where --kik-win-inset already takes its small-box
   value (libraries/kikaron/main-toolbar); composed on the app body it would
   carry the desk's 25px down into a window whose toggles sit on 15px. 100cqw
   is the app body — the window — which is the aside's nearest size container
   (libraries/quaive/application-body).

   Not on a phone: there the close is hidden as well (the carousel shell closes
   an app), nothing overlays the corner, and the drawer keeps its 85%. */
@container main (width <= 768px) {
@container screen style(--kik-sidebar-drawer: true) {
  @media (min-width: 681px) {
    html.kik-one:not(.kik-windowed) .application-body.state-on aside.sidebar.left {
      --kik-drawer-reserve: calc(2 * var(--kik-win-inset) + var(--pat-toolbar-button-height));
    }
    html.kik-one .application-body.state-on aside.sidebar.left {
      width: calc(100cqw - var(--kik-drawer-reserve));
    }
  }
}
}

/* MAXIMISE DIES WITH IT. Nothing to maximise outside windowed mode — most of
   all on a phone, which has no windows at all (it keeps the carousel shell).

   Declared HERE, in the file every One/Pro width loads, and not in
   windowed-mode.css beside its geometry: that file is loaded behind
   ``media="(min-width: 681px)"``, so a hide rule in it is inert exactly where
   it was needed. The toggle is server markup (partials/app_body_frame.html)
   and displayed by the ``.kik-win-toggle`` block below, so with its only
   hiding rule out of reach it drew itself on every phone. */
html.kik-one:not(.kik-windowed) .application-body.state-on > .kik-win-max {
  display: none !important;
}

/* CLOSE OUTLIVES WINDOWED MODE. It used to be hidden beside the maximise
   toggle, which was safe while `:not(.kik-windowed)` meant "phone": there the
   carousel shell owns closing an app. Since windowed mode waits for a filled
   screen (UserPreferences.windowed_fullscreen_only, ON by default), a DESKTOP
   sits in non-windowed mode all day — and hiding the close there left an open
   app with no way out of it at all (Daniel, 2026-08-20).

   Closing is not a windowing affordance: the button drops the app's state-on
   and persists it through ?closed-app whatever the mode, so it works exactly
   as it does between windows. Only the phone still hands the job to the
   carousel. */
@media (max-width: 680px) {
  html.kik-one:not(.kik-windowed) .application-body.state-on > .kik-win-close {
    display: none !important;
  }
}

/* --- AN OFFICE EDITOR OWNS THE WINDOW ----------------------------------
   Euro Office (and Collabora, the same shell one format over) paints its own
   full chrome inside the frame: a ribbon whose first tab starts at the top
   left corner, and a Close of its own at the top right. The window's three
   controls land straight on top of both — the sidebar toggle over the ribbon
   tabs, the close over the editor's own Close (Daniel, 2026-08-20).

   So while an editor shell is in the window, the frame shows none of them.
   Nothing is lost: the editor's Close is the way out (it saves and returns to
   the file's detail page, where the window's controls come straight back —
   `:has()` is live), and there is no sidebar to reveal behind an editor that
   fills the frame. The window keeps its resize handles and its drag zones,
   exactly as the collapse-screen modal case (windowed-mode.css) leaves them.

   Both modes: the editor covers that corner whether the window floats or the
   app fills the screen. */
html.kik-one .application-body.state-on:has(.onlyoffice-editor-shell),
html.kik-one .application-body.state-on:has(.collabora-editor-shell) {
  > .kik-win-side,
  > .kik-win-max,
  > .kik-win-close {
    display: none !important;
  }
}

/* What this face says about the CHROME AROUND the stage — the desk's door
   lit on the rail and in the header while the desk is the active app, the
   rail's and the side nav's own close hidden because the window carries one,
   the tab row's × and its reserved width gone — lives with each component
   since 2026-09-04: libraries/kikaron/global-nav/cloud-nav-rail.css,
   libraries/kikaron/global-header/global-header-compact.css,
   base/global-nav-side.css and libraries/kikaron/app-label/app-label.css. */

/* In normal mode the sidebar toggle rides out with whichever bar governs
   it: the sidebar's own on an open column, the main bar's when closed.

   The TRAVEL, though, is declared for every mode: a small window auto-hides
   its main bar in windowed mode too (the small-container block further up
   carries no mode gate), and a toggle that cannot animate would jump where
   the bar it belongs to glides. */
html.kik-one .application-body.state-on > .kik-win-toggle {
  transition: transform var(--pat-toolbar-auto-hide-speed, 0.5s) ease;
  /* The bar's travel, in px — see the close/maximise block below. */
  --kik-win-bar-travel: calc(-2 * (var(--kik-win-toolbar-height,
      calc(var(--pat-toolbar-button-height, 2.25rem) + 2 * var(--kik-win-inset, 25px)))
      + var(--pat-toolbar-top-distance, 0px)));
}

/* …and a SMALL window in every mode, by whichever box did the scrolling —
   the same four signals the bar answers there, the app body included (on a
   phone the page scrolls and windowed-mode.js stamps `kik-scroll-down`
   itself). No mode gate, for the same reason the bar's block has none. */
@container main (width <= 680px) {
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):is(.scrolling-down, .scroll-down):not(.scroll-position-top) > :is(.kik-win-close, .kik-win-max),
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide).scroll-position-bottom:not(.scroll-position-top) > :is(.kik-win-close, .kik-win-max),
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide).kik-scroll-down > :is(.kik-win-close, .kik-win-max),
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):has(:is(.scrolling-down, .scroll-down):not(.scroll-position-top)) > :is(.kik-win-close, .kik-win-max),
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):has(.scroll-position-bottom:not(.scroll-position-top)) > :is(.kik-win-close, .kik-win-max),
  html.kik-one .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):has(.kik-scroll-down) > :is(.kik-win-close, .kik-win-max) {
    transform: translateY(var(--kik-win-bar-travel));
  }
}

/* --- THE CLOSE AND THE MAXIMISE RIDE WITH THE MAIN BAR ------------------
   Both toggles are seated on the main bar's icon row, but they are fixed to
   the WINDOW rather than parented by the bar — so an auto-hide carried the
   bar off the top and left the two of them hanging over the content on their
   own (Daniel, 2026-08-20). They leave WITH it: same duration and easing
   (--pat-toolbar-auto-hide-speed, on the transition above) and the same
   distance.

   The distance needs saying in px, not in percent. The bar's own offset is
   `-2 * (100% + top-distance)`, and a percentage resolves against the box
   being transformed — so handing the toggles that same token would move a
   40px button by a fraction of what a 64px bar moves, and the two would
   visibly part company on the way out. --kik-win-bar-travel is that formula
   with the BAR's height written out, so both leave by the same number of
   pixels.

   Every selector asks for a main bar that HIDES first
   (`:has(.kik-win-main-toolbar.auto-hide)`): which bars slide away is each
   toolbar's own say (its toolbar_type), and on a page whose bar stays — or
   with no bar at all, the events calendar, where FullCalendar's own header is
   the band — the toggles must stay put. Two `:has()` in sequence, never one
   inside the other, which is invalid.

   NORMAL MODE, by the document body's own scroll classes. A window above the
   phone boundary pins its bar (windowed-mode.css), so its toggles never have
   to leave; the small window is the block above. */
html.kik-one:not(.kik-windowed) .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):has(.document-body:is(.scrolling-down, .scroll-down):not(.scroll-position-top)) > :is(.kik-win-close, .kik-win-max),
html.kik-one:not(.kik-windowed) .application-body.state-on:has(.kik-win-main-toolbar.auto-hide):has(.document-body.scroll-position-bottom:not(.scroll-position-top)) > :is(.kik-win-close, .kik-win-max) {
  transform: translateY(var(--kik-win-bar-travel));
}

/* …and they come back with it: a bar holding focus never leaves, so neither
   do its toggles. The bar's own exemption is repeated here in the vocabulary
   a single `:has()` allows — the focus test spelled out per branch instead of
   nested inside the bar's. */
html.kik-one .application-body.state-on:has(.kik-win-main-toolbar .tiptap-focus, .kik-win-main-toolbar .focus, .kik-win-main-toolbar :focus) > :is(.kik-win-close, .kik-win-max) {
  transform: none !important;
}

/* …EXCEPT THE CLOSE, WHICH ONLY TRAVELS FOR A DOCK (Daniel, 2026-08-21).
   The × is the way out of the app, so it stays where the user left it while
   the bar slides away: on an ordinary page there is nothing behind it that
   needed the room, and a control that moves on scroll is a control you have
   to go looking for.

   An open Ask-Kiki dock is the one thing that does need it — the card is
   flush with the ×'s own right edge and rises with the bar, so a close left
   behind would sit on the chat. `:has(.kiki-dock:not(.closing))` is the same
   live test the sidebar toggle uses further down, and the maximise toggle is
   untouched either way: it belongs to the bar's row, not to the app.

   Written as a pin rather than by splitting the blocks above in two: they
   already spell out nine scroll branches, and each would have had to be
   said twice. */
html.kik-one .application-body.state-on:not(:has(.kiki-dock:not(.closing))) > .kik-win-close {
  transform: none !important;
}

/* The DRESSING of all three — size, frost, radius, glyph box, focus ring,
   hover — is libraries/kikaron/sidebar-handle's, de-gated, because the sidebar
   handle is a control every face has. One definition, read by both; what is
   here is what this FACE has to say about these buttons.

   Showing the maximise and the close is one of those things: they are on
   whenever their app body is (and the maximise goes straight back off
   outside windowed mode — the rule above). NOT the sidebar handle: when it
   is painted is the component's own say on every face — a pane whose page
   has no column (Team spaces' landing, an edit page) gets none — and a
   blanket `.kik-win-toggle` here put it on those pages with nothing to
   toggle (2026-09-06). */
html.kik-one .application-body.state-on > :is(.kik-win-max, .kik-win-close) {
  display: inline-block;
}

html.kik-one .application-body.state-on > .kik-win-close {
  right: var(--kik-win-inset);

  &:before { content: var(--glyph-cancel); }
}

html.kik-one .application-body.state-on > .kik-win-max {
  /* Inside of the close: [ … max × ] at the window's corner. */
  right: calc(var(--kik-win-inset) + var(--kik-win-slot));

  /* The icon shows the ACTION: restore a maximised app to a window,
     maximise a window. */
  &:before { content: var(--glyph-window-restore); }
}
html.kik-one .application-body.state-on.kik-floating > .kik-win-max:before {
  content: var(--glyph-window-maximize);
}

/* AN OPEN ASK-KIKI DOCK TAKES THE TOGGLE WITH THE COLUMN (Daniel, 2026-08-17).
   The dock slides the sidebar out (quaive/document-body) for as long as the
   chat is open, and the button that works that column goes with it rather than
   moving onto the bar: while the dock is there the sidebar is not a thing the
   user is meant to bring back — closing the chat gives both back at once.

   Out to the LEFT, past the window's own edge, over the same distance the
   window toggles use for their auto-hide. `left` is a fixed inset here, so the
   travel has to be a transform; the transition is stated on the plain selector
   above it, or the button would jump out and only glide back. */
html.kik-one .application-body.state-on > .kik-win-side {
  transition: transform var(--base-animation-duration, 0.3s) ease;
}
html.kik-one .application-body.state-on:has(.kiki-dock:not(.closing)) > .kik-win-side {
  transform: translateX(calc(-100% - var(--kik-win-inset) - 4px));
  pointer-events: none;
}

/* --- Sidebar resize handle ----------------------------------------------
   A strip on the open column's edge; dragging it retunes --sidebar-width
   on the app body, which the document offsets already track. */
.kik-sb-handle {
  display: none;
}
html.kik-one .application-body.state-on.sidebar-left-open:not(.sidebar-large) aside.sidebar > .kik-sb-handle {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  right: -5px;
  width: 10px;
  cursor: ew-resize;
  z-index: 12;
  touch-action: none;   /* draggable by finger, like the window handles */
}

/* --- Drag state --------------------------------------------------------
   No resting grab cursor on the drag surfaces: it would cascade into every
   text node and control they contain. The cursor only changes while a drag
   is actually running. Here and not in windowed-mode.css because the sidebar
   resize above is a drag too, in every mode. */

/* THE CURSOR IS A SHEET, NOT A DECLARATION ON EVERY NODE (Daniel,
   2026-08-20). `html.kik-win-dragging *` set cursor and user-select
   !important on every element in the document — 4,907 of them here — and
   toggling that class cost a 160ms style recalc at the start of every drag,
   and 152ms again on release. That is the pause before a window starts
   moving; the movement itself costs 1ms. WebKit shows it plainly, Blink
   hides it, and neither should have been asked for it.
   windowed-mode.js lays one fixed sheet over the page for the duration
   instead: the pointer never reaches the text underneath, so nothing selects,
   and the cursor is set once on one element. */
.kik-drag-shield {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  cursor: grabbing;
  background: transparent;
}

/* While a drag or resize is live, every transition inside the app stage is
   off — the sidebar column, the document body's offsets and the bars all
   animate their geometry vars otherwise, and the pointer runs ahead of the
   easing (felt as lag). */
/* A DRAG NO LONGER DISTURBS WHAT IS INSIDE THE WINDOW, so it no longer has
   to freeze it. Moving is a transform now: the window's box does not change,
   so the sidebar column, the document body's offsets and the bars have
   nothing to animate and their transitions can be left alone. Only the
   window's own transform must not ease while the pointer is driving it.
   Not matching the subtree is most of what makes starting a drag cheap. */
html.kik-win-dragging #app-space .application-body.state-on {
  transition: none !important;
}
/* A RESIZE still changes width and height, so everything inside really does
   move, and really does have to hold still. */
html.kik-win-resizing #app-space .application-body.state-on,
html.kik-win-resizing #app-space .application-body.state-on * {
  transition: none !important;
}

/* --- Resize handles ---------------------------------------------------
   Eight strips partials/app_body_frame.html renders into each app body;
   visible (as hit areas — they paint nothing) only on a floating window in
   windowed mode, which is windowed-mode.css's to say. Hidden here, at every
   width, because that file is not loaded on a phone. */
.kik-win-handle {
  display: none;
  position: absolute;
  z-index: 60;
}
