/* ============================================================
   Desktop-only chrome
   ============================================================

   Everything here is scoped to `.pw-desktop`, the class desktop/preload.js puts
   on <html>. The web build never matches any of it, so this file is inert in a
   browser and there is no risk of a rule leaking into the page everyone else
   uses.

   The point of the file is the difference between an application and a web page
   in a window. Individually these are small; together they are most of what
   people mean when they say something "feels like a website". The list came from
   auditing what the app actually did, not from a checklist:

     - two title bars, the OS one repeating the app's own
     - nothing draggable — `-webkit-app-region` appeared zero times
     - text selecting when you drag across a toolbar
     - an I-beam cursor over things that are not text
     - focus rings appearing on mouse clicks, not just keyboard
     - the whole UI rubber-banding on overscroll

   Loaded after style.css so it wins on specificity ties without !important. */

/* ─── The toolbar IS the title bar ────────────────────────────
   The window's OS title bar is hidden (titleBarStyle: 'hidden' in
   desktop/main.js) and the app's top toolbar row occupies that strip instead.
   Dragging it moves the window, exactly as dragging a native title bar does. */

.pw-desktop #toolbar .toolbar-row-top {
    -webkit-app-region: drag;
}

/* Everything interactive inside the drag region has to opt back OUT, or it
   becomes furniture: a button inside a drag region does not receive clicks, it
   moves the window. This is the single most common mistake with a custom title
   bar, and it presents as "the tabs stopped working" rather than as anything to
   do with dragging. */
.pw-desktop .toolbar-row-top button,
.pw-desktop .toolbar-row-top input,
.pw-desktop .toolbar-row-top select,
.pw-desktop .toolbar-row-top textarea,
.pw-desktop .toolbar-row-top a,
.pw-desktop .toolbar-row-top [role="button"],
.pw-desktop .toolbar-row-top .logo,
.pw-desktop .toolbar-row-top #tabs-container,
.pw-desktop .toolbar-row-top #project-name,
.pw-desktop .toolbar-row-top .toolbar-right {
    -webkit-app-region: no-drag;
}

/* Reserve the space the system's caption buttons occupy, so the rightmost
   toolbar button is not sitting underneath close/maximise/minimise.

   env(titlebar-area-width) is the width the platform leaves us and is the only
   correct source: measured at 1463 of a 1600px window here — a 137px strip —
   but it differs by platform, by DPI, and when a Snap Layouts affordance is
   present.

   NOTE THE UNIT. This was `calc(100% - env(...))` first, which silently
   reserved 16px instead of 137: percentage padding resolves against the
   CONTAINING BLOCK, not the viewport, and the containing block here is inside
   #toolbar's own 20px padding. `vw` is unambiguous. The symptom was buttons
   rendering underneath the close button — clickable-looking and not clickable,
   because the caption strip takes the hit.

   Slightly conservative on purpose: it does not subtract #toolbar's 20px right
   padding, so the reserve overshoots by that much and leaves a small gap rather
   than risking an overlap if the strip grows. */
.pw-desktop #toolbar .toolbar-row-top {
    padding-right: calc(100vw - env(titlebar-area-width, calc(100vw - 140px)));
    box-sizing: border-box;
}

/* macOS puts its traffic lights on the LEFT, so the padding goes the other way.
   trafficLightPosition in main.js places them at x:14 in the 46px row. */
.pw-desktop-mac #toolbar .toolbar-row-top {
    padding-right: 0;
    padding-left: 78px;
}

/* The home screen has NO toolbar — it is a sidebar plus a content area — so
   hiding the OS title bar left it with nothing to drag the window by at all.
   This lays an invisible strip across the top of it.

   It sits at z-index 0 with the interactive content lifted above, rather than
   being given pointer-events: none. A drag region is resolved by hit-testing the
   element under the cursor, so pointer-events: none would disable the very thing
   it exists for; stacking is what lets clicks reach the controls while the gaps
   between them still drag.

   Width stops at the caption strip so it never sits under close/maximise. */
.pw-desktop .home-screen::before {
    content: '';
    position: fixed;
    top: 0;
    left: env(titlebar-area-x, 0px);
    width: env(titlebar-area-width, calc(100vw - 140px));
    height: 46px;
    z-index: 0;
    -webkit-app-region: drag;
}

/* Lifted above the strip so they stay clickable. */
.pw-desktop .home-sidebar-brand,
.pw-desktop .home-dash-head,
.pw-desktop .home-tab-content > *:first-child {
    position: relative;
    z-index: 1;
}

/* ─── Selection ───────────────────────────────────────────────
   Dragging across a label in an application selects nothing. Dragging across
   one on a web page paints it blue. Chrome is not text.

   Scoped to the chrome rather than applied to body: a blanket
   `user-select: none` also blocks selecting a generation's output, an error
   message someone needs to paste, or a filename — which is worse than the
   problem it fixes. */
.pw-desktop #toolbar,
.pw-desktop .settings-nav,
.pw-desktop .home-sidebar,
.pw-desktop .modal-header,
.pw-desktop .tab,
.pw-desktop .toolbar-icon-btn,
.pw-desktop .btn,
.pw-desktop .settings-nav-item {
    user-select: none;
    -webkit-user-select: none;
}

/* …and text still selects everywhere it is genuinely text. */
.pw-desktop input,
.pw-desktop textarea,
.pw-desktop [contenteditable="true"],
.pw-desktop .setting-hint,
.pw-desktop code,
.pw-desktop pre {
    user-select: text;
    -webkit-user-select: text;
}

/* ─── Cursors ─────────────────────────────────────────────────
   An I-beam over a button is a web page tell. Native controls show an arrow;
   only text shows a caret. */
.pw-desktop #toolbar,
.pw-desktop .settings-nav-item,
.pw-desktop .tab,
.pw-desktop .modal-header {
    cursor: default;
}

.pw-desktop button:not(:disabled),
.pw-desktop [role="button"]:not([aria-disabled="true"]) {
    cursor: pointer;
}

/* ─── Focus rings ─────────────────────────────────────────────
   :focus-visible already distinguishes keyboard focus from a mouse click in
   modern Chromium, but plenty of older rules in style.css use :focus. This puts
   the ring back on keyboard-only for the chrome, without touching form fields —
   where a visible focus ring is correct however you got there. */
.pw-desktop button:focus:not(:focus-visible),
.pw-desktop .settings-nav-item:focus:not(:focus-visible),
.pw-desktop .tab:focus:not(:focus-visible) {
    outline: none;
    box-shadow: none;
}

/* ─── Overscroll ──────────────────────────────────────────────
   The rubber-band bounce at the end of a scroll, and the swipe-to-navigate-back
   gesture, are both browser behaviours. There is nothing to navigate back TO in
   an application, and a two-finger swipe that appears to do nothing is worse
   than one that is simply not bound. */
.pw-desktop,
.pw-desktop body {
    overscroll-behavior: none;
}

/* ─── Drag and drop ───────────────────────────────────────────
   A file dropped on a browser navigates to it, replacing the app with a JSON
   dump and losing unsaved work. The app's own drop targets stop propagation and
   keep working; this only catches the ones that reach the document. */
.pw-desktop {
    -webkit-user-drag: none;
}

/* ═══════════════════════════════════════════════════════════
   Generation is by CONNECTED ACCOUNT here, not by API key
   ═══════════════════════════════════════════════════════════

   The desktop app signs into Flow, ChatGPT and Kling as the user and generates
   through those sessions. A metered API key is a second, parallel way to reach
   the same models, billed differently and configured somewhere else — offering
   both makes "why did this cost money" unanswerable, and makes the picker list
   every model twice under different provider folders.

   So the key fields go, and with them the G-Labs tab: G-Labs is a local relay
   for exactly the sessions this app now drives itself.

   WHAT STAYS, and why it is not an inconsistency: RunPod, Hugging Face, the
   LoRA library and the ComfyUI URL. Those are not accounts on someone's service
   — they address the user's OWN GPU, running MiniMax H3 and LTX. There is no
   session to sign into and nothing to pool; the key IS the machine.

   Voice keys stay too. ElevenLabs and Resemble are text-to-speech with no
   connected-account equivalent anywhere, so removing them would disable the
   Voice node and replace it with nothing.

   HIDDEN RATHER THAN DELETED. The settings-save handler reads these inputs by
   id, and a missing element there aborts it partway through — which is how a
   Save button silently stops working. Hiding also means a key already stored
   keeps working; it just stops being editable from here. */

/* Scoped to `.pw-accounts-only`, NOT to `.pw-desktop`. Packaged installers ship
   without the engine (desktop/builder.yml), so a downloaded build is a desktop
   build that cannot use a connected account for anything — hiding its API keys
   would leave it with no usable credential at all. desktop-integration.js adds
   this class only once the engine answers that it is present. */
.pw-accounts-only .settings-nav-item[data-tab="glabs"],
.pw-accounts-only .settings-tab[data-tab="glabs"],
.pw-accounts-only #setting-group-google-keys,
.pw-accounts-only #setting-group-seedream,
.pw-accounts-only #setting-group-falai {
    display: none !important;
}
